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

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: Resolve a bug with the entry.name used as mounted fileSystemId as entry.name can be duplicated. Now… 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
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..09458cdf25268712704560fb4d02955f63decfa3
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/api/fileSystemProvider/archive/background.js
@@ -0,0 +1,247 @@
+// 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 displayPath.
+// The value is a Volume object.
+var volumes = {};
+
+// Defines a volume object that contains information about a mounted file
+// system.
+function Volume(entry, metadata, opt_openedFiles) {
+ // Used for restoring the opened file entry after resuming the event page.
+ this.entry = entry;
+
+ // The volume metadata.
+ this.metadata = [];
+ for (var path in metadata) {
+ this.metadata[path] = metadata[path];
+ // Date object is serialized in JSON as string.
+ this.metadata[path].modificationTime =
+ new Date(metadata[path].modificationTime);
+ }
+
+ // A map with currently opened files. The key is a requestId value from the
+ // openFileRequested event, and the value is 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);
+};
+
+// Saves state in case of restarts, event page suspend, crashes, etc.
+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});
+}
+
+// Restores metadata for the passed file system ID.
+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);
+ });
+ });
+}
+
+// Reads metadata from a file and returns it with the onSuccess callback.
+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 opening a file with the extension or mime type
+// declared in the manifest file.
+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.
+ chrome.fileSystem.getDisplayPath(item.entry, function(displayPath) {
+ volumes[displayPath] = new Volume(item.entry, metadata);
+ chrome.fileSystemProvider.mount(
+ {fileSystemId: displayPath, displayName: 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.
+ 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);

Powered by Google App Engine
This is Rietveld 408576698