Commit ee41ade5 authored by yawano's avatar yawano Committed by Commit bot

Files.app: Do not run thumbnail fetch during directory scan.

In order not to block IO of directory scan by IO of thumbnail fetch,
do not run thumbnail fetch when directory scan is running.

BUG=470462
TEST=out/Release/browser_tests --gtest_filter=FileManagerJsTest.ListThumbnailLoader

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

Cr-Commit-Position: refs/heads/master@{#322330}
parent 5d75fb5a
...@@ -867,7 +867,7 @@ FileManager.prototype = /** @struct */ { ...@@ -867,7 +867,7 @@ FileManager.prototype = /** @struct */ {
this.initDirectoryTree_(); this.initDirectoryTree_();
this.ui_.listContainer.listThumbnailLoader = new ListThumbnailLoader( this.ui_.listContainer.listThumbnailLoader = new ListThumbnailLoader(
assert(this.directoryModel_.getFileList()), this.directoryModel_,
assert(this.thumbnailModel_), assert(this.thumbnailModel_),
this.volumeManager_); this.volumeManager_);
this.ui_.listContainer.dataModel = this.directoryModel_.getFileList(); this.ui_.listContainer.dataModel = this.directoryModel_.getFileList();
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* is responsible to return dataUrls of thumbnails and fetch them with proper * is responsible to return dataUrls of thumbnails and fetch them with proper
* priority. * priority.
* *
* @param {!FileListModel} dataModel A file list model. * @param {!DirectoryModel} directoryModel A directory model.
* @param {!ThumbnailModel} thumbnailModel Thumbnail metadata model. * @param {!ThumbnailModel} thumbnailModel Thumbnail metadata model.
* @param {!VolumeManagerWrapper} volumeManager Volume manager. * @param {!VolumeManagerWrapper} volumeManager Volume manager.
* @param {Function=} opt_thumbnailLoaderConstructor A constructor of thumbnail * @param {Function=} opt_thumbnailLoaderConstructor A constructor of thumbnail
...@@ -21,11 +21,12 @@ ...@@ -21,11 +21,12 @@
* @suppress {checkStructDictInheritance} * @suppress {checkStructDictInheritance}
*/ */
function ListThumbnailLoader( function ListThumbnailLoader(
dataModel, thumbnailModel, volumeManager, opt_thumbnailLoaderConstructor) { directoryModel, thumbnailModel, volumeManager,
opt_thumbnailLoaderConstructor) {
/** /**
* @private {!FileListModel} * @private {!DirectoryModel}
*/ */
this.dataModel_ = dataModel; this.directoryModel_ = directoryModel;
/** /**
* @private {!ThumbnailModel} * @private {!ThumbnailModel}
...@@ -76,6 +77,13 @@ function ListThumbnailLoader( ...@@ -76,6 +77,13 @@ function ListThumbnailLoader(
*/ */
this.currentVolumeType_ = null; this.currentVolumeType_ = null;
/**
* @private {!FileListModel}
*/
this.dataModel_ = assert(this.directoryModel_.getFileList());
this.directoryModel_.addEventListener(
'scan-completed', this.onScanCompleted_.bind(this));
this.dataModel_.addEventListener('splice', this.onSplice_.bind(this)); this.dataModel_.addEventListener('splice', this.onSplice_.bind(this));
this.dataModel_.addEventListener('sorted', this.onSorted_.bind(this)); this.dataModel_.addEventListener('sorted', this.onSorted_.bind(this));
this.dataModel_.addEventListener('change', this.onChange_.bind(this)); this.dataModel_.addEventListener('change', this.onChange_.bind(this));
...@@ -143,6 +151,19 @@ ListThumbnailLoader.prototype.getNumOfMaxActiveTasks_ = function() { ...@@ -143,6 +151,19 @@ ListThumbnailLoader.prototype.getNumOfMaxActiveTasks_ = function() {
} }
}; };
/**
* An event handler for scan-completed event of directory model. When directory
* scan is running, we don't fetch thumbnail in order not to block IO for
* directory scan. i.e. modification events during directory scan is ignored.
* We need to check thumbnail loadings after directory scan is completed.
*
* @param {!Event} event Event
*/
ListThumbnailLoader.prototype.onScanCompleted_ = function(event) {
this.cursor_ = this.beginIndex_;
this.continue_();
};
/** /**
* An event handler for splice event of data model. When list is changed, start * An event handler for splice event of data model. When list is changed, start
* to rescan items. * to rescan items.
...@@ -216,8 +237,9 @@ ListThumbnailLoader.prototype.getThumbnailFromCache = function(entry) { ...@@ -216,8 +237,9 @@ ListThumbnailLoader.prototype.getThumbnailFromCache = function(entry) {
* Enqueues tasks if available. * Enqueues tasks if available.
*/ */
ListThumbnailLoader.prototype.continue_ = function() { ListThumbnailLoader.prototype.continue_ = function() {
// If all items are scanned, do nothing. // If directory scan is running or all items are scanned, do nothing.
if (!(this.cursor_ < this.dataModel_.length)) if (this.directoryModel_.isScanning() ||
!(this.cursor_ < this.dataModel_.length))
return; return;
var entry = /** @type {Entry} */ (this.dataModel_.item(this.cursor_)); var entry = /** @type {Entry} */ (this.dataModel_.item(this.cursor_));
......
...@@ -45,7 +45,9 @@ var listThumbnailLoader; ...@@ -45,7 +45,9 @@ var listThumbnailLoader;
var getCallbacks; var getCallbacks;
var thumbnailLoadedEvents; var thumbnailLoadedEvents;
var fileListModel; var fileListModel;
var directoryModel;
var currentVolumeType; var currentVolumeType;
var isScanningForTest = false;
var fileSystem = new MockFileSystem('volume-id'); var fileSystem = new MockFileSystem('volume-id');
var directory1 = new MockDirectoryEntry(fileSystem, '/TestDirectory'); var directory1 = new MockDirectoryEntry(fileSystem, '/TestDirectory');
var entry1 = new MockEntry(fileSystem, '/Test1.jpg'); var entry1 = new MockEntry(fileSystem, '/Test1.jpg');
...@@ -75,8 +77,18 @@ function setUp() { ...@@ -75,8 +77,18 @@ function setUp() {
fileListModel = new FileListModel(thumbnailModel); fileListModel = new FileListModel(thumbnailModel);
directoryModel = {
__proto__: cr.EventTarget.prototype,
getFileList: function() {
return fileListModel;
},
isScanning: function() {
return isScanningForTest;
}
};
listThumbnailLoader = new ListThumbnailLoader( listThumbnailLoader = new ListThumbnailLoader(
fileListModel, directoryModel,
thumbnailModel, thumbnailModel,
// Mocking volume manager // Mocking volume manager
{ {
...@@ -337,3 +349,22 @@ function testMTPVolume() { ...@@ -337,3 +349,22 @@ function testMTPVolume() {
// Only one request should be enqueued on MTP volume. // Only one request should be enqueued on MTP volume.
assertEquals(1, Object.keys(getCallbacks).length); assertEquals(1, Object.keys(getCallbacks).length);
} }
/**
* Test case that directory scan is running.
*/
function testDirectoryScanIsRunning() {
// Items are added during directory scan.
isScanningForTest = true;
listThumbnailLoader.setHighPriorityRange(0,2);
fileListModel.push(directory1, entry1, entry2);
assertEquals(0, Object.keys(getCallbacks).length);
// Scan completed after adding the last item.
fileListModel.push(entry3);
isScanningForTest = false;
directoryModel.dispatchEvent(new Event('scan-completed'));
assertEquals(2, Object.keys(getCallbacks).length);
}
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