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

Side by Side Diff: chrome/browser/resources/file_manager/js/metadata/metadata_provider.js

Issue 9664045: [File Manager] Use content url for playing media files from a gdata directory (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments Created 8 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * A base class for metadata providers. Implementing in-memory caching. 6 * A base class for metadata provider. Implementing in-memory caching.
7 */ 7 */
8 function MetadataCache() { 8 function MetadataCache() {
9 this.cache_ = {}; 9 this.cache_ = {};
10 } 10 }
11 11
12 MetadataCache.prototype.isSupported = function(url) {
13 return true;
14 };
15
16 MetadataCache.prototype.doFetch = function(url) { 12 MetadataCache.prototype.doFetch = function(url) {
17 throw new Error('MetadataCache.doFetch not implemented'); 13 throw new Error('MetadataCache.doFetch not implemented');
18 }; 14 };
19 15
20 MetadataCache.prototype.fetch = function(url, callback) { 16 MetadataCache.prototype.fetch = function(url, callback) {
21 var cacheValue = this.cache_[url]; 17 var cacheValue = this.cache_[url];
22 18
23 if (!cacheValue) { 19 if (!cacheValue) {
24 // This is the first time anyone's asked, go get it. 20 // This is the first time anyone has asked, go get it.
25 if (this.isSupported(url)) { 21 this.cache_[url] = [callback];
26 this.cache_[url] = [callback]; 22 if (!this.doFetch(url)) {
27 this.doFetch(url);
28 } else {
29 // Fetch failed, return an empty map, no caching needed. 23 // Fetch failed, return an empty map, no caching needed.
24 delete this.cache_[url];
30 setTimeout(callback, 0, {}); 25 setTimeout(callback, 0, {});
31 } 26 }
32 return; 27 return;
33 } 28 }
34 29
35 if (cacheValue instanceof Array) { 30 if (cacheValue instanceof Array) {
36 // Something is already pending, add to the list of observers. 31 // Something is already pending, add to the list of observers.
37 cacheValue.push(callback); 32 cacheValue.push(callback);
38 return; 33 return;
39 } 34 }
40 35
41 if (cacheValue instanceof Object) { 36 if (cacheValue instanceof Object) {
42 // We already know the answer, let the caller know in a fresh call stack. 37 // We already know the answer, let the caller know in a fresh call stack.
43 setTimeout(function() { callback(cacheValue) }, 0); 38 setTimeout(callback, 0, cacheValue);
44 return; 39 return;
45 } 40 }
46 41
47 console.error('Unexpected metadata cache value:', cacheValue); 42 console.error('Unexpected metadata cache value:', cacheValue);
48 }; 43 };
49 44
50 MetadataCache.prototype.processResult = function(url, result) { 45 MetadataCache.prototype.processResult = function(url, result) {
51 console.log('metadata result:', result); 46 console.log('metadata result:', result);
52 47
53 var observers = this.cache_[url]; 48 var observers = this.cache_[url];
(...skipping 14 matching lines...) Expand all
68 MetadataCache.prototype.reset = function(url) { 63 MetadataCache.prototype.reset = function(url) {
69 if (this.cache_[url] instanceof Array) { 64 if (this.cache_[url] instanceof Array) {
70 console.error( 65 console.error(
71 'Abandoned ' + this.cache_[url].length + ' metadata subscribers', 66 'Abandoned ' + this.cache_[url].length + ' metadata subscribers',
72 url); 67 url);
73 } 68 }
74 delete this.cache_[url]; 69 delete this.cache_[url];
75 }; 70 };
76 71
77 /** 72 /**
78 * Create metadata provider for local files. 73 * Base class for metadata fetchers.
74 *
75 * @param {function(string, Object)} resultCallback
76 * @param {string} urlPrefix.
79 */ 77 */
80 function MetadataProvider() { 78 function MetadataFetcher(resultCallback, urlPrefix) {
81 MetadataCache.call(this); 79 this.resultCallback_ = resultCallback;
80 this.urlPrefix_ = urlPrefix;
81 }
82
83 MetadataFetcher.prototype.processResult = function(url, metadata) {
84 this.resultCallback_(url, metadata);
85 };
86
87 MetadataFetcher.prototype.isInitialized = function() {
88 return true;
89 };
90
91 MetadataFetcher.prototype.supports = function(url) {
92 return url.indexOf(this.urlPrefix_) == 0;
93 };
94
95 MetadataFetcher.prototype.doFetch = function(url) {
96 console.error('MetadataFetcher.doFetch not implemented');
97 };
98
99 /**
100 * Create metadata cache for local files.
101 */
102 function LocalMetadataFetcher(resultCallback, rootUrl) {
103 MetadataFetcher.apply(this, arguments);
82 104
83 // Pass all URLs to the metadata reader until we have a correct filter. 105 // Pass all URLs to the metadata reader until we have a correct filter.
84 this.urlFilter = /.*/; 106 this.urlFilter = /.*/;
85 107
86 var path = document.location.pathname; 108 var path = document.location.pathname;
87 var workerPath = document.location.origin + 109 var workerPath = document.location.origin +
88 path.substring(0, path.lastIndexOf('/') + 1) + 110 path.substring(0, path.lastIndexOf('/') + 1) +
89 'js/metadata/metadata_dispatcher.js'; 111 'js/metadata/metadata_dispatcher.js';
90 112
91 this.dispatcher_ = new Worker(workerPath); 113 this.dispatcher_ = new Worker(workerPath);
92 this.dispatcher_.onmessage = this.onMessage_.bind(this); 114 this.dispatcher_.onmessage = this.onMessage_.bind(this);
93 this.dispatcher_.postMessage({verb: 'init'}); 115 this.dispatcher_.postMessage({verb: 'init'});
94 // Initialization is not complete until the Worker sends back the 116 // Initialization is not complete until the Worker sends back the
95 // 'initialized' message. See below. 117 // 'initialized' message. See below.
118 this.initialized_ = false;
96 } 119 }
97 120
98 MetadataProvider.prototype = { __proto__: MetadataCache.prototype }; 121 LocalMetadataFetcher.prototype = { __proto__: MetadataFetcher.prototype };
99 122
100 MetadataProvider.prototype.isSupported = function(url) { 123 LocalMetadataFetcher.prototype.supports = function(url) {
101 return url.match(this.urlFilter); 124 return MetadataFetcher.prototype.supports.apply(this, arguments) &&
125 url.match(this.urlFilter);
102 }; 126 };
103 127
104 MetadataProvider.prototype.doFetch = function(url) { 128 LocalMetadataFetcher.prototype.doFetch = function(url) {
105 this.dispatcher_.postMessage({verb: 'request', arguments: [url]}); 129 this.dispatcher_.postMessage({verb: 'request', arguments: [url]});
106 }; 130 };
107 131
132 LocalMetadataFetcher.prototype.isInitialized = function() {
133 return this.initialized_;
134 };
135
108 /** 136 /**
109 * Dispatch a message from a metadata reader to the appropriate on* method. 137 * Dispatch a message from a metadata reader to the appropriate on* method.
110 */ 138 */
111 MetadataProvider.prototype.onMessage_ = function(event) { 139 LocalMetadataFetcher.prototype.onMessage_ = function(event) {
112 var data = event.data; 140 var data = event.data;
113 141
114 var methodName = 142 var methodName =
115 'on' + data.verb.substr(0, 1).toUpperCase() + data.verb.substr(1) + '_'; 143 'on' + data.verb.substr(0, 1).toUpperCase() + data.verb.substr(1) + '_';
116 144
117 if (!(methodName in this)) { 145 if (!(methodName in this)) {
118 console.log('Unknown message from metadata reader: ' + data.verb, data); 146 console.log('Unknown message from metadata reader: ' + data.verb, data);
119 return; 147 return;
120 } 148 }
121 149
122 this[methodName].apply(this, data.arguments); 150 this[methodName].apply(this, data.arguments);
123 }; 151 };
124 152
125 /** 153 /**
126 * Handles the 'initialized' message from the metadata reader Worker. 154 * Handles the 'initialized' message from the metadata reader Worker.
127 */ 155 */
128 MetadataProvider.prototype.onInitialized_ = function(regexp) { 156 LocalMetadataFetcher.prototype.onInitialized_ = function(regexp) {
129 this.urlFilter = regexp; 157 this.urlFilter = regexp;
158
159 // Tests can monitor for this state with
160 // ExtensionTestMessageListener listener("worker-initialized");
161 // ASSERT_TRUE(listener.WaitUntilSatisfied());
162 // Automated tests need to wait for this, otherwise we crash in
163 // browser_test cleanup because the worker process still has
164 // URL requests in-flight.
165 chrome.test.sendMessage('worker-initialized');
166 this.initialized_ = true;
130 }; 167 };
131 168
132 MetadataProvider.prototype.onResult_ = function(url, metadata) { 169 LocalMetadataFetcher.prototype.onResult_ = function(url, metadata) {
133 this.processResult(url, metadata); 170 this.processResult(url, metadata);
134 }; 171 };
135 172
136 MetadataProvider.prototype.onError_ = function(url, step, error, metadata) { 173 LocalMetadataFetcher.prototype.onError_ = function(url, step, error, metadata) {
137 console.warn('metadata: ' + url + ': ' + step + ': ' + error); 174 console.warn('metadata: ' + url + ': ' + step + ': ' + error);
138 this.processResult(url, metadata || {}); 175 this.processResult(url, metadata || {});
139 }; 176 };
140 177
141 MetadataProvider.prototype.onLog_ = function(arglist) { 178 LocalMetadataFetcher.prototype.onLog_ = function(arglist) {
142 console.log.apply(console, ['metadata:'].concat(arglist)); 179 console.log.apply(console, ['metadata:'].concat(arglist));
143 }; 180 };
144 181
145 /** 182 /**
146 * Create a metadata provider for GData files. 183 * Create a metadata fetcher for GData files.
147 * 184 *
148 * Instead of reading the file contents it gets the metadata from GData API. 185 * Instead of reading the file contents it gets the metadata from GData API.
149 */ 186 */
150 function GDataMetadataProvider() { 187 function GDataMetadataFetcher(resultCallback, rootUrl) {
151 MetadataCache.call(this); 188 MetadataFetcher.apply(this, arguments);
152 } 189 }
153 190
154 GDataMetadataProvider.prototype = { __proto__: MetadataCache.prototype }; 191 GDataMetadataFetcher.prototype = { __proto__: MetadataFetcher.prototype };
155 192
156 GDataMetadataProvider.prototype.doFetch = function(url) { 193 GDataMetadataFetcher.prototype.doFetch = function(url) {
157 function convertMetadata(result) { 194 function convertMetadata(result) {
158 return { 195 return {
159 thumbnailURL: result.thumbnailUrl, 196 thumbnailURL: result.thumbnailUrl,
160 thumbnailOnly: true, // Temporary, unless we learn to fetch the content. 197 contentURL: (result.contentUrl || '').replace(/\?.*$/gi, ''),
161 fileSize: 0 // TODO(kaznacheev) Get the correct size from File API. 198 fileSize: 0 // TODO(kaznacheev) Get the correct size from File API.
162 } 199 }
163 } 200 }
164 201
165 chrome.fileBrowserPrivate.getGDataFileProperties([url], 202 chrome.fileBrowserPrivate.getGDataFileProperties([url],
166 function(results) { 203 function(results) {
167 this.processResult(url, convertMetadata(results[0])); 204 this.processResult(url, convertMetadata(results[0]));
168 }.bind(this)); 205 }.bind(this));
169 }; 206 };
207
208 /**
209 * Create universal metadata provider.
210 *
211 * @param {string} rootUrl The file system root url.
212 * @constructor
213 */
214 function MetadataProvider(rootUrl) {
215 MetadataCache.call(this);
216
217 var resultCallback = this.processResult.bind(this);
218
219 // TODO(kaznacheev): We use 'gdata' literal here because
220 // DirectoryModel.GDATA_DIRECTORY definition might be not available.
221 // Consider extracting this definition into some common js file.
222 this.fetchers_ = [
223 new GDataMetadataFetcher(resultCallback, rootUrl + 'gdata' + '/'),
224 new LocalMetadataFetcher(resultCallback, rootUrl)
225 ];
226 }
227
228 MetadataProvider.prototype = { __proto__: MetadataCache.prototype };
229
230 MetadataProvider.prototype.isInitialized = function() {
231 for (var i = 0; i != this.fetchers_.length; i++) {
232 if (!this.fetchers_[i].isInitialized())
233 return false;
234 }
235 return true;
236 };
237
238 MetadataProvider.prototype.doFetch = function(url) {
239 for (var i = 0; i != this.fetchers_.length; i++) {
240 var fetcher = this.fetchers_[i];
241 if (fetcher.supports(url)) {
242 fetcher.doFetch(url);
243 return true;
244 }
245 }
246 return false;
247 };
OLDNEW
« no previous file with comments | « chrome/browser/resources/file_manager/js/media/audio_player.js ('k') | chrome/browser/resources/file_manager/manifest.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698