Commit 9fed0f06 authored by Sam McNally's avatar Sam McNally Committed by Commit Bot

Add mutual exclusion to new-folder command execution.

Rapidly clicking on the new folder button in the files app acting as a
save-as dialog can cause multiple flows through that process (from
pressing the button through to completing the rename) to run
concurrently. This can cause some strange effects:
- reporting that the directory already exists, despite the name
  intending to be unique;
- getting stuck a state renaming a newly-created directory that hasn't
  been rendered into the file list, causing the app to be effectively
  unresponsive.

Avoid these problems by disallowing execution of the new-folder command
while another is in progress.

Bug: 632270
Change-Id: I48eb43197403bf85ac78e42a6361c972499b008c
Reviewed-on: https://chromium-review.googlesource.com/c/1345687Reviewed-by: default avatarJoel Hockey <joelhockey@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Commit-Queue: Sam McNally <sammc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609978}
parent d4597f61
......@@ -624,7 +624,14 @@ CommandHandler.COMMANDS_['new-folder'] = (function() {
* @constructor
* @struct
*/
var NewFolderCommand = function() {};
var NewFolderCommand = function() {
/**
* Whether a new-folder is in progress.
* @type {boolean}
* @private
*/
this.busy_ = false;
};
/**
* @param {!Event} event Command event.
......@@ -648,14 +655,15 @@ CommandHandler.COMMANDS_['new-folder'] = (function() {
var directoryModel = fileManager.directoryModel;
var directoryTree = fileManager.ui.directoryTree;
var listContainer = fileManager.ui.listContainer;
this.busy_ = true;
this.generateNewDirectoryName_(targetDirectory).then(function(newName) {
this.generateNewDirectoryName_(targetDirectory).then((newName) => {
if (!executedFromDirectoryTree)
listContainer.startBatchUpdates();
return new Promise(targetDirectory.getDirectory.bind(targetDirectory,
newName,
{create: true, exclusive: true})).then(function(newDirectory) {
{create: true, exclusive: true})).then((newDirectory) => {
metrics.recordUserAction('CreateNewFolder');
// Select new directory and start rename operation.
......@@ -665,19 +673,24 @@ CommandHandler.COMMANDS_['new-folder'] = (function() {
fileManager.directoryTreeNamingController.attachAndStart(
assert(fileManager.ui.directoryTree.selectedItem), false,
null);
this.busy_ = false;
} else {
directoryModel.updateAndSelectNewDirectory(
newDirectory).then(function() {
newDirectory).then(() => {
listContainer.endBatchUpdates();
fileManager.namingController.initiateRename();
}, function() {
this.busy_ = false;
}, () => {
listContainer.endBatchUpdates();
this.busy_ = false;
});
}
}, function(error) {
}, (error) => {
if (!executedFromDirectoryTree)
listContainer.endBatchUpdates();
this.busy_ = false;
fileManager.ui.alertDialog.show(
strf('ERROR_CREATING_FOLDER',
newName,
......@@ -737,6 +750,9 @@ CommandHandler.COMMANDS_['new-folder'] = (function() {
CommandUtil.hasCapability([directoryEntry], 'canAddChildren');
event.command.setHidden(false);
}
if (this.busy_) {
event.canExecute = false;
}
};
return new NewFolderCommand();
......
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