Commit f8781418 authored by Tatsuhisa Yamaguchi's avatar Tatsuhisa Yamaguchi Committed by Commit Bot

Zip Archiver: Stop persisting mount info.

Make Zip Archiver to forget password when requested to resume, as well
as returning error to make VolumeManager remove the persisted provided
volume info.
Remove all code for persisting zip mount state.

Bug: 789073,803752
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: Icb9a6e9ca04b7ed633480a17973d1dcb126d02e0
Reviewed-on: https://chromium-review.googlesource.com/940742
Commit-Queue: Tatsuhisa Yamaguchi <yamaguchi@chromium.org>
Reviewed-by: default avatarYuki Awano <yawano@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543048}
parent d953b6af
......@@ -10,7 +10,8 @@
*/
unpacker.app = {
/**
* The key used by chrome.storage.local to save and restore the volumes state.
* The key which was used by chrome.storage.local to save and restore the
* volumes state in old versions.
* @const {string}
*/
STORAGE_KEY: 'state',
......@@ -173,94 +174,20 @@ unpacker.app = {
},
/**
* Saves state in case of restarts, event page suspend, crashes, etc. This
* method does nothing when context is in incognito mode.
* @param {!Array<!unpacker.types.FileSystemId>} fileSystemIdsArray
* @private
*/
saveState_: function(fileSystemIdsArray) {
// If current context is in incognito mode, then skip save state because
// retainEntry is not available in incognito mode.
if (chrome.extension.inIncognitoContext)
return;
chrome.storage.local.get([unpacker.app.STORAGE_KEY], function(result) {
if (!result[unpacker.app.STORAGE_KEY]) // First save state call.
result[unpacker.app.STORAGE_KEY] = {};
// Overwrite state only for the volumes that have their file system id
// present in the input array. Leave the rest of the volumes state
// untouched.
fileSystemIdsArray.forEach(function(fileSystemId) {
var entryId = chrome.fileSystem.retainEntry(
unpacker.app.volumes[fileSystemId].entry);
result[unpacker.app.STORAGE_KEY][fileSystemId] = {
entryId: entryId,
passphrase: unpacker.app.volumes[fileSystemId]
.decompressor.passphraseManager.rememberedPassphrase
};
});
chrome.storage.local.set(result);
});
},
/**
* Removes state from local storage for a single volume. This method does
* nothing when context is in incognito mode.
* @param {!unpacker.types.FileSystemId} fileSystemId
* Removes state from local storage for all volumes, which was stored by
* older versions of the extension. This method does nothing when context is
* in incognito mode.
*/
removeState_: function(fileSystemId) {
cleanupOldStorageInfo: function() {
if (chrome.extension.inIncognitoContext)
return;
chrome.storage.local.get([unpacker.app.STORAGE_KEY], function(result) {
console.assert(
result[unpacker.app.STORAGE_KEY] &&
result[unpacker.app.STORAGE_KEY][fileSystemId],
'Should call removeState_ only for file systems that ',
'have previously called saveState_.');
delete result[unpacker.app.STORAGE_KEY][fileSystemId];
chrome.storage.local.set(result);
});
},
/**
* Restores archive's entry and opened files for the passed file system id.
* @param {!unpacker.types.FileSystemId} fileSystemId
* @return {!Promise<!Object>} Promise fulfilled with the entry and list of
* opened files.
* @private
*/
restoreVolumeState_: function(fileSystemId) {
if (chrome.extension.inIncognitoContext)
return Promise.reject('No state restored due to incognito context');
return new Promise(function(fulfill, reject) {
chrome.storage.local.get([unpacker.app.STORAGE_KEY], function(result) {
if (!result[unpacker.app.STORAGE_KEY]) {
reject('FAILED');
return;
}
var volumeState = result[unpacker.app.STORAGE_KEY][fileSystemId];
if (!volumeState) {
console.error('No state for: ' + fileSystemId + '.');
reject('FAILED');
return;
}
chrome.fileSystem.restoreEntry(volumeState.entryId, function(entry) {
if (chrome.runtime.lastError) {
console.error(
'Restore entry error for <', fileSystemId,
'>: ' + chrome.runtime.lastError.message);
reject('FAILED');
return;
}
fulfill({entry: entry, passphrase: volumeState.passphrase});
if (result[unpacker.app.STORAGE_KEY]) {
chrome.storage.local.clear(function() {
console.info('Cleaned up archive mount info from older versions.');
});
});
}
});
},
......@@ -321,63 +248,6 @@ unpacker.app = {
});
},
/**
* Restores a volume mounted previously to a suspend / restart. In case of
* failure of the load promise for fileSystemId, the corresponding volume is
* forcely unmounted.
* @param {!unpacker.types.FileSystemId} fileSystemId
* @return {!Promise} A promise that restores state and loads volume.
* @private
*/
restoreSingleVolume_: function(fileSystemId) {
// Load volume after restart / suspend page event.
return unpacker.app.restoreVolumeState_(fileSystemId)
.then(function(state) {
return new Promise(function(fulfill, reject) {
// Check if the file system is compatible with this version of the
// ZIP unpacker.
// TODO(mtomasz): Implement remounting instead of unmounting.
chrome.fileSystemProvider.get(fileSystemId, function(fileSystem) {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError.name);
reject('FAILED');
return;
}
if (!fileSystem || fileSystem.openedFilesLimit != 1) {
console.error('No compatible mounted file system found.');
reject('FAILED');
return;
}
fulfill({state: state, fileSystem: fileSystem});
});
});
})
.then(function(stateWithFileSystem) {
var openedFilesOptions = {};
stateWithFileSystem.fileSystem.openedFiles.forEach(function(
openedFile) {
openedFilesOptions[openedFile.openRequestId] = {
fileSystemId: fileSystemId,
requestId: openedFile.openRequestId,
mode: openedFile.mode,
filePath: openedFile.filePath
};
});
return unpacker.app.loadVolume_(
fileSystemId, stateWithFileSystem.state.entry, openedFilesOptions);
})
.catch(function(error) {
console.error(error.stack || error);
// Force unmount in case restore failed. All resources related to the
// volume will be cleanup from both memory and local storage.
// TODO(523195): Show a notification that the source file is gone.
return unpacker.app.unmountVolume(fileSystemId, true)
.then(function() {
return Promise.reject('FAILED');
});
});
},
/**
* Ensures a volume is loaded by returning its corresponding loaded promise
* from unpacker.app.volumeLoadedPromises. In case there is no such promise,
......@@ -400,11 +270,14 @@ unpacker.app = {
return unpacker.app.moduleLoadedPromise.then(function() {
// In case there is no volume promise for fileSystemId then we
// received a call after restart / suspend as load promises are
// created on launched. In this case we will restore volume state
// from local storage and create a new load promise.
// created on launched.
if (!unpacker.app.volumeLoadedPromises[fileSystemId]) {
// This path was once used for restoring volume state from local
// storage, but we no longer do it. Emulate an error to make caller
// forget the persisted mount info.
unpacker.app.volumeLoadedPromises[fileSystemId] =
unpacker.app.restoreSingleVolume_(fileSystemId);
unpacker.app.unmountVolume(fileSystemId, true)
.then(Promise.reject('FAILED'));
}
// Decrement the counter when the mounting process ends.
......@@ -499,8 +372,7 @@ unpacker.app = {
},
/**
* Cleans up the resources for a volume, except for the local storage. If
* necessary that can be done using unpacker.app.removeState_.
* Cleans up the resources for a volume.
* @param {!unpacker.types.FileSystemId} fileSystemId
*/
cleanupVolume: function(fileSystemId) {
......@@ -549,16 +421,6 @@ unpacker.app = {
delete unpacker.app.compressors[compressorId];
},
/**
* Updates the state in case of restarts, event page suspend, crashes, etc.
* Use this method to update or save the state out side of the object in case
* when password changes, etc.
* @param {!Array<!unpacker.types.FileSystemId>} fileSystemIdsArray
*/
updateState: function(fileSystemIdsArray) {
unpacker.app.saveState_(fileSystemIdsArray);
},
/**
* Unmounts a volume and removes any resources related to the volume from both
* the extension and the local storage state.
......@@ -614,8 +476,6 @@ unpacker.app = {
else
unpacker.app.cleanupVolume(fileSystemId);
// Remove volume from local storage.
unpacker.app.removeState_(fileSystemId);
fulfill();
});
});
......@@ -969,9 +829,6 @@ unpacker.app = {
});
})
.then(function() {
// Mount the volume and save its information in local
// storage in order to be able to recover the metadata
// in case of restarts, system crashes, etc.
chrome.fileSystemProvider.mount(
{
fileSystemId: fileSystemId,
......@@ -984,9 +841,6 @@ unpacker.app = {
onError(chrome.runtime.lastError, fileSystemId);
return;
}
// Save state so in case of restarts we are able
// to correctly get the archive's metadata.
unpacker.app.saveState_([fileSystemId]);
onSuccess(fileSystemId);
});
})
......@@ -1026,12 +880,4 @@ unpacker.app = {
else
unpacker.app.onLaunchedWithUnpack(launchData, opt_onSuccess, opt_onError);
},
/**
* Saves the state before suspending the event page, so we can resume it
* once new events arrive.
*/
onSuspend: function() {
unpacker.app.saveState_(Object.keys(unpacker.app.volumes));
}
};
......@@ -296,8 +296,6 @@ unpacker.Decompressor.prototype.readChunk_ = function(data, requestId) {
unpacker.Decompressor.prototype.readPassphrase_ = function(data, requestId) {
this.passphraseManager.getPassphrase()
.then(function(passphrase) {
// Update remembered password
unpacker.app.updateState([this.fileSystemId_]);
this.naclModule_.postMessage(
unpacker.request.createReadPassphraseDoneResponse(
this.fileSystemId_, requestId, passphrase));
......
......@@ -8,6 +8,7 @@ function init() {
loadTimeData.data = strings;
i18nTemplate.process(document, loadTimeData);
});
backgroundPage.unpacker.app.cleanupOldStorageInfo();
});
}
......
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