Commit 36a75677 authored by Zain Afzal's avatar Zain Afzal Committed by Commit Bot

Make request save file return a pickedFile.

Previously the media app was unable to perform a save as operation on a
file obtained from a drag and drop or from a paste event. This was
because the logic surrounding the operation was encapsulated in
ReceivedFile which is a class the media app does not have access to.
This cl updates the requestSaveFile IPC to return a ReceivedFile
instead of returning a file token, allowing the media app to obtain a
native file, overwrite it and copy over it's functions so future saves
can happen in place.

The google3 side of this change is @ cl/334717684.

Bug: b/165769056, b/169630668
Change-Id: Ied8dd540f9f319b18b427e6566851bc628ed3204
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2439969Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Reviewed-by: default avatardstockwell <dstockwell@google.com>
Commit-Queue: Zain Afzal <zafzal@google.com>
Cr-Commit-Position: refs/heads/master@{#812607}
parent 1b05ee04
......@@ -245,7 +245,16 @@ guestMessagePipe.registerHandler(Message.REQUEST_SAVE_FILE, async (message) => {
/** @type {!RequestSaveFileMessage} */ (message);
const handle = await pickWritableFile(suggestedName, mimeType);
/** @type {!RequestSaveFileResponse} */
const response = {token: generateToken(handle)};
const response = {
pickedFileContext: {
token: generateToken(handle),
file: assertCast(await handle.getFile()),
name: handle.name,
error: '',
canDelete: false,
canRename: false,
}
};
return response;
});
......
......@@ -145,17 +145,17 @@ mediaApp.ClientApiDelegate = function() {};
mediaApp.ClientApiDelegate.prototype.openFeedbackDialog = function() {};
/**
* Request for the user to be prompted with a save file dialog. Once the user
* selects a location a new file handle is created and a unique token to that
* file will be returned. This token can be then used with saveCopy(). The file
* extension on `suggestedName` and the provided `mimeType` are used to inform
* the save as dialog what file should be created. Once the Native Filesystem
* API allows, this save as dialog will additionally have the filename input be
* pre-filled with `suggestedName`.
* selects a location a new file handle is created and a new AbstractFile
* representing that file will be returned. This can be then used in a save as
* operation. The file extension on `suggestedName` and the provided `mimeType`
* are used to inform the save as dialog what file should be created. Once the
* Native Filesystem API allows, this save as dialog will additionally have the
* filename input be pre-filled with `suggestedName`.
* TODO(b/161087799): Update function description once Native Filesystem API
* supports suggestedName.
* @param {string} suggestedName
* @param {string} mimeType
* @return {!Promise<number>}
* @return {!Promise<!mediaApp.AbstractFile>}
*/
mediaApp.ClientApiDelegate.prototype.requestSaveFile = function(
suggestedName, mimeType) {};
......
......@@ -140,7 +140,7 @@ let RequestSaveFileMessage;
* Response message sent by the privileged context with a unique identifier for
* the new writable file created on disk by the corresponding request save
* file message.
* @typedef {{token: number}}
* @typedef {{pickedFileContext: !FileContext}}
*/
let RequestSaveFileResponse;
......
......@@ -223,7 +223,7 @@ const DELEGATE = {
/**
* @param {string} suggestedName
* @param {string} mimeType
* @return {!Promise<number>}
* @return {!Promise<!mediaApp.AbstractFile>}
*/
async requestSaveFile(suggestedName, mimeType) {
/** @type {!RequestSaveFileMessage} */
......@@ -232,7 +232,7 @@ const DELEGATE = {
/** @type {!RequestSaveFileResponse} */ (
await parentMessagePipe.sendMessage(
Message.REQUEST_SAVE_FILE, msg));
return response.token;
return new ReceivedFile(response.pickedFileContext);
},
/**
* @return {!Promise<undefined>}
......
......@@ -98,9 +98,9 @@ async function runTestQuery(data) {
if (!existingFile) {
result = 'requestSaveFile failed, no file loaded';
} else {
const token = await DELEGATE.requestSaveFile(
const pickedFile = await DELEGATE.requestSaveFile(
existingFile.name, existingFile.mimeType);
result = token.toString();
result = assertCast(pickedFile.token).toString();
}
} else if (data.saveAs) {
const existingFile = assertCast(lastReceivedFileList).item(0);
......@@ -109,10 +109,11 @@ async function runTestQuery(data) {
} else {
const file = firstReceivedItem();
try {
const token = await DELEGATE.requestSaveFile(
existingFile.name, existingFile.mimeType);
const token = (await DELEGATE.requestSaveFile(
existingFile.name, existingFile.mimeType))
.token;
const testBlob = new Blob([data.saveAs]);
await assertCast(file.saveAs).call(file, testBlob, token);
await assertCast(file.saveAs).call(file, testBlob, assertCast(token));
result = file.name;
extraResultData = {blobText: await file.blob.text()};
} catch (/** @type{!Error} */ error) {
......
......@@ -922,6 +922,8 @@ TEST_F('MediaAppUIBrowserTest', 'RequestSaveFileIPC', async () => {
const result = await sendTestMessage({requestSaveFile: true});
const options = await chooseEntries;
const lastToken = [...tokenMap.keys()].slice(-1)[0];
// Check the token matches to confirm the ReceivedFile returned represents the
// new file created on disk.
assertMatch(result.testQueryResult, lastToken);
assertEquals(options.types.length, 1);
assertEquals(options.types[0].description, '.png');
......
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