Commit 35764892 authored by Luciano Pacheco's avatar Luciano Pacheco Committed by Commit Bot

Files app: ES6 background importer.*

Convert to ES6 classes the following files:
- ui/file_manager/externs/background/media_import_handler.js
- ui/file_manager/file_manager/background/js/media_import_handler.js
- ui/file_manager/file_manager/background/js/media_import_handler_unittest.js
- ui/file_manager/file_manager/background/js/task_queue.js
- ui/file_manager/file_manager/background/js/task_queue_unittest.js
- ui/file_manager/externs/background/import_runner.js

Converting these to ES6 revealed a set of entangled dependencies between
the Background (BG) and Foreground (FG) page implementations. We do not
want FG and BG implementations depending on each other. For Closure type
checking, externs can be used to declare their @interface, allowing the
FG and BG implementations to only depend on their @interface.

Fix BG progress_center.js depending on FG progress_center_panel.js by
declaring a new extern progress_center_panel.js.

media_import_handler.js extern was a cluster of its externs and its own
dependencies. This CL splits parts of it into task_queue.js and
duplicate_finder.js, so their implementations don't have to depend on
the media_import_handler.js.

Moved importer.TaskQueue.UpdateType enum to /common/ to be shared between
FG and BG: enums can't be on externs because externs aren't loaded in our
unittests or production code.

