Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3380)

Unified Diff: chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/background.js

Issue 360673004: Demonstrate the functionality of the File System Provider API for archives. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Split readMetadataFromFile function in order to make the code more readable and correct some commen… Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/example1.fake » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/background.js
diff --git a/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/background.js b/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/background.js
new file mode 100644
index 0000000000000000000000000000000000000000..333172bbc2d810b756ab3bc468dc5fc932896f20
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/background.js
@@ -0,0 +1,245 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+// Metadata is stored in files as serialized to JSON maps. See contents of
+// example1.fake and example2.fake.
+
+// Multiple volumes can be opened at the same time. The key is the
+// fileSystemId, which is the same as the file's entry.name.
+// The value is a Volume object.
+var volumes = {};
+
+// Defines a volume object that contains information about mounted devices.
mtomasz 2014/07/01 00:40:33 nit: about mounted devices -> about a mounted file
cmihail 2014/07/01 01:27:20 Done.
+function Volume(entry, metadata, opt_openedFiles) {
+ // Used for restoring the opened file entry after resuming the event page.
+ this.entry = entry;
+
+ // The volume metadata. Date object is serialized in JSON as string.
mtomasz 2014/07/01 00:40:33 nit: I think the second comment is confusing in th
cmihail 2014/07/01 01:27:21 Done.
+ this.metadata = [];
+ for (var path in metadata) {
+ this.metadata[path] = metadata[path];
+ this.metadata[path].modificationTime =
+ new Date(metadata[path].modificationTime);
+ }
+
+ // A map with currently opened files. As key it has requestId of
mtomasz 2014/07/01 00:40:32 nit: As key it has requestId... -> The key is a re
cmihail 2014/07/01 01:27:21 Done.
+ // openFileRequested and as a value the file path.
+ this.openedFiles = opt_openedFiles ? opt_openedFiles : {};
+};
+
+function onUnmountRequested(options, onSuccess, onError) {
+ if (Object.keys(volumes[options.fileSystemId].openedFiles).length != 0) {
+ onError('IN_USE');
+ return;
+ }
+
+ chrome.fileSystemProvider.unmount(
+ {fileSystemId: options.fileSystemId},
+ function() {
+ delete volumes[options.fileSystemId];
+ saveState(); // Remove volume from local storage state.
+ onSuccess();
+ },
+ function() {
+ onError('FAILED');
+ });
+};
+
+function onGetMetadataRequested(options, onSuccess, onError) {
+ restoreState(options.fileSystemId, function () {
+ var entryMetadata =
+ volumes[options.fileSystemId].metadata[options.entryPath];
+ if (!entryMetadata)
+ error('NOT_FOUND');
+ else
+ onSuccess(entryMetadata);
+ }, onError);
+};
+
+function onReadDirectoryRequested(options, onSuccess, onError) {
+ restoreState(options.fileSystemId, function () {
+ var directoryMetadata =
+ volumes[options.fileSystemId].metadata[options.directoryPath];
+ if (!directoryMetadata) {
+ onError('NOT_FOUND');
+ return;
+ }
+ if (!directoryMetadata.isDirectory) {
+ onError('NOT_A_DIRECTORY');
+ return;
+ }
+
+ // Retrieve directory contents from metadata.
+ var entries = [];
+ for (var entry in volumes[options.fileSystemId].metadata) {
+ // Do not add itself on the list.
+ if (entry == options.directoryPath)
+ continue;
+ // Check if the entry is a child of the requested directory.
+ if (entry.indexOf(options.directoryPath) != 0)
+ continue;
+ // Restrict to direct children only.
+ if (entry.substring(options.directoryPath.length + 1).indexOf('/') != -1)
+ continue;
+
+ entries.push(volumes[options.fileSystemId].metadata[entry]);
+ }
+ onSuccess(entries, false /* Last call. */);
+ }, onError);
+};
+
+function onOpenFileRequested(options, onSuccess, onError) {
+ restoreState(options.fileSystemId, function () {
+ if (options.mode != 'READ' || options.create) {
+ onError('INVALID_OPERATION');
+ } else {
+ volumes[options.fileSystemId].openedFiles[options.requestId] =
+ options.filePath;
+ onSuccess();
+ }
+ }, onError);
+};
+
+function onCloseFileRequested(options, onSuccess, onError) {
+ restoreState(options.fileSystemId, function () {
+ if (!volumes[options.fileSystemId].openedFiles[options.openRequestId]) {
+ onError('INVALID_OPERATION');
+ } else {
+ delete volumes[options.fileSystemId].openedFiles[options.openRequestId];
+ onSuccess();
+ }
+ }, onError);
+};
+
+function onReadFileRequested(options, onSuccess, onError) {
+ restoreState(options.fileSystemId, function () {
+ var filePath =
+ volumes[options.fileSystemId].openedFiles[options.openRequestId];
+ if (!filePath) {
+ onError('INVALID_OPERATION');
+ return;
+ }
+
+ var contents = volumes[options.fileSystemId].metadata[filePath].contents;
+
+ // Write the contents as ASCII text.
+ var buffer = new ArrayBuffer(options.length);
+ var bufferView = new Uint8Array(buffer);
+ for (var i = 0; i < options.length; i++) {
+ bufferView[i] = contents.charCodeAt(i);
+ }
+
+ onSuccess(buffer, false /* Last call. */);
+ }, onError);
+};
+
+// Save state in case of restarts, event page suspend, crashes, etc.
mtomasz 2014/07/01 00:40:32 nit: Save -> Saves
cmihail 2014/07/01 01:27:21 Done.
+function saveState() {
+ var state = {};
+ for (var volumeId in volumes) {
+ var entryId = chrome.fileSystem.retainEntry(volumes[volumeId].entry);
+ state[volumeId] = {
+ entryId: entryId,
+ openedFiles: volumes[volumeId].openedFiles
+ };
+ }
+ chrome.storage.local.set({state: state});
+}
+
+// Restore state. In this case the file system is already mounted and
mtomasz 2014/07/01 00:40:32 nit: Restore -> Restores. Comments for methods sho
cmihail 2014/07/01 01:27:22 Done.
+// we only need to obtain the metadata, which is done lazily.
mtomasz 2014/07/01 00:40:33 The comment about remounting is confusing. How abo
cmihail 2014/07/01 01:27:21 Done.
+function restoreState(fileSystemId, onSuccess, onError) {
+ chrome.storage.local.get(['state'], function(result) {
+ // Check if metadata for the given file system is alread in memory.
+ if (volumes[fileSystemId]) {
+ onSuccess();
+ return;
+ }
+
+ chrome.fileSystem.restoreEntry(
+ result.state[fileSystemId].entryId,
+ function(entry) {
+ readMetadataFromFile(entry,
+ function(metadata) {
+ volumes[fileSystemId] = new Volume(entry, metadata,
+ result.state[fileSystemId].openedFiles);
+ onSuccess();
+ }, onError);
+ });
+ });
+}
+
+// onSuccess has as parameter the metadata read in JSON format.
mtomasz 2014/07/01 00:40:33 The returned metadata is already deserialized, so
cmihail 2014/07/01 01:27:21 Yes. I wasn't clear. I was referring to the fact t
+function readMetadataFromFile(entry, onSuccess, onError) {
+ entry.file(function(file) {
+ var fileReader = new FileReader();
+ fileReader.onload = function(event) {
+ onSuccess(JSON.parse(event.target.result));
+ };
+
+ fileReader.onerror = function(event) {
+ onError('FAILED');
+ };
+
+ fileReader.readAsText(file);
+ });
+}
+
+// Event called on clicking the file with the extension or mime type
+// mentioned in the manifest file.
mtomasz 2014/07/01 00:40:32 nit: clicking on the file -> opening the file nit:
cmihail 2014/07/01 01:27:21 Done.
+chrome.app.runtime.onLaunched.addListener(function(event) {
+ event.items.forEach(function(item) {
+ readMetadataFromFile(item.entry,
+ function(metadata) {
+ // 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.
+ volumes[item.entry.name] = new Volume(item.entry, metadata);
+ chrome.fileSystemProvider.mount(
+ {fileSystemId: item.entry.name, displayName: item.entry.name},
mtomasz 2014/07/01 00:40:33 This may fail when two files with the same name ar
cmihail 2014/07/01 01:27:20 Done. For displayName I have kept item.entry.name
+ function() { saveState(); },
+ function() { console.error('Failed to mount.'); });
+ },
+ function(error) {
+ console.error(error);
+ });
+ });
+});
+
+// Event called on a profile startup.
+chrome.runtime.onStartup.addListener(function () {
+ chrome.storage.local.get(['state'], function(result) {
+ // Nothing to change.
+ if (!result.state)
+ return;
+
+ // Remove files opened before the profile shutdown from the local
+ // storage state.
mtomasz 2014/07/01 00:40:32 nit: local storage state -> local storage.
cmihail 2014/07/01 01:27:21 Done.
+ for (var volumeId in result.state) {
+ result.state[volumeId].openedFiles = {};
+ }
+ chrome.storage.local.set({state: result.state});
+ });
+});
+
+// Save the state before suspending the event page, so we can resume it
+// once new events arrive.
+chrome.runtime.onSuspend.addListener(function() {
+ saveState();
+});
+
+chrome.fileSystemProvider.onUnmountRequested.addListener(
+ onUnmountRequested);
+chrome.fileSystemProvider.onGetMetadataRequested.addListener(
+ onGetMetadataRequested);
+chrome.fileSystemProvider.onReadDirectoryRequested.addListener(
+ onReadDirectoryRequested);
+chrome.fileSystemProvider.onOpenFileRequested.addListener(
+ onOpenFileRequested);
+chrome.fileSystemProvider.onCloseFileRequested.addListener(
+ onCloseFileRequested);
+chrome.fileSystemProvider.onReadFileRequested.addListener(
+ onReadFileRequested);
« no previous file with comments | « no previous file | chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/example1.fake » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698