Commit 28744569 authored by Joel Hockey's avatar Joel Hockey Committed by Commit Bot

FilesApp mount crostini immediately for drag and drop

Currently FileTransferController starts a 2s timer to change to
a directory if you drag and then hover over a root.  This happens
on the dragenter event.  The dragleave event will cancel the timer
if it has not already fired.

For crostini, we want to change to the directory immediately.

Test fires dragenter and then dragleave events immediately after each
other.  Usually this would cause no change if the events are
received within 2s of each other.  We test for crostini that even
if these events are fired right after each other, we still change
directory.

Bug: 846917
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I4f0f463ff1c4bc164328a2764ff235ee399d6e4c
Reviewed-on: https://chromium-review.googlesource.com/1096801
Commit-Queue: Joel Hockey <joelhockey@chromium.org>
Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Cr-Commit-Position: refs/heads/master@{#566693}
parent ab9ccc8c
......@@ -917,6 +917,9 @@
<message name="IDS_FILE_BROWSER_DROP_TARGET_ACCESS_RESTRICTED" desc="Tooltip label displayed besides mouse pointer when dragging files or folders over a removable device whose write access is restricted by administration policy.">
Access restricted
</message>
<message name="IDS_FILE_BROWSER_DROP_TARGET_OPENING_LINUX_FILES" desc="Tooltip label displayed besides mouse pointer when dragging files or folders over Linux Files root before the container has been started and mounted.">
Opening Linux Files...
</message>
<message name="IDS_FILE_BROWSER_SELECT_FOLDER_TITLE" desc="Select folder title.">
Select a folder to open
......
......@@ -652,6 +652,8 @@ ExtensionFunction::ResponseAction FileManagerPrivateGetStringsFunction::Run() {
IDS_FILE_BROWSER_OPEN_IN_OTHER_DESKTOP_MESSAGE_PLURAL);
SET_STRING("OPEN_LABEL", IDS_FILE_BROWSER_OPEN_LABEL);
SET_STRING("OPEN_WITH_BUTTON_LABEL", IDS_FILE_BROWSER_OPEN_WITH_BUTTON_LABEL);
SET_STRING("OPENING_LINUX_FILES",
IDS_FILE_BROWSER_DROP_TARGET_OPENING_LINUX_FILES);
SET_STRING("MORE_ACTIONS_BUTTON_LABEL",
IDS_FILE_BROWSER_MORE_ACTIONS_BUTTON_LABEL);
SET_STRING("OPEN_WITH_VERB_BUTTON_LABEL",
......
......@@ -69,7 +69,8 @@ EmptyFolderController.prototype.onScanStarted_ = function() {
/**
* Handles scan fail.
* @param {event} Event may contain error field containing DOMError for alert.
* @param {Event} event Event may contain error field containing DOMError for
* alert.
* @private
*/
EmptyFolderController.prototype.onScanFailed_ = function(event) {
......
......@@ -167,7 +167,7 @@ function FileTransferController(
queryRequiredElement('command#cut', this.document_));
/**
* @private {DirectoryEntry}
* @private {DirectoryEntry|FakeEntry}
*/
this.destinationEntry_ = null;
......@@ -1181,12 +1181,23 @@ FileTransferController.prototype.onDrop_ =
this.clearDropTarget_();
};
/**
* Change to the drop target directory.
* @private
*/
FileTransferController.prototype.changeToDropTargetDirectory_ = function() {
// Do custom action.
if (this.dropTarget_ instanceof DirectoryItem)
/** @type {DirectoryItem} */ (this.dropTarget_).doDropTargetAction();
this.directoryModel_.changeDirectoryEntry(assert(this.destinationEntry_));
};
/**
* Sets the drop target.
*
* @param {Element} domElement Target of the drop.
* @param {!ClipboardData} clipboardData Data transfer object.
* @param {!DirectoryEntry} destinationEntry Destination entry.
* @param {!DirectoryEntry|!FakeEntry} destinationEntry Destination entry.
* @private
*/
FileTransferController.prototype.setDropTarget_ =
......@@ -1208,14 +1219,13 @@ FileTransferController.prototype.setDropTarget_ =
domElement.classList.add('accepts');
this.destinationEntry_ = destinationEntry;
// Start timer changing the directory.
this.navigateTimer_ = setTimeout(function() {
if (domElement instanceof DirectoryItem) {
// Do custom action.
/** @type {DirectoryItem} */ (domElement).doDropTargetAction();
}
this.directoryModel_.changeDirectoryEntry(destinationEntry);
}.bind(this), 2000);
// Change directory immediately for crostini, otherwise start timer.
if (destinationEntry.rootType === VolumeManagerCommon.RootType.CROSTINI) {
this.changeToDropTargetDirectory_();
} else {
this.navigateTimer_ =
setTimeout(this.changeToDropTargetDirectory_.bind(this), 2000);
}
};
/**
......@@ -1603,6 +1613,12 @@ FileTransferController.prototype.selectDropEffect_ = function(
// The location is a fake entry that corresponds to special search.
return new DropEffectAndLabel(DropEffectType.NONE, null);
}
if (destinationLocationInfo.rootType ==
VolumeManagerCommon.RootType.CROSTINI) {
// The location is a the fake entry for crostini. Start container.
return new DropEffectAndLabel(
DropEffectType.NONE, strf('OPENING_LINUX_FILES'));
}
if (destinationLocationInfo.volumeInfo.isReadOnlyRemovableDevice) {
return new DropEffectAndLabel(DropEffectType.NONE,
strf('DEVICE_WRITE_PROTECTED'));
......
......@@ -19,8 +19,8 @@ crostini.testCrostiniNotEnabled = (done) => {
crostini.testCrostiniSuccess = (done) => {
chrome.fileManagerPrivate.crostiniEnabled_ = true;
var oldMount = chrome.fileManagerPrivate.mountCrostiniContainer;
var mountCallback = null;
const oldMount = chrome.fileManagerPrivate.mountCrostiniContainer;
let mountCallback = null;
chrome.fileManagerPrivate.mountCrostiniContainer = (callback) => {
mountCallback = callback;
};
......@@ -77,7 +77,7 @@ crostini.testCrostiniSuccess = (done) => {
crostini.testCrostiniError = (done) => {
chrome.fileManagerPrivate.crostiniEnabled_ = true;
var oldMount = chrome.fileManagerPrivate.mountCrostiniContainer;
const oldMount = chrome.fileManagerPrivate.mountCrostiniContainer;
// Override fileManagerPrivate.mountCrostiniContainer to return error.
chrome.fileManagerPrivate.mountCrostiniContainer = (callback) => {
chrome.runtime.lastError = {message: 'test message'};
......@@ -107,3 +107,28 @@ crostini.testCrostiniError = (done) => {
done();
});
};
crostini.testCrostiniMountOnDrag = (done) => {
chrome.fileManagerPrivate.crostiniEnabled_ = true;
chrome.fileManagerPrivate.mountCrostiniContainerDelay_ = 0;
fileManager.setupCrostini_();
test.setupAndWaitUntilReady()
.then(() => {
return test.waitForElement(
'#directory-tree .tree-item [root-type-icon="crostini"]');
})
.then(() => {
assertTrue(test.sendEvent(
'#directory-tree .tree-item [root-type-icon="crostini"]',
new Event('dragenter', {bubbles: true})));
assertTrue(test.sendEvent(
'#directory-tree .tree-item [root-type-icon="crostini"]',
new Event('dragleave', {bubbles: true})));
return test.waitForFiles(
test.TestEntryInfo.getExpectedRows(test.BASIC_CROSTINI_ENTRY_SET));
})
.then(() => {
chrome.fileManagerPrivate.removeMount('crostini');
done();
});
};
......@@ -123,11 +123,13 @@ chrome.fileManagerPrivate = {
isUMAEnabled: (callback) => {
setTimeout(callback, 0, false);
},
mountCrostiniContainer: (callback) => {
// Simulate startup of vm and container by taking 1s.
// Simulate startup of vm and container by taking 1s.
mountCrostiniContainerDelay_: 1000,
mountCrostiniContainer: function(callback) {
setTimeout(() => {
test.mountCrostini();
}, 1000);
callback();
}, this.mountCrostiniContainerDelay_);
},
onAppsUpdated: {
addListener: () => {},
......
......@@ -17,6 +17,7 @@ loadTimeData.data = new Proxy(
DEFAULT_NEW_FOLDER_NAME: 'New Folder',
DEFAULT_TASK_LABEL: '(default)',
DELETE_FILE_NAME: 'Deleting "$1"...',
DEVICE_ACCESS_RESTRICTED: 'Access restricted',
DIRECTORY_ALREADY_EXISTS: 'The folder named "$1" already exists. ' +
'Please choose a different name.',
DOWNLOADS_DIRECTORY_LABEL: 'Downloads',
......@@ -69,6 +70,7 @@ loadTimeData.data = new Proxy(
OK_LABEL: 'OK',
ONE_DIRECTORY_SELECTED: '1 folder selected',
ONE_FILE_SELECTED: '1 file selected',
OPENING_LINUX_FILES: 'Opening Linux Files...',
OPEN_LABEL: 'Open',
PLAIN_TEXT_FILE_TYPE: 'Plain text',
PREPARING_LABEL: 'Preparing',
......
......@@ -507,6 +507,7 @@ test.setupAndWaitUntilReady = function(resolve) {
test.fakeMouseRightClick =
test.util.sync.fakeMouseRightClick.bind(null, window);
test.fakeKeyDown = test.util.sync.fakeKeyDown.bind(null, window);
test.sendEvent = test.util.sync.sendEvent.bind(null, window);
test.getFileList = test.util.sync.getFileList.bind(null, window);
test.inputText = test.util.sync.inputText.bind(null, window);
test.selectFile = test.util.sync.selectFile.bind(null, window);
......
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