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

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: 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 // For file examples with metadata inside, see example1.fake and example2.fake.
mtomasz 2014/06/30 08:30:30 ... -> Metadata is stored in files as serialized t
cmihail 2014/07/01 00:07:05 Done.
8
9 // Multiple volumes can be opened at the same time. The key is the
10 // fileSystemId, which is the same as the file entry.name. The value
mtomasz 2014/06/30 08:30:31 file -> file's
cmihail 2014/07/01 00:07:05 Done.
11 // is a Volume object.
12 var volumes = {};
13
14 // Defines a volume object that contains information about mounted devices.
15 // openedFiles parameter is optional and can be undefined.
16 function Volume(entry, mount, metadata, openedFiles) {
mtomasz 2014/06/30 08:30:31 openedFiles -> opt_openedFiles
cmihail 2014/07/01 00:07:05 Done.
17 // Used for restoring file entry.
mtomasz 2014/06/30 08:30:30 ... -> Used for restoring the opened file entry af
cmihail 2014/07/01 00:07:05 Done.
18 this.entry_ = entry;
19
20 // The volume metadata.
mtomasz 2014/06/30 08:30:31 Let's add a comment: Date object is serialized in
cmihail 2014/07/01 00:07:05 Done.
21 for (var item in metadata) {
mtomasz 2014/06/30 08:30:31 I think it is better not to modify input arguments
cmihail 2014/07/01 00:07:05 Done.
22 metadata[item].modificationTime =
23 new Date(metadata[item].modificationTime);
24 }
25 this.metadata_ = metadata;
26
27 // A map with currently opened files. As key it has requestId of
28 // openFileRequested and as a value the file path.
29 this.openedFiles_ = openedFiles ? openedFiles : {};
30
31 // Mount device and save device information on local storage in order to be
mtomasz 2014/06/30 08:30:31 Mount device -> Mount the volume and save its info
cmihail 2014/07/01 00:07:05 Done.
32 // able to recover metadata in case of restarts, system crashes, etc.
33 if (mount) {
34 chrome.fileSystemProvider.mount(
35 {fileSystemId: entry.name, displayName: entry.name},
36 function() { saveState(); },
37 function() { console.error('Failed to mount.'); });
38
39 }
40 };
41
42 function onUnmountRequested(options, onSuccess, onError) {
43 if (Object.keys(volumes[options.fileSystemId].openedFiles_).length != 0) {
44 onError('IN_USE');
45 return;
46 }
47
48 chrome.fileSystemProvider.unmount(
49 {fileSystemId: options.fileSystemId},
50 function() {
51 delete volumes[options.fileSystemId];
52 saveState(); // Remove volume from local storage state.
53 onSuccess();
54 },
55 function() {
56 onError('FAILED');
57 });
58 };
59
60 function onGetMetadataRequested(options, onSuccess, onError) {
61 restoreState(options.fileSystemId, function () {
62 var entryMetadata =
63 volumes[options.fileSystemId].metadata_[options.entryPath];
64 if (!entryMetadata)
65 error('NOT_FOUND');
66 else
67 onSuccess(entryMetadata);
68 }, onError);
69 };
70
71 function onReadDirectoryRequested(options, onSuccess, onError) {
72 restoreState(options.fileSystemId, function () {
73 var directoryMetadata =
74 volumes[options.fileSystemId].metadata_[options.directoryPath];
75 if (!directoryMetadata) {
76 onError('NOT_FOUND');
77 return;
78 }
79 if (!directoryMetadata.isDirectory) {
80 onError('NOT_A_DIRECTORY');
81 return;
82 }
83
84 // Retrieve directory contents from metadata.
85 var entries = [];
86 for (var entry in volumes[options.fileSystemId].metadata_) {
87 // Do not add itself on the list.
88 if (entry == options.directoryPath)
89 continue;
90 // Check if the entry is a child of the requested directory.
91 if (entry.indexOf(options.directoryPath) != 0)
92 continue;
93 // Restrict to direct children only.
94 if (entry.substring(options.directoryPath.length + 1).indexOf('/') != -1)
95 continue;
96
97 entries.push(volumes[options.fileSystemId].metadata_[entry]);
98 }
99 onSuccess(entries, false /* Last call. */);
100 }, onError);
101 };
102
103 function onOpenFileRequested(options, onSuccess, onError) {
104 restoreState(options.fileSystemId, function () {
105 if (options.mode != 'READ' || options.create) {
106 onError('INVALID_OPERATION');
107 } else {
108 volumes[options.fileSystemId].openedFiles_[options.requestId] =
109 options.filePath;
110 onSuccess();
111 }
112 }, onError);
113 };
114
115 function onCloseFileRequested(options, onSuccess, onError) {
116 restoreState(options.fileSystemId, function () {
117 if (!volumes[options.fileSystemId].openedFiles_[options.openRequestId]) {
118 onError('INVALID_OPERATION');
119 } else {
120 delete volumes[options.fileSystemId].openedFiles_[options.openRequestId];
121 onSuccess();
122 }
123 }, onError);
124 };
125
126 function onReadFileRequested(options, onSuccess, onError) {
127 restoreState(options.fileSystemId, function () {
128 var filePath =
129 volumes[options.fileSystemId].openedFiles_[options.openRequestId];
130 if (!filePath) {
131 onError('INVALID_OPERATION');
132 return;
133 }
134
135 var contents = volumes[options.fileSystemId].metadata_[filePath].contents;
mtomasz 2014/06/30 08:30:31 nit: metadata_ is private here. Let's make it publ
cmihail 2014/07/01 00:07:05 Done. Also modified the other variables.
136
137 // Write the contents as ASCII text.
138 var buffer = new ArrayBuffer(options.length);
139 var bufferView = new Uint8Array(buffer);
140 for (var i = 0; i < options.length; i++) {
141 bufferView[i] = contents.charCodeAt(i);
142 }
143
144 onSuccess(buffer, false /* Last call. */);
145 }, onError);
146 };
147
148 // Save state in case of restart, extension suspend, crashes, etc.
mtomasz 2014/06/30 08:30:30 nit: restart -> restarts nit: extension suspend ->
cmihail 2014/07/01 00:07:05 Done.
149 function saveState() {
150 var state = {};
151 for (var volumeId in volumes) {
152 var entryId = chrome.fileSystem.retainEntry(volumes[volumeId].entry_);
cmihail 2014/06/30 08:01:44 As a mention: retainEntry executes quite often. I
mtomasz 2014/06/30 13:35:32 That's a good point. I took a look at the C++ code
153 state[volumeId] = {
154 entryId: entryId,
155 openedFiles: volumes[volumeId].openedFiles_
156 };
157 }
158 chrome.storage.local.set({state: state});
159 }
160
161 // Restore state. In this case the file system is already mounted and
162 // we only need to obtain the metadata, which is done lazily.
163 function restoreState(fileSystemId, onSuccess, onError) {
164 chrome.storage.local.get(['state'], function(result) {
165 // Check if metadata for the given file system is alread in memory.
166 if (volumes[fileSystemId]) {
167 onSuccess();
168 return;
169 }
170
171 chrome.fileSystem.restoreEntry(
172 result.state[fileSystemId].entryId,
173 function(entry) {
174 readMetadataFromFile(entry, false /* File system is mounted. */,
175 onSuccess, onError, result.state[fileSystemId].openedFiles);
176 });
177 });
178 }
179
180 // openedFiles is an optional parameter.
181 function readMetadataFromFile(entry, mount, onSuccess, onError, openedFiles) {
mtomasz 2014/06/30 08:30:30 readMetadataFromFile shouldn't need |openedFiles|.
cmihail 2014/07/01 00:07:05 Done.
182 entry.file(function(file) {
183 var fileReader = new FileReader();
184 fileReader.onload = function(event) {
185 var metadata = JSON.parse(event.target.result);
186 volumes[entry.name] = new Volume(entry, mount, metadata, openedFiles);
187 onSuccess();
188 };
189
190 fileReader.onerror = function(event) {
191 onError('FAILED');
192 };
193
194 fileReader.readAsText(file);
195 });
196 }
197
198 // Event called on clicking the file with the extension mentioned
199 // in the manifest file.
mtomasz 2014/06/30 08:30:30 Not only file extension, but also if mime type is
cmihail 2014/07/01 00:07:06 Done.
200 chrome.app.runtime.onLaunched.addListener(function(event) {
201 event.items.forEach(function(item) {
202 readMetadataFromFile(item.entry, true /* Mount file system. */,
203 function() {},
204 function(error) { console.error(error); } );
205 });
206 });
207
208 // Event called on chromeos startup.
mtomasz 2014/06/30 08:30:31 ... -> Event called on a profile startup.
cmihail 2014/07/01 00:07:05 Done.
209 chrome.runtime.onStartup.addListener(function () {
210 chrome.storage.local.get(['state'], function(result) {
211 // Nothing to change.
212 if (!result.state)
213 return;
214
215 // Remove opened files from state. The file entry restore
mtomasz 2014/06/30 08:30:31 I think we could clarify it a little bit, eg.: ...
cmihail 2014/07/01 00:07:05 Done. I added local storage state. It seems a bit
216 // will be done by the restoreState function.
217 for (var volumeId in result.state) {
218 result.state[volumeId].openedFiles = {};
219 }
220 chrome.storage.local.set({state: result.state});
221 });
222 });
223
224 // Event called when the extension is idle for about 10+ seconds and it will
mtomasz 2014/06/30 08:30:31 I think we can remove this comment. The idling per
cmihail 2014/07/01 00:07:05 That sounds good to me.
225 // get killed to free resources. The extension state should be saved.
226 chrome.runtime.onSuspend.addListener(function() {
227 saveState();
228 });
229
230 chrome.fileSystemProvider.onUnmountRequested.addListener(
231 onUnmountRequested);
232 chrome.fileSystemProvider.onGetMetadataRequested.addListener(
233 onGetMetadataRequested);
234 chrome.fileSystemProvider.onReadDirectoryRequested.addListener(
235 onReadDirectoryRequested);
236 chrome.fileSystemProvider.onOpenFileRequested.addListener(
237 onOpenFileRequested);
238 chrome.fileSystemProvider.onCloseFileRequested.addListener(
239 onCloseFileRequested);
240 chrome.fileSystemProvider.onReadFileRequested.addListener(
241 onReadFileRequested);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698