Commit f7768b6a authored by Zain Afzal's avatar Zain Afzal Committed by Commit Bot

Add delegate function to open a new file

Since the media_app in the guest frame can't use any file system api
functions we need some IPC so the guest frame can ask the parent frame
to show the open file picker. This cl adds a delegate function which
allows for this functionality, the parent frame will show the picker
and insert the picked file into the navigation order after the current
file.

Note that since we navigate to the new file via a normal call to
"advance" the media app will show a dialog asking users if they are
sure they want to navigate if they have unsaved changes. If they click
cancel the get into a weird state where clicking "next" will make them
jump forward a file. Finding a way to deal with this is tracked in
b/163662946.

Additionally this updates the externs for "showOpenFilePicker" so it
now returns a FileSystemFileHandle, not a fileSystemHandle. This is
consistent with both the spec:

https://wicg.github.io/native-file-system/#dom-window-showopenfilepicker

and the implementation:

https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl;l=17;drc=0c6b1827bb42907302eac1e1a24f93768fc89985

Bug: b/147395281
Change-Id: I199bc787b2f69e6cd5f6785fb4f94556cd1438cc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2352954
Commit-Queue: Zain Afzal <zafzal@google.com>
Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798058}
parent ea330473
...@@ -242,6 +242,19 @@ guestMessagePipe.registerHandler(Message.SAVE_AS, async (message) => { ...@@ -242,6 +242,19 @@ guestMessagePipe.registerHandler(Message.SAVE_AS, async (message) => {
return response; return response;
}); });
guestMessagePipe.registerHandler(Message.OPEN_FILE, async () => {
const [handle] = await window.showOpenFilePicker({multiple: false});
/** @type {!FileDescriptor} */
const fileDescriptor = {
token: generateToken(handle),
file: null,
handle: handle,
inCurrentDirectory: false
};
currentFiles.splice(entryIndex + 1, 0, fileDescriptor);
advance(1);
});
/** /**
* Shows a file picker to get a writable file. * Shows a file picker to get a writable file.
* @param {string} suggestedName * @param {string} suggestedName
......
...@@ -149,6 +149,13 @@ mediaApp.ClientApiDelegate.prototype.openFeedbackDialog = function() {}; ...@@ -149,6 +149,13 @@ mediaApp.ClientApiDelegate.prototype.openFeedbackDialog = function() {};
*/ */
mediaApp.ClientApiDelegate.prototype.requestSaveFile = function( mediaApp.ClientApiDelegate.prototype.requestSaveFile = function(
suggestedName, mimeType) {}; suggestedName, mimeType) {};
/**
* Request for the user to be prompted with a open file picker. Once the user
* selects a file, the file is inserted into the navigation order after the
* current file and navigated to.
* @return {!Promise<undefined>}
*/
mediaApp.ClientApiDelegate.prototype.openFile = function() {};
/** /**
* The client Api for interacting with the media app instance. * The client Api for interacting with the media app instance.
......
...@@ -18,6 +18,7 @@ const Message = { ...@@ -18,6 +18,7 @@ const Message = {
LOAD_FILES: 'load-files', LOAD_FILES: 'load-files',
NAVIGATE: 'navigate', NAVIGATE: 'navigate',
OPEN_FEEDBACK_DIALOG: 'open-feedback-dialog', OPEN_FEEDBACK_DIALOG: 'open-feedback-dialog',
OPEN_FILE: 'open-file',
OVERWRITE_FILE: 'overwrite-file', OVERWRITE_FILE: 'overwrite-file',
RENAME_FILE: 'rename-file', RENAME_FILE: 'rename-file',
REQUEST_SAVE_FILE: 'request-save-file', REQUEST_SAVE_FILE: 'request-save-file',
......
...@@ -236,6 +236,12 @@ const DELEGATE = { ...@@ -236,6 +236,12 @@ const DELEGATE = {
await parentMessagePipe.sendMessage( await parentMessagePipe.sendMessage(
Message.REQUEST_SAVE_FILE, msg)); Message.REQUEST_SAVE_FILE, msg));
return response.token; return response.token;
},
/**
* @return {!Promise<undefined>}
*/
async openFile() {
await parentMessagePipe.sendMessage(Message.OPEN_FILE);
} }
}; };
......
...@@ -24,6 +24,7 @@ let TestMessageResponseData; ...@@ -24,6 +24,7 @@ let TestMessageResponseData;
* requestFullscreen: (boolean|undefined), * requestFullscreen: (boolean|undefined),
* requestSaveFile: (boolean|undefined), * requestSaveFile: (boolean|undefined),
* saveAs: (string|undefined), * saveAs: (string|undefined),
* openFile: (boolean|undefined),
* testQuery: string, * testQuery: string,
* }} * }}
*/ */
......
...@@ -118,6 +118,8 @@ async function runTestQuery(data) { ...@@ -118,6 +118,8 @@ async function runTestQuery(data) {
} else if (data.getFileErrors) { } else if (data.getFileErrors) {
result = result =
assertCast(lastReceivedFileList).files.map(file => file.error).join(); assertCast(lastReceivedFileList).files.map(file => file.error).join();
} else if (data.openFile) {
await DELEGATE.openFile();
} }
return {testQueryResult: result, testQueryResultData: extraResultData}; return {testQueryResult: result, testQueryResultData: extraResultData};
} }
......
...@@ -917,6 +917,23 @@ TEST_F('MediaAppUIBrowserTest', 'SaveAsErrorHandling', async () => { ...@@ -917,6 +917,23 @@ TEST_F('MediaAppUIBrowserTest', 'SaveAsErrorHandling', async () => {
testDone(); testDone();
}); });
// Tests the IPC behind the openFile delegate function.
TEST_F('MediaAppUIBrowserTest', 'OpenFileIPC', async () => {
const pickedFileHandle = new FakeFileSystemFileHandle('picked_file.jpg');
window.showOpenFilePicker = () => Promise.resolve([pickedFileHandle]);
await sendTestMessage({openFile: true});
const lastToken = [...tokenMap.keys()].slice(-1)[0];
assertEquals(entryIndex, 0);
assertEquals(currentFiles.length, 1);
assertEquals(currentFiles[0].handle, pickedFileHandle);
assertEquals(currentFiles[0].handle.name, 'picked_file.jpg');
assertEquals(currentFiles[0].token, lastToken);
assertEquals(tokenMap.get(currentFiles[0].token), currentFiles[0].handle);
testDone();
});
TEST_F('MediaAppUIBrowserTest', 'RelatedFiles', async () => { TEST_F('MediaAppUIBrowserTest', 'RelatedFiles', async () => {
const testFiles = [ const testFiles = [
{name: 'matroska.mkv'}, {name: 'matroska.mkv'},
......
...@@ -202,7 +202,7 @@ let FilePickerOptions; ...@@ -202,7 +202,7 @@ let FilePickerOptions;
/** /**
* https://wicg.github.io/native-file-system/#native-filesystem * https://wicg.github.io/native-file-system/#native-filesystem
* @param {(!FilePickerOptions|undefined)} options * @param {(!FilePickerOptions|undefined)} options
* @return {!Promise<(!Array<!FileSystemHandle>)>} * @return {!Promise<(!Array<!FileSystemFileHandle>)>}
*/ */
window.showOpenFilePicker; window.showOpenFilePicker;
......
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