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

Side by Side 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, 5 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 'use strict';
6
7 // Metadata is stored in files as serialized to JSON maps. See contents of
8 // example1.fake and example2.fake.
9
10 // Multiple volumes can be opened at the same time. The key is the
11 // fileSystemId, which is the same as the file's displayPath.
12 // The value is a Volume object.
13 var volumes = {};
14
15 // Defines a volume object that contains information about a mounted file
16 // system.
17 function Volume(entry, metadata, opt_openedFiles) {
18 // Used for restoring the opened file entry after resuming the event page.
19 this.entry = entry;
20
21 // The volume metadata.
22 this.metadata = [];
23 for (var path in metadata) {
24 this.metadata[path] = metadata[path];
25 // Date object is serialized in JSON as string.
26 this.metadata[path].modificationTime =
27 new Date(metadata[path].modificationTime);
28 }
29
30 // A map with currently opened files. The key is a requestId value from the
31 // openFileRequested event, and the value is the file path.
32 this.openedFiles = opt_openedFiles ? opt_openedFiles : {};
33 };
34
35 function onUnmountRequested(options, onSuccess, onError) {
36 if (Object.keys(volumes[options.fileSystemId].openedFiles).length != 0) {
37 onError('IN_USE');
38 return;
39 }
40
41 chrome.fileSystemProvider.unmount(
42 {fileSystemId: options.fileSystemId},
43 function() {
44 delete volumes[options.fileSystemId];
45 saveState(); // Remove volume from local storage state.
46 onSuccess();
47 },
48 function() {
49 onError('FAILED');
50 });
51 };
52
53 function onGetMetadataRequested(options, onSuccess, onError) {
54 restoreState(options.fileSystemId, function () {
55 var entryMetadata =
56 volumes[options.fileSystemId].metadata[options.entryPath];
57 if (!entryMetadata)
58 error('NOT_FOUND');
59 else
60 onSuccess(entryMetadata);
61 }, onError);
62 };
63
64 function onReadDirectoryRequested(options, onSuccess, onError) {
65 restoreState(options.fileSystemId, function () {
66 var directoryMetadata =
67 volumes[options.fileSystemId].metadata[options.directoryPath];
68 if (!directoryMetadata) {
69 onError('NOT_FOUND');
70 return;
71 }
72 if (!directoryMetadata.isDirectory) {
73 onError('NOT_A_DIRECTORY');
74 return;
75 }
76
77 // Retrieve directory contents from metadata.
78 var entries = [];
79 for (var entry in volumes[options.fileSystemId].metadata) {
80 // Do not add itself on the list.
81 if (entry == options.directoryPath)
82 continue;
83 // Check if the entry is a child of the requested directory.
84 if (entry.indexOf(options.directoryPath) != 0)
85 continue;
86 // Restrict to direct children only.
87 if (entry.substring(options.directoryPath.length + 1).indexOf('/') != -1)
88 continue;
89
90 entries.push(volumes[options.fileSystemId].metadata[entry]);
91 }
92 onSuccess(entries, false /* Last call. */);
93 }, onError);
94 };
95
96 function onOpenFileRequested(options, onSuccess, onError) {
97 restoreState(options.fileSystemId, function () {
98 if (options.mode != 'READ' || options.create) {
99 onError('INVALID_OPERATION');
100 } else {
101 volumes[options.fileSystemId].openedFiles[options.requestId] =
102 options.filePath;
103 onSuccess();
104 }
105 }, onError);
106 };
107
108 function onCloseFileRequested(options, onSuccess, onError) {
109 restoreState(options.fileSystemId, function () {
110 if (!volumes[options.fileSystemId].openedFiles[options.openRequestId]) {
111 onError('INVALID_OPERATION');
112 } else {
113 delete volumes[options.fileSystemId].openedFiles[options.openRequestId];
114 onSuccess();
115 }
116 }, onError);
117 };
118
119 function onReadFileRequested(options, onSuccess, onError) {
120 restoreState(options.fileSystemId, function () {
121 var filePath =
122 volumes[options.fileSystemId].openedFiles[options.openRequestId];
123 if (!filePath) {
124 onError('INVALID_OPERATION');
125 return;
126 }
127
128 var contents = volumes[options.fileSystemId].metadata[filePath].contents;
129
130 // Write the contents as ASCII text.
131 var buffer = new ArrayBuffer(options.length);
132 var bufferView = new Uint8Array(buffer);
133 for (var i = 0; i < options.length; i++) {
134 bufferView[i] = contents.charCodeAt(i);
135 }
136
137 onSuccess(buffer, false /* Last call. */);
138 }, onError);
139 };
140
141 // Saves state in case of restarts, event page suspend, crashes, etc.
142 function saveState() {
143 var state = {};
144 for (var volumeId in volumes) {
145 var entryId = chrome.fileSystem.retainEntry(volumes[volumeId].entry);
146 state[volumeId] = {
147 entryId: entryId,
148 openedFiles: volumes[volumeId].openedFiles
149 };
150 }
151 chrome.storage.local.set({state: state});
152 }
153
154 // Restores metadata for the passed file system ID.
155 function restoreState(fileSystemId, onSuccess, onError) {
156 chrome.storage.local.get(['state'], function(result) {
157 // Check if metadata for the given file system is alread in memory.
158 if (volumes[fileSystemId]) {
159 onSuccess();
160 return;
161 }
162
163 chrome.fileSystem.restoreEntry(
164 result.state[fileSystemId].entryId,
165 function(entry) {
166 readMetadataFromFile(entry,
167 function(metadata) {
168 volumes[fileSystemId] = new Volume(entry, metadata,
169 result.state[fileSystemId].openedFiles);
170 onSuccess();
171 }, onError);
172 });
173 });
174 }
175
176 // Reads metadata from a file and returns it with the onSuccess callback.
177 function readMetadataFromFile(entry, onSuccess, onError) {
178 entry.file(function(file) {
179 var fileReader = new FileReader();
180 fileReader.onload = function(event) {
181 onSuccess(JSON.parse(event.target.result));
182 };
183
184 fileReader.onerror = function(event) {
185 onError('FAILED');
186 };
187
188 fileReader.readAsText(file);
189 });
190 }
191
192 // Event called on opening a file with the extension or mime type
193 // declared in the manifest file.
194 chrome.app.runtime.onLaunched.addListener(function(event) {
195 event.items.forEach(function(item) {
196 readMetadataFromFile(item.entry,
197 function(metadata) {
198 // Mount the volume and save its information in local storage
199 // in order to be able to recover the metadata in case of
200 // restarts, system crashes, etc.
201 chrome.fileSystem.getDisplayPath(item.entry, function(displayPath) {
202 volumes[displayPath] = new Volume(item.entry, metadata);
203 chrome.fileSystemProvider.mount(
204 {fileSystemId: displayPath, displayName: item.entry.name},
205 function() { saveState(); },
206 function() { console.error('Failed to mount.'); });
207 });
208 },
209 function(error) {
210 console.error(error);
211 });
212 });
213 });
214
215 // Event called on a profile startup.
216 chrome.runtime.onStartup.addListener(function () {
217 chrome.storage.local.get(['state'], function(result) {
218 // Nothing to change.
219 if (!result.state)
220 return;
221
222 // Remove files opened before the profile shutdown from the local storage.
223 for (var volumeId in result.state) {
224 result.state[volumeId].openedFiles = {};
225 }
226 chrome.storage.local.set({state: result.state});
227 });
228 });
229
230 // Save the state before suspending the event page, so we can resume it
231 // once new events arrive.
232 chrome.runtime.onSuspend.addListener(function() {
233 saveState();
234 });
235
236 chrome.fileSystemProvider.onUnmountRequested.addListener(
237 onUnmountRequested);
238 chrome.fileSystemProvider.onGetMetadataRequested.addListener(
239 onGetMetadataRequested);
240 chrome.fileSystemProvider.onReadDirectoryRequested.addListener(
241 onReadDirectoryRequested);
242 chrome.fileSystemProvider.onOpenFileRequested.addListener(
243 onOpenFileRequested);
244 chrome.fileSystemProvider.onCloseFileRequested.addListener(
245 onCloseFileRequested);
246 chrome.fileSystemProvider.onReadFileRequested.addListener(
247 onReadFileRequested);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698