Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / wallpaper_manager / js / util.js
blobde8c5187886a5fd7e56ce86e4c502f26c39ce69a
1 // Copyright (c) 2013 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.
5 var WallpaperUtil = {
6   strings: null,  // Object that contains all the flags
7   syncFs: null,   // syncFileSystem handler
8   webkitFs: null  // webkitFileSystem handler
9 };
11 /**
12  * Deletes |wallpaperFileName| and its associated thumbnail from local FS.
13  * @param {string} wallpaperFilename Name of the file that will be deleted
14  */
15 WallpaperUtil.deleteWallpaperFromLocalFS = function(wallpaperFilename) {
16   WallpaperUtil.requestLocalFS(function(fs) {
17     var originalPath = Constants.WallpaperDirNameEnum.ORIGINAL + '/' +
18                        wallpaperFilename;
19     var thumbnailPath = Constants.WallpaperDirNameEnum.THUMBNAIL + '/' +
20                         wallpaperFilename;
21     fs.root.getFile(originalPath,
22                     {create: false},
23                     function(fe) {
24                       fe.remove(function() {}, null);
25                     },
26                     // NotFoundError is expected. After we receive a delete
27                     // event from either original wallpaper or wallpaper
28                     // thumbnail, we delete both of them in local FS to achieve
29                     // a faster synchronization. So each file is expected to be
30                     // deleted twice and the second attempt is a noop.
31                     function(e) {
32                       if (e.name != 'NotFoundError')
33                         WallpaperUtil.onFileSystemError(e);
34                     });
35     fs.root.getFile(thumbnailPath,
36                     {create: false},
37                     function(fe) {
38                       fe.remove(function() {}, null);
39                     },
40                     function(e) {
41                       if (e.name != 'NotFoundError')
42                         WallpaperUtil.onFileSystemError(e);
43                     });
44   });
47 /**
48  * Loads a wallpaper from sync file system and saves it and its thumbnail to
49  *     local file system.
50  * @param {string} wallpaperFileEntry File name of wallpaper image.
51  */
52 WallpaperUtil.storeWallpaperFromSyncFSToLocalFS = function(wallpaperFileEntry) {
53   var filenName = wallpaperFileEntry.name;
54   var storeDir = Constants.WallpaperDirNameEnum.ORIGINAL;
55   if (filenName.indexOf(Constants.CustomWallpaperThumbnailSuffix) != -1)
56     storeDir = Constants.WallpaperDirNameEnum.THUMBNAIL;
57   filenName = filenName.replace(Constants.CustomWallpaperThumbnailSuffix, '');
58   wallpaperFileEntry.file(function(file) {
59     var reader = new FileReader();
60     reader.onloadend = function() {
61       WallpaperUtil.storeWallpaperToLocalFS(filenName, reader.result, storeDir);
62     };
63     reader.readAsArrayBuffer(file);
64   }, WallpaperUtil.onFileSystemError);
67 /**
68  * Deletes |wallpaperFileName| and its associated thumbnail from syncFileSystem.
69  * @param {string} wallpaperFilename Name of the file that will be deleted.
70  */
71 WallpaperUtil.deleteWallpaperFromSyncFS = function(wallpaperFilename) {
72   var thumbnailFilename = wallpaperFilename +
73                           Constants.CustomWallpaperThumbnailSuffix;
74   var success = function(fs) {
75     fs.root.getFile(wallpaperFilename,
76                     {create: false},
77                     function(fe) {
78                       fe.remove(function() {}, null);
79                     },
80                     WallpaperUtil.onFileSystemError);
81     fs.root.getFile(thumbnailFilename,
82                     {create: false},
83                     function(fe) {
84                       fe.remove(function() {}, null);
85                     },
86                     WallpaperUtil.onFileSystemError);
87   };
88   WallpaperUtil.requestSyncFS(success);
91 /**
92  * Executes callback after requesting the sync settings.
93  * @param {function} callback The callback will be executed.
94  */
95 WallpaperUtil.enabledSyncThemesCallback = function(callback) {
96   chrome.wallpaperPrivate.getSyncSetting(function(setting) {
97     callback(setting.syncThemes);
98   });
102  * Request a syncFileSystem handle and run callback on it.
103  * @param {function} callback The callback to execute after syncFileSystem
104  *     handler is available.
105  */
106 WallpaperUtil.requestSyncFS = function(callback) {
107   WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) {
108     if (!syncEnabled)
109       return;
110     if (WallpaperUtil.syncFs) {
111       callback(WallpaperUtil.syncFs);
112     } else {
113       chrome.syncFileSystem.requestFileSystem(function(fs) {
114         WallpaperUtil.syncFs = fs;
115         callback(WallpaperUtil.syncFs);
116       });
117     }
118   });
122  * Request a Local Fs handle and run callback on it.
123  * @param {function} callback The callback to execute after Local handler is
124  *     available.
125  */
126 WallpaperUtil.requestLocalFS = function(callback) {
127   if (WallpaperUtil.webkitFs) {
128     callback(WallpaperUtil.webkitFs);
129   } else {
130     window.webkitRequestFileSystem(window.PERSISTENT, 1024 * 1024 * 100,
131                                    function(fs) {
132                                      WallpaperUtil.webkitFs = fs;
133                                      callback(fs);
134                                    });
135   }
139  * Print error to console.error.
140  * @param {Event} e The error will be printed to console.error.
141  */
142 // TODO(ranj): Handle different errors differently.
143 WallpaperUtil.onFileSystemError = function(e) {
144   console.error(e);
148  * Write jpeg/png file data into file entry.
149  * @param {FileEntry} fileEntry The file entry that going to be writen.
150  * @param {ArrayBuffer} wallpaperData Data for image file.
151  * @param {function=} writeCallback The callback that will be executed after
152  *     writing data.
153  */
154 WallpaperUtil.writeFile = function(fileEntry, wallpaperData, writeCallback) {
155   fileEntry.createWriter(function(fileWriter) {
156     var blob = new Blob([new Int8Array(wallpaperData)]);
157     fileWriter.write(blob);
158     if (writeCallback)
159       writeCallback();
160   }, WallpaperUtil.onFileSystemError);
164  * Write jpeg/png file data into syncFileSystem.
165  * @param {string} wallpaperFilename The filename that going to be writen.
166  * @param {ArrayBuffer} wallpaperData Data for image file.
167  */
168 WallpaperUtil.storeWallpaperToSyncFS = function(wallpaperFilename,
169                                                 wallpaperData) {
170   var callback = function(fs) {
171     fs.root.getFile(wallpaperFilename,
172                     {create: false},
173                     function() {},  // already exists
174                     function(e) {  // not exists, create
175                       fs.root.getFile(wallpaperFilename, {create: true},
176                                       function(fe) {
177                                         WallpaperUtil.writeFile(
178                                             fe, wallpaperData);
179                                       },
180                                       WallpaperUtil.onFileSystemError);
181                     });
182   };
183   WallpaperUtil.requestSyncFS(callback);
187  * Stores jpeg/png wallpaper into |localDir| in local file system.
188  * @param {string} wallpaperFilename File name of wallpaper image.
189  * @param {ArrayBuffer} wallpaperData The wallpaper data.
190  * @param {string} saveDir The path to store wallpaper in local file system.
191  */
192 WallpaperUtil.storeWallpaperToLocalFS = function(wallpaperFilename,
193     wallpaperData, saveDir) {
194   if (!wallpaperData) {
195     console.error('wallpaperData is null');
196     return;
197   }
198   var getDirSuccess = function(dirEntry) {
199     dirEntry.getFile(wallpaperFilename,
200                     {create: false},
201                     function() {},  // already exists
202                     function(e) {   // not exists, create
203                     dirEntry.getFile(wallpaperFilename, {create: true},
204                                      function(fe) {
205                                        WallpaperUtil.writeFile(fe,
206                                                                wallpaperData);
207                                      },
208                                      WallpaperUtil.onFileSystemError);
209                     });
210   };
211   WallpaperUtil.requestLocalFS(function(fs) {
212     fs.root.getDirectory(saveDir, {create: true}, getDirSuccess,
213                          WallpaperUtil.onFileSystemError);
214   });
218  * Sets wallpaper from synced file system.
219  * @param {string} wallpaperFilename File name used to set wallpaper.
220  * @param {string} wallpaperLayout Layout used to set wallpaper.
221  * @param {function=} onSuccess Callback if set successfully.
222  */
223 WallpaperUtil.setCustomWallpaperFromSyncFS = function(
224     wallpaperFilename, wallpaperLayout, onSuccess) {
225   var setWallpaperFromSyncCallback = function(fs) {
226     if (!wallpaperFilename) {
227       console.error('wallpaperFilename is not provided.');
228       return;
229     }
230     if (!wallpaperLayout)
231       wallpaperLayout = 'CENTER_CROPPED';
232     fs.root.getFile(wallpaperFilename, {create: false}, function(fileEntry) {
233       fileEntry.file(function(file) {
234         var reader = new FileReader();
235         reader.onloadend = function() {
236           chrome.wallpaperPrivate.setCustomWallpaper(
237               reader.result,
238               wallpaperLayout,
239               true,
240               wallpaperFilename,
241               function(thumbnailData) {
242                 // TODO(ranj): Ignore 'canceledWallpaper' error.
243                 if (chrome.runtime.lastError) {
244                   console.error(chrome.runtime.lastError.message);
245                   return;
246                 }
247                 WallpaperUtil.storeWallpaperToLocalFS(wallpaperFilename,
248                     reader.result, Constants.WallpaperDirNameEnum.ORIGINAL);
249                 WallpaperUtil.storeWallpaperToLocalFS(wallpaperFilename,
250                     reader.result, Constants.WallpaperDirNameEnum.THUMBNAIL);
251                 if (onSuccess)
252                   onSuccess();
253               });
254         };
255         reader.readAsArrayBuffer(file);
256       }, WallpaperUtil.onFileSystemError);
257     }, function(e) {}  // fail to read file, expected due to download delay
258     );
259   };
260   WallpaperUtil.requestSyncFS(setWallpaperFromSyncCallback);
264  * Saves value to local storage that associates with key.
265  * @param {string} key The key that associates with value.
266  * @param {string} value The value to save to local storage.
267  * @param {function=} opt_callback The callback on success.
268  */
269 WallpaperUtil.saveToLocalStorage = function(key, value, opt_callback) {
270   var items = {};
271   items[key] = value;
272   Constants.WallpaperLocalStorage.set(items, opt_callback);
276  * Saves value to sync storage that associates with key if sync theme is
277  * enabled.
278  * @param {string} key The key that associates with value.
279  * @param {string} value The value to save to sync storage.
280  * @param {function=} opt_callback The callback on success.
281  */
282 WallpaperUtil.saveToSyncStorage = function(key, value, opt_callback) {
283   var items = {};
284   items[key] = value;
285   WallpaperUtil.enabledSyncThemesCallback(function(syncEnabled) {
286     if (syncEnabled)
287       Constants.WallpaperSyncStorage.set(items, opt_callback);
288   });
292  * Saves user's wallpaper infomation to local and sync storage. Note that local
293  * value should be saved first.
294  * @param {string} url The url address of wallpaper. For custom wallpaper, it is
295  *     the file name.
296  * @param {string} layout The wallpaper layout.
297  * @param {string} source The wallpaper source.
298  */
299 WallpaperUtil.saveWallpaperInfo = function(url, layout, source) {
300   var wallpaperInfo = {
301       url: url,
302       layout: layout,
303       source: source
304   };
305   WallpaperUtil.saveToLocalStorage(Constants.AccessLocalWallpaperInfoKey,
306                               wallpaperInfo, function() {
307     WallpaperUtil.saveToSyncStorage(Constants.AccessSyncWallpaperInfoKey,
308                                 wallpaperInfo);
309   });
313  * Downloads resources from url. Calls onSuccess and opt_onFailure accordingly.
314  * @param {string} url The url address where we should fetch resources.
315  * @param {string} type The response type of XMLHttprequest.
316  * @param {function} onSuccess The success callback. It must be called with
317  *     current XMLHttprequest object.
318  * @param {function} onFailure The failure callback.
319  * @param {XMLHttpRequest=} opt_xhr The XMLHttpRequest object.
320  */
321 WallpaperUtil.fetchURL = function(url, type, onSuccess, onFailure, opt_xhr) {
322   var xhr;
323   if (opt_xhr)
324     xhr = opt_xhr;
325   else
326     xhr = new XMLHttpRequest();
328   try {
329     // Do not use loadend here to handle both success and failure case. It gets
330     // complicated with abortion. Unexpected error message may show up. See
331     // http://crbug.com/242581.
332     xhr.addEventListener('load', function(e) {
333       if (this.status == 200) {
334         onSuccess(this);
335       } else {
336         onFailure(this.status);
337       }
338     });
339     xhr.addEventListener('error', onFailure);
340     xhr.open('GET', url, true);
341     xhr.responseType = type;
342     xhr.send(null);
343   } catch (e) {
344     onFailure();
345   }
349  * Sets wallpaper to online wallpaper specified by url and layout
350  * @param {string} url The url address where we should fetch resources.
351  * @param {string} layout The layout of online wallpaper.
352  * @param {function} onSuccess The success callback.
353  * @param {function} onFailure The failure callback.
354  */
355 WallpaperUtil.setOnlineWallpaper = function(url, layout, onSuccess, onFailure) {
356   var self = this;
357   chrome.wallpaperPrivate.setWallpaperIfExists(url, layout, function(exists) {
358     if (exists) {
359       onSuccess();
360       return;
361     }
363     self.fetchURL(url, 'arraybuffer', function(xhr) {
364       if (xhr.response != null) {
365         chrome.wallpaperPrivate.setWallpaper(xhr.response, layout, url,
366                                              onSuccess);
367         self.saveWallpaperInfo(url, layout,
368                                Constants.WallpaperSourceEnum.Online);
369       } else {
370         onFailure();
371       }
372     }, onFailure);
373   });
377  * Runs chrome.test.sendMessage in test environment. Does nothing if running
378  * in production environment.
380  * @param {string} message Test message to send.
381  */
382 WallpaperUtil.testSendMessage = function(message) {
383   var test = chrome.test || window.top.chrome.test;
384   if (test)
385     test.sendMessage(message);