| 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);
|
|
|