Commit c207bdf2 authored by smckay's avatar smckay Committed by Commit bot

Correctly handle out of storage space and "actively importing" states in controller.

Changes in task state trigger import controller updates (triggering scanning and UI updates).
Update test to work with new async update model.

Also: Fix media importer code to pass logical destination when marking a file imported.

+satorux for chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
BUG=420680
TEST=browser_test: FileManagerJsTest.*

Review URL: https://codereview.chromium.org/888693002

Cr-Commit-Position: refs/heads/master@{#313869}
parent ff93ab78
......@@ -448,6 +448,9 @@ Press any key to continue exploring.
<message name="IDS_FILE_BROWSER_CLOUD_IMPORT_BUTTON_LABEL" desc="Label for button that initiates media backup to the cloud.">
Import <ph name="FILE_COUNT">$1<ex>5</ex></ph> files to Google Drive
</message>
<message name="IDS_FILE_BROWSER_CLOUD_IMPORT_ACTIVE_IMPORT_BUTTON_LABEL" desc="Message to user that there is an active import in progress.">
Importing...
</message>
<message name="IDS_FILE_BROWSER_CLOUD_IMPORT_EMPTY_SCAN_BUTTON_LABEL" desc="Message to user that no new files were found, so cloud import is not possible.">
No new media
</message>
......
......@@ -264,6 +264,8 @@ bool FileManagerPrivateGetStringsFunction::RunSync() {
IDS_FILE_BROWSER_CLOSE_VOLUME_BUTTON_LABEL);
SET_STRING("CLOUD_IMPORT_BUTTON_LABEL",
IDS_FILE_BROWSER_CLOUD_IMPORT_BUTTON_LABEL);
SET_STRING("CLOUD_IMPORT_ACTIVE_IMPORT_BUTTON_LABEL",
IDS_FILE_BROWSER_CLOUD_IMPORT_ACTIVE_IMPORT_BUTTON_LABEL);
SET_STRING("CLOUD_IMPORT_EMPTY_SCAN_BUTTON_LABEL",
IDS_FILE_BROWSER_CLOUD_IMPORT_EMPTY_SCAN_BUTTON_LABEL);
SET_STRING("CLOUD_IMPORT_INSUFFICIENT_SPACE_BUTTON_LABEL",
......
......@@ -21,8 +21,9 @@ importer.ImportRunner.DestinationFactory;
* Imports all media identified by scanResult.
*
* @param {!importer.ScanResult} scanResult
* @param {!importer.ImportRunner.DestinationFactory=} opt_destination A
* function that returns the directory into which media will be imported.
* @param {!importer.Destination} destination
* @param {!importer.ImportRunner.DestinationFactory=} opt_destinationDirectory
* A function that returns the directory into which media will be imported.
*
* @return {!importer.MediaImportHandler.ImportTask} The resulting import task.
*/
......@@ -59,16 +60,17 @@ importer.MediaImportHandler =
/** @override */
importer.MediaImportHandler.prototype.importFromScanResult =
function(scanResult, opt_destination) {
var destination = opt_destination ||
function(scanResult, destination, opt_destinationDirectory) {
var destinationDirectory = opt_destinationDirectory ||
importer.MediaImportHandler.defaultDestination.getImportDestination;
var task = new importer.MediaImportHandler.ImportTask(
this.generateTaskId_(),
this.historyLoader_,
scanResult,
destination,
this.duplicateFinder_);
destinationDirectory,
this.duplicateFinder_,
destination);
task.addObserver(this.onTaskProgress_.bind(this, task));
......@@ -149,20 +151,25 @@ importer.MediaImportHandler.prototype.onTaskProgress_ =
* @param {!importer.ScanResult} scanResult
* @param {!importer.ImportRunner.DestinationFactory} destinationFactory A
* function that returns the directory into which media will be imported.
* @param {!importer.DuplicateFinder} duplicateFinder A duplicate-finder linked
* to the import destination, that will be used to deduplicate imports.
* @param {!importer.DuplicateFinder} duplicateFinder A duplicate-finder linked
* to the import destination, that will be used to deduplicate imports.
* @param {!importer.Destination} destination The logical destination.
*/
importer.MediaImportHandler.ImportTask = function(
taskId,
historyLoader,
scanResult,
destinationFactory,
duplicateFinder) {
duplicateFinder,
destination) {
importer.TaskQueue.BaseTask.call(this, taskId);
/** @private {string} */
this.taskId_ = taskId;
/** @private {!importer.Destination} */
this.destination_ = destination;
/** @private {!importer.ImportRunner.DestinationFactory} */
this.destinationFactory_ = destinationFactory;
......@@ -194,6 +201,18 @@ importer.MediaImportHandler.ImportTask = function(
this.canceled_ = false;
};
/** @struct */
importer.MediaImportHandler.ImportTask.prototype = {
/** @return {number} Number of imported bytes */
get processedBytes() { return this.processedBytes_; },
/** @return {number} Total number of bytes to import */
get totalBytes() { return this.totalBytes_; },
/** @return {number} Number of files left to import */
get remainingFilesCount() { return this.remainingFilesCount_; }
};
/**
* Update types that are specific to ImportTask. Clients can add Observers to
* ImportTask to listen for these kinds of updates.
......@@ -212,18 +231,6 @@ importer.MediaImportHandler.ImportTask.UpdateType = {
*/
importer.MediaImportHandler.ImportTask.EntryChangedInfo;
/** @struct */
importer.MediaImportHandler.ImportTask.prototype = {
/** @return {number} Number of imported bytes */
get processedBytes() { return this.processedBytes_; },
/** @return {number} Total number of bytes to import */
get totalBytes() { return this.totalBytes_; },
/** @return {number} Number of files left to import */
get remainingFilesCount() { return this.remainingFilesCount_; }
};
/**
* Extends importer.TaskQueue.Task
*/
......@@ -429,7 +436,7 @@ importer.MediaImportHandler.ImportTask.prototype.markAsCopied_ =
/**
* @param {!FileEntry} entry
* @param {!DirectoryEntry} destination
* @private
*/
importer.MediaImportHandler.ImportTask.prototype.markAsImported_ =
function(entry) {
......@@ -437,10 +444,8 @@ importer.MediaImportHandler.ImportTask.prototype.markAsImported_ =
this.historyLoader_.getHistory().then(
/** @param {!importer.ImportHistory} history */
function(history) {
history.markImported(
entry,
importer.Destination.GOOGLE_DRIVE);
});
history.markImported(entry, this.destination_);
}.bind(this));
};
/** @private */
......
......@@ -72,8 +72,10 @@ function testImportMedia(callback) {
]);
var scanResult = new TestScanResult(media);
var importTask =
mediaImporter.importFromScanResult(scanResult, destinationFactory);
var importTask = mediaImporter.importFromScanResult(
scanResult,
importer.Destination.GOOGLE_DRIVE,
destinationFactory);
var whenImportDone = new Promise(
function(resolve, reject) {
importTask.addObserver(
......@@ -111,8 +113,10 @@ function testUpdatesHistoryAfterImport(callback) {
]);
var scanResult = new TestScanResult(entries);
var importTask =
mediaImporter.importFromScanResult(scanResult, destinationFactory);
var importTask = mediaImporter.importFromScanResult(
scanResult,
importer.Destination.GOOGLE_DRIVE,
destinationFactory);
var whenImportDone = new Promise(
function(resolve, reject) {
importTask.addObserver(
......@@ -162,8 +166,10 @@ function testImportCancellation(callback) {
var EXPECTED_COPY_COUNT = 3;
var scanResult = new TestScanResult(media);
var importTask =
mediaImporter.importFromScanResult(scanResult, destinationFactory);
var importTask = mediaImporter.importFromScanResult(
scanResult,
importer.Destination.GOOGLE_DRIVE,
destinationFactory);
var whenImportCancelled = new Promise(
function(resolve, reject) {
importTask.addObserver(
......@@ -215,8 +221,10 @@ function testImportWithDuplicates(callback) {
var EXPECTED_COPY_COUNT = 3;
var scanResult = new TestScanResult(media);
var importTask =
mediaImporter.importFromScanResult(scanResult, destinationFactory);
var importTask = mediaImporter.importFromScanResult(
scanResult,
importer.Destination.GOOGLE_DRIVE,
destinationFactory);
var whenImportDone = new Promise(
function(resolve, reject) {
importTask.addObserver(
......
......@@ -181,16 +181,18 @@ importer.TaskQueue.BaseTask = function(taskId) {
this.taskId_ = taskId;
/** @private {!Array<!importer.TaskQueue.Task.Observer>} */
this.observers_ = [];
/** @private {!importer.Resolver} */
this.finishedResolver_ = new importer.Resolver();
};
/** @struct */
importer.TaskQueue.BaseTask.prototype = {
/**
* @return {string} The task ID.
*/
get taskId() {
return this.taskId_;
}
/** @return {string} The task ID. */
get taskId() { return this.taskId_; },
/** @return {!Promise} Resolves when task is complete, rejects on error. */
get whenFinished() { return this.finishedResolver_.promise; }
};
/** @override */
......@@ -207,6 +209,13 @@ importer.TaskQueue.BaseTask.prototype.run = function() {};
* @protected
*/
importer.TaskQueue.BaseTask.prototype.notify = function(updateType, opt_data) {
switch (updateType) {
case importer.TaskQueue.UpdateType.CANCELED:
case importer.TaskQueue.UpdateType.ERROR:
case importer.TaskQueue.UpdateType.SUCCESS:
this.finishedResolver_.resolve();
}
this.observers_.forEach(
/** @param {!importer.TaskQueue.Task.Observer} callback */
function(callback) {
......
......@@ -10,6 +10,8 @@
<script src="../../../../../ui/webui/resources/js/assert.js"></script>
<script src="../../../../../ui/webui/resources/js/cr/event_target.js"></script>
<script src="../../common/js/volume_manager_common.js"></script>
<script src="../../common/js/importer_common.js"></script>
<script src="../../common/js/unittest_util.js"></script>
<script src="task_queue.js"></script>
......
......@@ -16,6 +16,7 @@ function setUp() {
// Reset counts for all update types.
updates[importer.TaskQueue.UpdateType[updateType]] = 0;
}
// Counts the number of updates of each type that have been received.
var updateCallback = function(type, updatedTask) {
updates[type]++;
......
......@@ -218,7 +218,7 @@ importer.Resolver = function() {
/** @private {boolean} */
this.settled_ = false;
/** @private {function(T)} */
/** @private {function(T=)} */
this.resolve_;
/** @private {function(*=)} */
......@@ -240,7 +240,7 @@ importer.Resolver = function() {
importer.Resolver.prototype = /** @struct */ {
/**
* @return {function(T)}
* @return {function(T=)}
* @template T
*/
get resolve() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment