Commit 0f41b132 authored by Julian Watson's avatar Julian Watson Committed by Commit Bot

plugin_vm: change error message based on file location

If file is local but unshared display message:
IDS_FILE_BROWSER_UNABLE_TO_OPEN_WITH_PLUGIN_VM_DIRECTORY_NOT_SHARED_MESSAGE.

If file is on an external drive (usb/Google Drive) display message:
IDS_FILE_BROWSER_UNABLE_TO_OPEN_WITH_PLUGIN_VM_EXTERNAL_DRIVE_MESSAGE

TBR=timloh@chromium.org

Bug: 1049453
Change-Id: I98a35e51b98d11537c0a675b0a1a28645b60ccfe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2217512
Commit-Queue: Julian Watson <juwa@google.com>
Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Cr-Commit-Position: refs/heads/master@{#773903}
parent f1316b01
...@@ -863,7 +863,8 @@ WRAPPED_INSTANTIATE_TEST_SUITE_P( ...@@ -863,7 +863,8 @@ WRAPPED_INSTANTIATE_TEST_SUITE_P(
::testing::Values(TestCase("mountCrostini"), ::testing::Values(TestCase("mountCrostini"),
TestCase("enableDisableCrostini"), TestCase("enableDisableCrostini"),
TestCase("sharePathWithCrostini"), TestCase("sharePathWithCrostini"),
TestCase("pluginVmErrorDialog"))); TestCase("pluginVmDirectoryNotSharedErrorDialog"),
TestCase("pluginVmFileOnExternalDriveErrorDialog")));
WRAPPED_INSTANTIATE_TEST_SUITE_P( WRAPPED_INSTANTIATE_TEST_SUITE_P(
MyFiles, /* my_files.js */ MyFiles, /* my_files.js */
......
...@@ -784,8 +784,12 @@ std::unique_ptr<base::DictionaryValue> GetFileManagerStrings() { ...@@ -784,8 +784,12 @@ std::unique_ptr<base::DictionaryValue> GetFileManagerStrings() {
SET_STRING("PLUGIN_VM_APP_NAME", IDS_PLUGIN_VM_APP_NAME); SET_STRING("PLUGIN_VM_APP_NAME", IDS_PLUGIN_VM_APP_NAME);
SET_STRING("UNABLE_TO_OPEN_WITH_PLUGIN_VM_TITLE", SET_STRING("UNABLE_TO_OPEN_WITH_PLUGIN_VM_TITLE",
IDS_FILE_BROWSER_UNABLE_TO_OPEN_WITH_PLUGIN_VM_TITLE); IDS_FILE_BROWSER_UNABLE_TO_OPEN_WITH_PLUGIN_VM_TITLE);
SET_STRING("UNABLE_TO_OPEN_WITH_PLUGIN_VM_MESSAGE", SET_STRING(
IDS_FILE_BROWSER_UNABLE_TO_OPEN_WITH_PLUGIN_VM_MESSAGE); "UNABLE_TO_OPEN_WITH_PLUGIN_VM_DIRECTORY_NOT_SHARED_MESSAGE",
IDS_FILE_BROWSER_UNABLE_TO_OPEN_WITH_PLUGIN_VM_DIRECTORY_NOT_SHARED_MESSAGE);
SET_STRING(
"UNABLE_TO_OPEN_WITH_PLUGIN_VM_EXTERNAL_DRIVE_MESSAGE",
IDS_FILE_BROWSER_UNABLE_TO_OPEN_WITH_PLUGIN_VM_EXTERNAL_DRIVE_MESSAGE);
SET_STRING("CHANGE_TO_LISTVIEW_BUTTON_LABEL", SET_STRING("CHANGE_TO_LISTVIEW_BUTTON_LABEL",
IDS_FILE_BROWSER_CHANGE_TO_LISTVIEW_BUTTON_LABEL); IDS_FILE_BROWSER_CHANGE_TO_LISTVIEW_BUTTON_LABEL);
SET_STRING("CHANGE_TO_THUMBNAILVIEW_BUTTON_LABEL", SET_STRING("CHANGE_TO_THUMBNAILVIEW_BUTTON_LABEL",
......
...@@ -193,6 +193,8 @@ auto ConvertLaunchPluginVmAppResultToTaskResult( ...@@ -193,6 +193,8 @@ auto ConvertLaunchPluginVmAppResultToTaskResult(
return fmp::TASK_RESULT_MESSAGE_SENT; return fmp::TASK_RESULT_MESSAGE_SENT;
case plugin_vm::LaunchPluginVmAppResult::FAILED_DIRECTORY_NOT_SHARED: case plugin_vm::LaunchPluginVmAppResult::FAILED_DIRECTORY_NOT_SHARED:
return fmp::TASK_RESULT_FAILED_PLUGIN_VM_TASK_DIRECTORY_NOT_SHARED; return fmp::TASK_RESULT_FAILED_PLUGIN_VM_TASK_DIRECTORY_NOT_SHARED;
case plugin_vm::LaunchPluginVmAppResult::FAILED_FILE_ON_EXTERNAL_DRIVE:
return fmp::TASK_RESULT_FAILED_PLUGIN_VM_TASK_EXTERNAL_DRIVE;
case plugin_vm::LaunchPluginVmAppResult::FAILED: case plugin_vm::LaunchPluginVmAppResult::FAILED:
return fmp::TASK_RESULT_FAILED; return fmp::TASK_RESULT_FAILED;
} }
......
...@@ -194,7 +194,10 @@ void LaunchPluginVmApp(Profile* profile, ...@@ -194,7 +194,10 @@ void LaunchPluginVmApp(Profile* profile,
ConvertFileSystemURLToPathInsidePluginVmSharedDir(profile, file); ConvertFileSystemURLToPathInsidePluginVmSharedDir(profile, file);
if (!file_path) { if (!file_path) {
return std::move(callback).Run( return std::move(callback).Run(
LaunchPluginVmAppResult::FAILED_DIRECTORY_NOT_SHARED, file_manager::util::GetMyFilesFolderForProfile(profile).IsParent(
file.path())
? LaunchPluginVmAppResult::FAILED_DIRECTORY_NOT_SHARED
: LaunchPluginVmAppResult::FAILED_FILE_ON_EXTERNAL_DRIVE,
"Only files in the shared dir are supported. Got: " + "Only files in the shared dir are supported. Got: " +
file.DebugString()); file.DebugString());
} }
......
...@@ -30,6 +30,7 @@ enum class LaunchPluginVmAppResult { ...@@ -30,6 +30,7 @@ enum class LaunchPluginVmAppResult {
SUCCESS, SUCCESS,
FAILED, FAILED,
FAILED_DIRECTORY_NOT_SHARED, FAILED_DIRECTORY_NOT_SHARED,
FAILED_FILE_ON_EXTERNAL_DRIVE,
}; };
using LaunchPluginVmAppCallback = using LaunchPluginVmAppCallback =
......
...@@ -159,7 +159,9 @@ enum TaskResult { ...@@ -159,7 +159,9 @@ enum TaskResult {
// No URL is specified. // No URL is specified.
empty, empty,
// The task was a |plugin_vm| task, and the file was in a unshared directory // The task was a |plugin_vm| task, and the file was in a unshared directory
failed_plugin_vm_task_directory_not_shared failed_plugin_vm_task_directory_not_shared,
// The task was a |plugin_vm| task, and the file was in an external drive.
failed_plugin_vm_task_external_drive
}; };
// Drive share type. // Drive share type.
......
...@@ -176,7 +176,9 @@ chrome.fileManagerPrivate.TaskResult = { ...@@ -176,7 +176,9 @@ chrome.fileManagerPrivate.TaskResult = {
MESSAGE_SENT: 'message_sent', MESSAGE_SENT: 'message_sent',
FAILED: 'failed', FAILED: 'failed',
EMPTY: 'empty', EMPTY: 'empty',
FAILED_PLUGIN_VM_TASK_DIRECTORY_NOT_SHARED: 'failed_plugin_vm_task_directory_not_shared', FAILED_PLUGIN_VM_TASK_DIRECTORY_NOT_SHARED:
'failed_plugin_vm_task_directory_not_shared',
FAILED_PLUGIN_VM_TASK_EXTERNAL_DRIVE: 'failed_plugin_vm_task_external_drive',
}; };
/** @enum {string} */ /** @enum {string} */
......
...@@ -607,8 +607,11 @@ ...@@ -607,8 +607,11 @@
<message name="IDS_FILE_BROWSER_UNABLE_TO_OPEN_WITH_PLUGIN_VM_TITLE" desc="Title of the dialog shown to users when they try to open a file with Plugin VM from a directory that hasn't been shared into the VM."> <message name="IDS_FILE_BROWSER_UNABLE_TO_OPEN_WITH_PLUGIN_VM_TITLE" desc="Title of the dialog shown to users when they try to open a file with Plugin VM from a directory that hasn't been shared into the VM.">
Unable to open with <ph name="APP_NAME">$1<ex>Plugin VM</ex></ph> Unable to open with <ph name="APP_NAME">$1<ex>Plugin VM</ex></ph>
</message> </message>
<message name="IDS_FILE_BROWSER_UNABLE_TO_OPEN_WITH_PLUGIN_VM_MESSAGE" desc="Body of the dialog shown to users when they try to open a file with Plugin VM from a directory that hasn't been shared into the VM."> <message name="IDS_FILE_BROWSER_UNABLE_TO_OPEN_WITH_PLUGIN_VM_DIRECTORY_NOT_SHARED_MESSAGE" desc="Body of the dialog shown to users when they try to open a file with an application in a virtual machine, but the file is not in a directory shared into the VM.">
To open files with <ph name="APP_NAME">$1<ex>Plugin VM</ex></ph> apps, first move them to <ph name="SHARED_DIRECTORY_LABEL">$2<ex>Plugin VM</ex></ph> folder. To open files with <ph name="APP_NAME">$1<ex>Libre Office</ex></ph> (<ph name="VM_SOFTWARE_NAME">$2<ex>Plugin VM</ex></ph>), first move them to the <ph name="FOLDER_NAME">$3<ex>Shared Files</ex></ph> folder.
</message>
<message name="IDS_FILE_BROWSER_UNABLE_TO_OPEN_WITH_PLUGIN_VM_EXTERNAL_DRIVE_MESSAGE" desc="Body of the dialog shown to users when they try to open a file with an application in a virtual machine, but the file is on an external drive so isn't accessile from with the VM.">
To open files with <ph name="APP_NAME">$1<ex>Libre Office</ex></ph> (<ph name="VM_SOFTWARE_NAME">$2<ex>Plugin VM</ex></ph>), first copy them to the <ph name="FOLDER_NAME">$3<ex>Shared Files</ex></ph> folder.
</message> </message>
<message name="IDS_FILE_BROWSER_TOGGLE_HIDDEN_FILES_COMMAND_LABEL" desc="Label for menu or button with checkmark that toggles visibility of hidden files."> <message name="IDS_FILE_BROWSER_TOGGLE_HIDDEN_FILES_COMMAND_LABEL" desc="Label for menu or button with checkmark that toggles visibility of hidden files.">
Show hidden files Show hidden files
......
...@@ -672,6 +672,38 @@ class FileTasks { ...@@ -672,6 +672,38 @@ class FileTasks {
* @private * @private
*/ */
executeInternal_(task) { executeInternal_(task) {
const onFileManagerPrivateExecuteTask = result => {
if (chrome.runtime.lastError) {
console.warn(
'Unable to execute task: ' + chrome.runtime.lastError.message);
return;
}
const taskResult = chrome.fileManagerPrivate.TaskResult;
switch (result) {
case taskResult.MESSAGE_SENT:
util.isTeleported(window).then((teleported) => {
if (teleported) {
this.ui_.showOpenInOtherDesktopAlert(this.entries_);
}
});
break;
case taskResult.FAILED_PLUGIN_VM_TASK_DIRECTORY_NOT_SHARED:
case taskResult.FAILED_PLUGIN_VM_TASK_EXTERNAL_DRIVE:
const messageId =
result == taskResult.FAILED_PLUGIN_VM_TASK_DIRECTORY_NOT_SHARED ?
'UNABLE_TO_OPEN_WITH_PLUGIN_VM_DIRECTORY_NOT_SHARED_MESSAGE' :
'UNABLE_TO_OPEN_WITH_PLUGIN_VM_EXTERNAL_DRIVE_MESSAGE';
this.ui_.alertDialog.showHtml(
strf(
'UNABLE_TO_OPEN_WITH_PLUGIN_VM_TITLE',
strf('PLUGIN_VM_APP_NAME')),
strf(
messageId, task.title, strf('PLUGIN_VM_APP_NAME'),
strf('PLUGIN_VM_DIRECTORY_LABEL')));
break;
}
};
this.checkAvailability_(() => { this.checkAvailability_(() => {
this.taskHistory_.recordTaskExecuted(task.taskId); this.taskHistory_.recordTaskExecuted(task.taskId);
let msg; let msg;
...@@ -686,34 +718,7 @@ class FileTasks { ...@@ -686,34 +718,7 @@ class FileTasks {
} else { } else {
FileTasks.recordZipHandlerUMA_(task.taskId); FileTasks.recordZipHandlerUMA_(task.taskId);
chrome.fileManagerPrivate.executeTask( chrome.fileManagerPrivate.executeTask(
task.taskId, this.entries_, (result) => { task.taskId, this.entries_, onFileManagerPrivateExecuteTask);
if (chrome.runtime.lastError) {
console.warn(
'Unable to execute task: ' +
chrome.runtime.lastError.message);
return;
}
switch (result) {
case chrome.fileManagerPrivate.TaskResult.MESSAGE_SENT:
util.isTeleported(window).then((teleported) => {
if (teleported) {
this.ui_.showOpenInOtherDesktopAlert(this.entries_);
}
});
break;
case chrome.fileManagerPrivate.TaskResult
.FAILED_PLUGIN_VM_TASK_DIRECTORY_NOT_SHARED:
this.ui_.alertDialog.showHtml(
strf(
'UNABLE_TO_OPEN_WITH_PLUGIN_VM_TITLE',
strf('PLUGIN_VM_APP_NAME')),
strf(
'UNABLE_TO_OPEN_WITH_PLUGIN_VM_MESSAGE',
strf('PLUGIN_VM_APP_NAME'),
strf('PLUGIN_VM_DIRECTORY_LABEL')));
break;
}
});
} }
}); });
} }
......
...@@ -95,6 +95,7 @@ function setUp() { ...@@ -95,6 +95,7 @@ function setUp() {
TaskResult: { TaskResult: {
MESSAGE_SENT: 'test_ms_task', MESSAGE_SENT: 'test_ms_task',
FAILED_PLUGIN_VM_TASK_DIRECTORY_NOT_SHARED: 'test_fpvtdns_task', FAILED_PLUGIN_VM_TASK_DIRECTORY_NOT_SHARED: 'test_fpvtdns_task',
FAILED_PLUGIN_VM_TASK_EXTERNAL_DRIVE: 'test_fpvted_task',
}, },
getFileTasks: function(entries, callback) { getFileTasks: function(entries, callback) {
setTimeout(callback.bind(null, [mockTask]), 0); setTimeout(callback.bind(null, [mockTask]), 0);
......
...@@ -72,7 +72,7 @@ testcase.sharePathWithCrostini = async () => { ...@@ -72,7 +72,7 @@ testcase.sharePathWithCrostini = async () => {
await remoteCall.waitForElement(appId, menuNoShareWithLinux); await remoteCall.waitForElement(appId, menuNoShareWithLinux);
}; };
testcase.pluginVmErrorDialog = async () => { testcase.pluginVmDirectoryNotSharedErrorDialog = async () => {
const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS); const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS);
// Override the tasks so the "Open with Plugin VM App" button becomes a // Override the tasks so the "Open with Plugin VM App" button becomes a
...@@ -128,7 +128,68 @@ testcase.pluginVmErrorDialog = async () => { ...@@ -128,7 +128,68 @@ testcase.pluginVmErrorDialog = async () => {
chrome.test.assertEq( chrome.test.assertEq(
['Unable to open with Plugin VM'], dialogTitles.map(el => el.text)); ['Unable to open with Plugin VM'], dialogTitles.map(el => el.text));
chrome.test.assertEq( chrome.test.assertEq(
['To open files with Plugin VM apps,' + ['To open files with Plugin VM App (Plugin VM), ' +
' first move them to Plugin VM folder.'], 'first move them to the Plugin VM folder.'],
dialogTexts.map(el => el.text));
};
testcase.pluginVmFileOnExternalDriveErrorDialog = async () => {
const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS);
// Override the tasks so the "Open with Plugin VM App" button becomes a
// dropdown option.
chrome.test.assertTrue(!!await remoteCall.callRemoteTestUtil(
'overrideTasks', appId, [[
{
taskId: 'text-app-id|app|text',
title: 'Text',
verb: 'open_with',
},
{
taskId: 'plugin-vm-app-id|pluginvm|open-with',
title: 'Plugin VM App',
verb: 'open_with',
}
]]));
// Right click on 'hello.txt' file, and wait for dialog with 'Open with'.
await remoteCall.callRemoteTestUtil(
'fakeMouseRightClick', appId,
['[id^="listitem-"][file-name="hello.txt"]']);
// Click 'Open with'.
await remoteCall.waitAndClickElement(
appId, 'cr-menu-item[command="#open-with"]:not([hidden])');
// Wait for app picker.
await remoteCall.waitForElement(appId, '#default-tasks-list:not([hidden])');
// Ensure app picker shows Plugin VM option.
const appOptions = await remoteCall.callRemoteTestUtil(
'queryAllElements', appId, ['#default-tasks-list [tabindex]']);
chrome.test.assertEq(
1, appOptions.filter(el => el.text == 'Open with Plugin VM App').length);
// Click on the Plugin VM app, and wait for error dialog.
await remoteCall.callRemoteTestUtil('fakeMouseClick', appId, [
`#default-tasks-list [tabindex]:nth-of-type(${
appOptions.map(el => el.text).indexOf('Open with Plugin VM App') + 1})`
]);
await remoteCall.waitUntilTaskExecutes(
appId, 'plugin-vm-app-id|pluginvm|open-with',
['failed_plugin_vm_task_external_drive']);
await remoteCall.waitForElement(appId, '.files-alert-dialog:not([hidden])');
// Validate error messages.
const dialogTitles = await remoteCall.callRemoteTestUtil(
'queryAllElements', appId, ['.files-alert-dialog .cr-dialog-title']);
const dialogTexts = await remoteCall.callRemoteTestUtil(
'queryAllElements', appId, ['.files-alert-dialog .cr-dialog-text']);
chrome.test.assertEq(
['Unable to open with Plugin VM'], dialogTitles.map(el => el.text));
chrome.test.assertEq(
['To open files with Plugin VM App (Plugin VM), ' +
'first copy them to the Plugin VM folder.'],
dialogTexts.map(el => el.text)); dialogTexts.map(el => el.text));
}; };
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