Bug: 778674
Change-Id: I05cb122df95581d1c966d64cb7388d1591c322fe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1772792Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Commit-Queue: Noel Gordon <noel@chromium.org>
Auto-Submit: Luciano Pacheco <lucmult@chromium.org>
Cr-Commit-Position: refs/heads/master@{#692326}
parent 2ae03b94
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Namespace
var importer = importer || {};
/**
* Declare DispositionChecker class.
* @interface
*/
importer.DispositionChecker = class {
/**
* Factory for a function that returns a file entry's content disposition.
*
* @param {!importer.HistoryLoader} historyLoader
*
* @return {!importer.DispositionChecker.CheckerFunction}
*/
static createChecker(historyLoader) {}
};
/**
* Define a function type that returns a Promise that resolves the content
* disposition of an entry.
*
* @typedef {function(!FileEntry, !importer.Destination, !importer.ScanMode):
* !Promise<!importer.Disposition>}
*/
importer.DispositionChecker.CheckerFunction;
......@@ -3,7 +3,7 @@
// found in the LICENSE file.
// Namespace
var importer;
var importer = importer || {};
/**
* A persistent data store for Cloud Import history information.
......
......@@ -3,22 +3,22 @@
// found in the LICENSE file.
// Namespace
var importer;
var importer = importer || {};
/**
* Interface providing access to information about active import processes.
*
* @interface
*/
importer.ImportRunner = function() {};
/**
* Imports all media identified by a scanResult.
*
* @param {!importer.ScanResult} scanResult
* @param {!importer.Destination} destination
* @param {!Promise<!DirectoryEntry>} directoryPromise
*
* @return {!importer.MediaImportHandler.ImportTask} The media import task.
*/
importer.ImportRunner.prototype.importFromScanResult;
importer.ImportRunner = class {
/**
* Imports all media identified by a scanResult.
*
* @param {!importer.ScanResult} scanResult
* @param {!importer.Destination} destination
* @param {!Promise<!DirectoryEntry>} directoryPromise
*
* @return {!importer.MediaImportHandler.ImportTask} The media import task.
*/
importFromScanResult(scanResult, destination, directoryPromise) {}
};
......@@ -3,74 +3,29 @@
// found in the LICENSE file.
// Namespace
var importer;
var importer = importer || {};
/*
* Classes MediaImportHandler needs are not currently defined in externs to
* allow for Closure compilation of its media import unittest.
*
* Rectify this situation by forward declaring needed classes, and defining
* their constructor signatures, to enable Closure type checks in all users
* of the media import handler class, including unittests.
*/
/**
* Define TaskQueue constructor.
* @constructor
* @struct
* Externs definition for MediaImportHandler to allow for Closure compilation
* of its media import unittest and caller sites.
*/
importer.TaskQueue = function() {};
/**
* Declare TaskQueue.Task interface.
* @interface
*/
importer.TaskQueue.Task = function() {};
/**
* Define TaskQueue.BaseTask constructor.
* @constructor
* @implements {importer.TaskQueue.Task}
* @param {string} taskId
*/
importer.TaskQueue.BaseTask = function(taskId) {};
/**
* Declare DispositionChecker class.
* @struct
*/
importer.DispositionChecker;
/**
* Define a function type that returns a Promise that resolves the content
* disposition of an entry.
*
* @typedef {function(!FileEntry, !importer.Destination, !importer.ScanMode):
* !Promise<!importer.Disposition>}
*/
importer.DispositionChecker.CheckerFunction;
/**
* Define MediaImportHandler constructor: handler for importing media from
* removable devices into the user's Drive.
*
* @constructor
* @implements {importer.ImportRunner}
* @struct
* @param {!ProgressCenter} progressCenter
* @param {!importer.HistoryLoader} historyLoader
* @param {!importer.DispositionChecker.CheckerFunction} dispositionChecker
* @param {!DriveSyncHandler} driveSyncHandler
*/
importer.MediaImportHandler = function(
progressCenter, historyLoader, dispositionChecker, driveSyncHandler) {};
/**
* Define importer.ImportRunner.importFromScanResult override.
* @override
* @return {!importer.MediaImportHandler.ImportTask} The media import task.
* @interface
*/
importer.MediaImportHandler.prototype.importFromScanResult;
importer.MediaImportHandler = class extends importer.ImportRunner {
/**
* @param {!ProgressCenter} progressCenter
* @param {!importer.HistoryLoader} historyLoader
* @param {!importer.DispositionChecker.CheckerFunction} dispositionChecker
* @param {!DriveSyncHandler} driveSyncHandler
*/
constructor(
progressCenter, historyLoader, dispositionChecker, driveSyncHandler) {}
};
/**
* Define MediaImportHandler.ImportTask.
......@@ -79,29 +34,40 @@ importer.MediaImportHandler.prototype.importFromScanResult;
* the FileOperationManager (and thus *spawns* an associated
* FileOperationManager.CopyTask) but this is a temporary state of affairs.
*
* @constructor
* @extends {importer.TaskQueue.BaseTask}
* @struct
* @param {string} taskId
* @param {!importer.HistoryLoader} historyLoader
* @param {!importer.ScanResult} scanResult
* @param {!Promise<!DirectoryEntry>} directoryPromise
* @param {!importer.Destination} destination The logical destination.
* @param {!importer.DispositionChecker.CheckerFunction} dispositionChecker
* @interface
*/
importer.MediaImportHandler.ImportTask = function(
taskId, historyLoader, scanResult, directoryPromise, destination,
dispositionChecker) {};
importer.MediaImportHandler.ImportTask = class {
/**
* @param {string} taskId
* @param {!importer.HistoryLoader} historyLoader
* @param {!importer.ScanResult} scanResult
* @param {!Promise<!DirectoryEntry>} directoryPromise
* @param {!importer.Destination} destination The logical destination.
* @param {!importer.DispositionChecker.CheckerFunction} dispositionChecker
*/
constructor(
taskId, historyLoader, scanResult, directoryPromise, destination,
dispositionChecker) {}
/** @struct */
importer.MediaImportHandler.ImportTask.prototype = {
/** @return {!Promise} Resolves when task
is complete, or cancelled, rejects on error. */
/**
* @return {!Promise} Resolves when task is complete, or cancelled, rejects
* on error.
*/
get whenFinished() {}
/**
* Requests cancellation of this task: an update will be sent to all observers
* of this task when the task is actually cancelled.
*/
requestCancel() {}
};
/**
* Requests cancellation of this task: an update will be sent to all observers
* of this task when the task is actually cancelled.
* Auxiliary info for ENTRY_CHANGED notifications.
* @typedef {{
* sourceUrl: string,
* destination: !Entry
* }}
*/
importer.MediaImportHandler.ImportTask.prototype.requestCancel = function() {};
importer.MediaImportHandler.ImportTask.EntryChangedInfo;
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var importer;
var importer = importer || {};
/**
* Class representing the results of a scan operation.
......
......@@ -22,13 +22,13 @@ class ProgressCenter {
/**
* Adds a panel UI to the notification center.
* @param {ProgressCenterPanel} panel Panel UI.
* @param {ProgressCenterPanelInterface} panel Panel UI.
*/
addPanel(panel) {}
/**
* Removes a panel UI from the notification center.
* @param {ProgressCenterPanel} panel Panel UI.
* @param {ProgressCenterPanelInterface} panel Panel UI.
*/
removePanel(panel) {}
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Namespace
var importer = importer || {};
/**
* import.TaskQueue.
* @interface
*/
importer.TaskQueue = class {
/**
* @param {!importer.TaskQueue.Task} task
*/
queueTask(task) {}
/**
* Sets a callback to be triggered when a task updates.
* @param {function(string, !importer.TaskQueue.Task)} callback
*/
addUpdateCallback(callback) {}
/**
* Sets a callback that is triggered each time the queue goes from an idle
* (i.e. empty with no running tasks) to an active (i.e. having a running
* task) state.
* @param {function()} callback
*/
setActiveCallback(callback) {}
/**
* Sets a callback that is triggered each time the queue goes from an active
* to an idle state. Also see #setActiveCallback.
* @param {function()} callback
*/
setIdleCallback(callback) {}
};
/**
* Interface for any Task that is to run on the TaskQueue.
* @interface
*/
importer.TaskQueue.Task = class {
constructor() {}
/**
* Sets the TaskQueue that will own this task. The TaskQueue must call this
* prior to enqueuing a Task.
* @param {!importer.TaskQueue.Task.Observer} observer A callback that
* will be triggered each time the task has a status update.
*/
addObserver(observer) {}
/**
* Performs the actual work of the Task. Child classes should implement this.
*/
run() {}
};
/**
* Base class for importer tasks.
* @interface
*/
importer.TaskQueue.BaseTask = class extends importer.TaskQueue.Task {
/**
* @param {string} taskId
*/
constructor(taskId) {}
/** @return {string} The task ID. */
get taskId() {}
/**
* @return {!Promise<!importer.TaskQueue.UpdateType>} Resolves when task
* is complete, or cancelled, rejects on error.
*/
get whenFinished() {}
/**
* @param {importer.TaskQueue.UpdateType} updateType
* @param {Object=} opt_data
* @protected
*/
notify(updateType, opt_data) {}
};
/**
* A callback that is triggered whenever an update is reported on the observed
* task. The first argument is a string specifying the type of the update.
* Standard values used by all tasks are enumerated in
* importer.TaskQueue.UpdateType, but child classes may add supplementary update
* types of their own. The second argument is an Object containing
* supplementary information pertaining to the update.
* @typedef {function(!importer.TaskQueue.UpdateType, Object=)}
*/
importer.TaskQueue.Task.Observer;
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Interface implemented in foreground page that the background page uses to
* send progress event updates to the foreground page, and to receive cancel
* and dismiss events from the foreground page.
* @interface
*/
class ProgressCenterPanelInterface {
constructor() {
/**
* Callback to be called with the ID of the progress item when the cancel
* button is clicked.
* @public {?function(string)}
*/
this.cancelCallback;
/**
* Callback to be called with the ID of the error item when user pressed
* dismiss button of it.
* @public {?function(string)}
*/
this.dismissErrorItemCallback;
}
/**
* Updates an item to the progress center panel.
* @param {!ProgressCenterItem} item Item including new contents.
*/
updateItem(item) {}
/**
* Requests all item groups to dismiss an error item.
* @param {string} id Item id.
*/
dismissErrorItem(id) {}
}
......@@ -98,6 +98,9 @@ js_library("closure_compile_externs") {
"../../../externs/foreground_window.js",
"../../../externs/launcher_search_provider.js",
"../../../externs/platform.js",
"//ui/file_manager/externs/progress_center_panel.js",
"//ui/file_manager/externs/background/task_queue.js",
"//ui/file_manager/externs/background/duplicate_finder.js",
]
}
......@@ -230,6 +233,7 @@ js_library("duplicate_finder") {
"../../common/js:lru_cache",
"../../common/js:metrics",
]
externs_list = [ "//ui/file_manager/externs/background/duplicate_finder.js" ]
}
js_unittest("duplicate_finder_unittest") {
......@@ -354,7 +358,12 @@ js_library("media_import_handler") {
"../../common/js:importer_common",
"../../common/js:metrics",
]
externs_list = [ "//ui/file_manager/externs/background/import_runner.js" ]
externs_list = [
"//ui/file_manager/externs/background/import_runner.js",
"//ui/file_manager/externs/background/duplicate_finder.js",
"//ui/file_manager/externs/background/task_queue.js",
"//ui/file_manager/externs/background/media_import_handler.js",
]
}
js_unittest("media_import_handler_unittest") {
......@@ -416,7 +425,6 @@ js_library("mock_progress_center") {
":progress_center",
"//ui/webui/resources/js/cr:event_target",
]
externs_list = [ "//ui/file_manager/externs/background/progress_center.js" ]
}
js_library("progress_center") {
......@@ -424,29 +432,33 @@ js_library("progress_center") {
"../../common/js:async_util",
"../../common/js:progress_center_common",
"../../common/js:util",
"../../foreground/js/ui:progress_center_panel",
"//ui/webui/resources/js/cr:event_target",
]
externs_list = [ "//ui/file_manager/externs/background/progress_center.js" ]
externs_list = [
"//ui/file_manager/externs/background/progress_center.js",
"//ui/file_manager/externs/progress_center_panel.js",
]
}
js_library("task_queue") {
deps = [
":duplicate_finder",
"../../common/js:importer_common",
]
externs_list = [ "//ui/file_manager/externs/background/task_queue.js" ]
}
js_unittest("task_queue_unittest") {
deps = [
":task_queue",
"../../common/js:importer_common",
"../../common/js:progress_center_common",
"//ui/file_manager/base/js:test_error_reporting",
"//ui/file_manager/base/js:volume_manager_types",
"//ui/webui/resources/js:assert",
"//ui/webui/resources/js:cr",
"//ui/webui/resources/js/cr:event_target",
]
externs_list = [ "//ui/file_manager/externs/background/task_queue.js" ]
}
js_library("test_util_base") {
......
......@@ -61,7 +61,7 @@ function FileBrowserBackgroundImpl() {
* @type {!importer.DispositionChecker.CheckerFunction}
*/
this.dispositionChecker_ =
importer.DispositionChecker.createChecker(this.historyLoader);
importer.DispositionCheckerImpl.createChecker(this.historyLoader);
/**
* Provides support for scaning media devices as part of Cloud Import.
......@@ -76,7 +76,7 @@ function FileBrowserBackgroundImpl() {
* devices.
* @type {!importer.MediaImportHandler}
*/
this.mediaImportHandler = new importer.MediaImportHandler(
this.mediaImportHandler = new importer.MediaImportHandlerImpl(
this.progressCenter, this.historyLoader, this.dispositionChecker_,
this.driveSyncHandler);
......
......@@ -174,8 +174,9 @@ importer.DriveDuplicateFinder.MAX_CACHED_HASHCODES_ = 10000;
* primary source for duplicate checking (with the exception
* of in-scan deduplication, where duplicate results that
* are within the scan are ignored).
* @implements {importer.DispositionChecker}
*/
importer.DispositionChecker = class DispositionChecker {
importer.DispositionCheckerImpl = class {
/**
* @param {!importer.HistoryLoader} historyLoader
* @param {!importer.DriveDuplicateFinder} contentMatcher
......@@ -267,17 +268,8 @@ importer.DispositionChecker = class DispositionChecker {
* @return {!importer.DispositionChecker.CheckerFunction}
*/
static createChecker(historyLoader) {
const checker = new importer.DispositionChecker(
const checker = new importer.DispositionCheckerImpl(
historyLoader, new importer.DriveDuplicateFinder());
return checker.getDisposition.bind(checker);
}
};
/**
* Define a function type that returns a Promise that resolves the content
* disposition of an entry.
*
* @typedef {function(!FileEntry, !importer.Destination, !importer.ScanMode):
* !Promise<!importer.Disposition>}
*/
importer.DispositionChecker.CheckerFunction;
......@@ -76,7 +76,7 @@ function setUp() {
testHistory = new importer.TestImportHistory();
duplicateFinder = new importer.DriveDuplicateFinder();
getDisposition = importer.DispositionChecker.createChecker(testHistory);
getDisposition = importer.DispositionCheckerImpl.createChecker(testHistory);
}
// Verifies the correct result when a duplicate exists.
......
......@@ -97,7 +97,7 @@ function setUp() {
importHistory = new importer.TestImportHistory();
driveSyncHandler = new MockDriveSyncHandler();
importer.setupTestLogger();
mediaImporter = new importer.MediaImportHandler(
mediaImporter = new importer.MediaImportHandlerImpl(
progressCenter, importHistory, dispositionChecker, driveSyncHandler);
// Setup the copy destination.
......@@ -176,7 +176,7 @@ function testImportMedia_skipAndMarkDuplicatedFiles(callback) {
}
return Promise.resolve(importer.Disposition.ORIGINAL);
};
mediaImporter = new importer.MediaImportHandler(
mediaImporter = new importer.MediaImportHandlerImpl(
progressCenter, importHistory, dispositionChecker, driveSyncHandler);
const scanResult = new TestScanResult(media);
const importTask = mediaImporter.importFromScanResult(
......@@ -602,23 +602,72 @@ function setupFileSystem(fileNames) {
/**
* Replaces fileOperationUtil.copyTo with a mock for testing.
* @constructor
*/
function MockCopyTo() {
/** @type {!Array<!MockCopyTo.CopyInfo>} */
this.copiedFiles = [];
class MockCopyTo {
constructor() {
/** @type {!Array<!MockCopyTo.CopyInfo>} */
this.copiedFiles = [];
// Replace fileOperationUtil.copyTo with our mock test function.
fileOperationUtil.copyTo =
/** @type {function(*)} */ (this.copyTo_.bind(this));
// Replace fileOperationUtil.copyTo with our mock test function.
fileOperationUtil.copyTo =
/** @type {function(*)} */ (this.copyTo_.bind(this));
/** @private {boolean} */
this.simulateError_ = false;
/** @private {boolean} */
this.simulateError_ = false;
this.entryChangedCallback_ = null;
this.progressCallback_ = null;
this.successCallback_ = null;
this.errorCallback_ = null;
}
/**
* Makes the mock copier simulate an error the next time copyTo_ is called.
*/
simulateOneError() {
this.simulateError_ = true;
}
this.entryChangedCallback_ = null;
this.progressCallback_ = null;
this.successCallback_ = null;
this.errorCallback_ = null;
/**
* A mock to replace fileOperationUtil.copyTo. See the original for details.
* @param {!Entry} source
* @param {!DirectoryEntry} parent
* @param {string} newName
* @param {function(string, Entry)} entryChangedCallback
* @param {function(string, number)} progressCallback
* @param {function(Entry)} successCallback
* @param {function(Error)} errorCallback
*/
copyTo_(
source, parent, newName, entryChangedCallback, progressCallback,
successCallback, errorCallback) {
this.entryChangedCallback_ = entryChangedCallback;
this.progressCallback_ = progressCallback;
this.successCallback_ = successCallback;
this.errorCallback_ = errorCallback;
if (this.simulateError_) {
this.simulateError_ = false;
const error = new Error('test error');
this.errorCallback_(error);
return;
}
// Log the copy details.
this.copiedFiles.push(/** @type {!MockCopyTo.CopyInfo} */ ({
source: source,
destination: parent,
newName: newName,
}));
// Copy the file.
const copyErrorCallback = /** @type {!function(FileError):*} */
(this.errorCallback_.bind(this));
source.copyTo(parent, newName, newEntry => {
this.entryChangedCallback_(source.toURL(), parent);
this.successCallback_(newEntry);
}, copyErrorCallback);
}
}
/**
......@@ -629,51 +678,3 @@ function MockCopyTo() {
* }}
*/
MockCopyTo.CopyInfo;
/**
* Makes the mock copier simulate an error the next time copyTo_ is called.
*/
MockCopyTo.prototype.simulateOneError = function() {
this.simulateError_ = true;
};
/**
* A mock to replace fileOperationUtil.copyTo. See the original for details.
* @param {!Entry} source
* @param {!DirectoryEntry} parent
* @param {string} newName
* @param {function(string, Entry)} entryChangedCallback
* @param {function(string, number)} progressCallback
* @param {function(Entry)} successCallback
* @param {function(Error)} errorCallback
*/
MockCopyTo.prototype.copyTo_ = function(
source, parent, newName, entryChangedCallback, progressCallback,
successCallback, errorCallback) {
this.entryChangedCallback_ = entryChangedCallback;
this.progressCallback_ = progressCallback;
this.successCallback_ = successCallback;
this.errorCallback_ = errorCallback;
if (this.simulateError_) {
this.simulateError_ = false;
const error = new Error('test error');
this.errorCallback_(error);
return;
}
// Log the copy details.
this.copiedFiles.push(/** @type {!MockCopyTo.CopyInfo} */ ({
source: source,
destination: parent,
newName: newName,
}));
// Copy the file.
const copyErrorCallback = /** @type {!function(FileError):*} */
(this.errorCallback_.bind(this));
source.copyTo(parent, newName, newEntry => {
this.entryChangedCallback_(source.toURL(), parent);
this.successCallback_(newEntry);
}, copyErrorCallback);
};
......@@ -25,7 +25,7 @@ class ProgressCenterImpl {
/**
* List of panel UI managed by the progress center.
* @private @const {!Array<ProgressCenterPanel>}
* @private @const {!Array<ProgressCenterPanelInterface>}
*/
this.panels_ = [];
}
......@@ -86,7 +86,7 @@ class ProgressCenterImpl {
/**
* Adds a panel UI to the notification center.
* @param {ProgressCenterPanel} panel Panel UI.
* @param {ProgressCenterPanelInterface} panel Panel UI.
*/
addPanel(panel) {
if (this.panels_.indexOf(panel) !== -1) {
......@@ -110,7 +110,7 @@ class ProgressCenterImpl {
/**
* Removes a panel UI from the notification center.
* @param {ProgressCenterPanel} panel Panel UI.
* @param {ProgressCenterPanelInterface} panel Panel UI.
*/
removePanel(panel) {
const index = this.panels_.indexOf(panel);
......
......@@ -9,7 +9,7 @@ let queue;
const updates = {};
function setUp() {
queue = new importer.TaskQueue();
queue = new importer.TaskQueueImpl();
// Set up a callback to log updates from running tasks.
for (const updateType in importer.TaskQueue.UpdateType) {
......@@ -26,58 +26,58 @@ function setUp() {
/**
* A Task subclass for testing.
* @constructor
* @extends {importer.TaskQueue.BaseTask}
*
* @param {string} taskId
*/
const TestTask = function(taskId) {
importer.TaskQueue.BaseTask.call(this, taskId);
/** @type {boolean} */
this.wasRun = false;
class TestTask extends importer.TaskQueue.BaseTaskImpl {
/**
* @private {Function}
* @param {string} taskId
*/
this.runResolver_ = null;
constructor(taskId) {
super(taskId);
this.runPromise_ = new Promise(resolve => {
this.runResolver_ = resolve;
});
};
TestTask.prototype.__proto__ = importer.TaskQueue.BaseTask.prototype;
/** @override */
TestTask.prototype.run = function() {
this.wasRun = true;
this.runResolver_(this);
};
/** Sends a quick error notification. */
TestTask.prototype.notifyError = function() {
this.notify(importer.TaskQueue.UpdateType.ERROR);
};
/** Sends a quick completion notification. */
TestTask.prototype.notifyComplete = function() {
this.notify(importer.TaskQueue.UpdateType.COMPLETE);
};
/** Sends a quick cancelled notification. */
TestTask.prototype.notifyCanceled = function() {
this.notify(importer.TaskQueue.UpdateType.CANCELED);
};
/** Sends a quick progress notification. */
TestTask.prototype.notifyProgress = function() {
this.notify(importer.TaskQueue.UpdateType.PROGRESS);
};
/** @return {!Promise} A promise that settles once #run is called. */
TestTask.prototype.whenRun = function() {
return this.runPromise_;
};
/** @type {boolean} */
this.wasRun = false;
/**
* @private {Function}
*/
this.runResolver_ = null;
this.runPromise_ = new Promise(resolve => {
this.runResolver_ = resolve;
});
}
/** @override */
run() {
this.wasRun = true;
this.runResolver_(this);
}
/** Sends a quick error notification. */
notifyError() {
this.notify(importer.TaskQueue.UpdateType.ERROR);
}
/** Sends a quick completion notification. */
notifyComplete() {
this.notify(importer.TaskQueue.UpdateType.COMPLETE);
}
/** Sends a quick cancelled notification. */
notifyCanceled() {
this.notify(importer.TaskQueue.UpdateType.CANCELED);
}
/** Sends a quick progress notification. */
notifyProgress() {
this.notify(importer.TaskQueue.UpdateType.PROGRESS);
}
/** @return {!Promise} A promise that settles once #run is called. */
whenRun() {
return this.runPromise_;
}
}
// Verifies that a queued task gets run.
function testRunsTask(callback) {
......
......@@ -2,9 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Shared cloud importer namespace
// Namespace
var importer = importer || {};
importer.TaskQueue = importer.TaskQueue || {};
/**
* @enum {string}
*/
importer.TaskQueue.UpdateType = {
PROGRESS: 'PROGRESS',
COMPLETE: 'COMPLETE',
ERROR: 'ERROR',
CANCELED: 'CANCELED'
};
/** @enum {string} */
importer.ScanEvent = {
FINALIZED: 'finalized',
......
......@@ -91,6 +91,8 @@ js_library("closure_compile_externs") {
"../../../externs/background/file_operation_manager.js",
"../../../externs/background/import_runner.js",
"../../../externs/background/media_import_handler.js",
"../../../externs/background/task_queue.js",
"../../../externs/background/duplicate_finder.js",
"../../../externs/background/media_scanner.js",
"../../../externs/background/progress_center.js",
"../../../externs/background_window.js",
......@@ -501,6 +503,8 @@ js_library("import_controller") {
externs_list = [
"//ui/file_manager/externs/background/import_runner.js",
"//ui/file_manager/externs/background/media_import_handler.js",
"//ui/file_manager/externs/background/duplicate_finder.js",
"//ui/file_manager/externs/background/task_queue.js",
"//ui/file_manager/externs/command_handler_deps.js",
]
}
......
......@@ -443,6 +443,7 @@ js_library("progress_center_panel") {
"..:progress_center_item_group",
"../../../common/js:progress_center_common",
]
externs_list = [ "//ui/file_manager/externs/progress_center_panel.js" ]
}
js_library("providers_menu") {
......
......@@ -187,7 +187,7 @@ ProgressCenterItemElement.PROGRESS_ANIMATION_END_EVENT = 'progressAnimationEnd';
/**
* Progress center panel.
*
* @implements {ProgressCenterPanelInterface}
*/
class ProgressCenterPanel {
/**
......
......@@ -58,6 +58,7 @@ js_library("closure_compile_externs") {
"$externs_path/metrics_private.js",
"//ui/file_manager/externs/background/file_browser_background.js",
"//ui/file_manager/externs/background/progress_center.js",
"//ui/file_manager/externs/progress_center_panel.js",
"//ui/file_manager/externs/background/crostini.js",
"//ui/file_manager/externs/entry_location.js",
"//ui/file_manager/externs/volume_info.js",
......
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