Upstream version 9.37.195.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / chromeos / wallpaper_manager / js / event_page.js
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.
4
5 var WALLPAPER_PICKER_WIDTH = 574;
6 var WALLPAPER_PICKER_HEIGHT = 420;
7
8 var wallpaperPickerWindow;
9
10 var surpriseWallpaper = null;
11
12 function SurpriseWallpaper() {
13 }
14
15 /**
16  * Gets SurpriseWallpaper instance. In case it hasn't been initialized, a new
17  * instance is created.
18  * @return {SurpriseWallpaper} A SurpriseWallpaper instance.
19  */
20 SurpriseWallpaper.getInstance = function() {
21   if (!surpriseWallpaper)
22     surpriseWallpaper = new SurpriseWallpaper();
23   return surpriseWallpaper;
24 };
25
26 /**
27  * Tries to change wallpaper to a new one in the background. May fail due to a
28  * network issue.
29  */
30 SurpriseWallpaper.prototype.tryChangeWallpaper = function() {
31   var self = this;
32   var onFailure = function() {
33     self.retryLater_();
34     self.fallbackToLocalRss_();
35   };
36   // Try to fetch newest rss as document from server first. If any error occurs,
37   // proceed with local copy of rss.
38   WallpaperUtil.fetchURL(Constants.WallpaperRssURL, 'document', function(xhr) {
39     WallpaperUtil.saveToStorage(Constants.AccessRssKey,
40         new XMLSerializer().serializeToString(xhr.responseXML), false);
41     self.updateSurpriseWallpaper(xhr.responseXML);
42   }, onFailure);
43 };
44
45 /**
46  * Retries changing the wallpaper 1 hour later. This is called when fetching the
47  * rss or wallpaper from server fails.
48  * @private
49  */
50 SurpriseWallpaper.prototype.retryLater_ = function() {
51   chrome.alarms.create('RetryAlarm', {delayInMinutes: 60});
52 };
53
54 /**
55  * Fetches the cached rss feed from local storage in the event of being unable
56  * to download the online feed.
57  * @private
58  */
59 SurpriseWallpaper.prototype.fallbackToLocalRss_ = function() {
60   var self = this;
61   Constants.WallpaperLocalStorage.get(Constants.AccessRssKey, function(items) {
62     var rssString = items[Constants.AccessRssKey];
63     if (rssString) {
64       self.updateSurpriseWallpaper(new DOMParser().parseFromString(rssString,
65                                                                    'text/xml'));
66     } else {
67       self.updateSurpriseWallpaper();
68     }
69   });
70 };
71
72 /**
73  * Starts to change wallpaper. Called after rss is fetched.
74  * @param {Document=} opt_rss The fetched rss document. If opt_rss is null, uses
75  *     a random wallpaper.
76  */
77 SurpriseWallpaper.prototype.updateSurpriseWallpaper = function(opt_rss) {
78   if (opt_rss) {
79     var items = opt_rss.querySelectorAll('item');
80     var date = new Date(new Date().toDateString()).getTime();
81     for (var i = 0; i < items.length; i++) {
82       item = items[i];
83       var disableDate = new Date(item.getElementsByTagNameNS(
84           Constants.WallpaperNameSpaceURI, 'disableDate')[0].textContent).
85               getTime();
86       var enableDate = new Date(item.getElementsByTagNameNS(
87           Constants.WallpaperNameSpaceURI, 'enableDate')[0].textContent).
88               getTime();
89       var regionsString = item.getElementsByTagNameNS(
90           Constants.WallpaperNameSpaceURI, 'regions')[0].textContent;
91       var regions = regionsString.split(', ');
92       if (enableDate <= date && disableDate > date &&
93           regions.indexOf(navigator.language) != -1) {
94         var self = this;
95         this.setWallpaperFromRssItem_(item,
96                                       function() {},
97                                       function() {
98                                         self.retryLater_();
99                                         self.updateRandomWallpaper_();
100                                       });
101         return;
102       }
103     }
104   }
105   // No surprise wallpaper for today at current locale or fetching rss feed
106   // fails. Fallback to use a random one from wallpaper server.
107   this.updateRandomWallpaper_();
108 };
109
110 /**
111  * Sets a new random wallpaper if one has not already been set today.
112  * @private
113  */
114 SurpriseWallpaper.prototype.updateRandomWallpaper_ = function() {
115   var self = this;
116   Constants.WallpaperSyncStorage.get(
117       Constants.AccessLastSurpriseWallpaperChangedDate, function(items) {
118     var dateString = new Date().toDateString();
119     // At most one random wallpaper per day.
120     if (items[Constants.AccessLastSurpriseWallpaperChangedDate] != dateString) {
121       self.setRandomWallpaper_(dateString);
122     }
123   });
124 };
125
126 /**
127  * Sets wallpaper to one of the wallpapers displayed in wallpaper picker. If
128  * the wallpaper download fails, retry one hour later. Wallpapers that are
129  * disabled for surprise me are excluded.
130  * @param {string} dateString String representation of current local date.
131  * @private
132  */
133 SurpriseWallpaper.prototype.setRandomWallpaper_ = function(dateString) {
134   var self = this;
135   Constants.WallpaperLocalStorage.get(Constants.AccessManifestKey,
136                                       function(items) {
137     var manifest = items[Constants.AccessManifestKey];
138     if (manifest && manifest.wallpaper_list) {
139       var filtered = manifest.wallpaper_list.filter(function(element) {
140         // Older version manifest do not have available_for_surprise_me field.
141         // In this case, no wallpaper should be filtered out.
142         return element.available_for_surprise_me ||
143             element.available_for_surprise_me == undefined;
144       });
145       var index = Math.floor(Math.random() * filtered.length);
146       var wallpaper = filtered[index];
147       var wallpaperURL = wallpaper.base_url + Constants.HighResolutionSuffix;
148       var onSuccess = function() {
149         WallpaperUtil.saveToStorage(
150             Constants.AccessLastSurpriseWallpaperChangedDate,
151             dateString,
152             true);
153       }
154       WallpaperUtil.setOnlineWallpaper(wallpaperURL, wallpaper.default_layout,
155           onSuccess, self.retryLater_.bind(self));
156     }
157   });
158 };
159
160 /**
161  * Sets wallpaper to the wallpaper specified by item from rss. If downloading
162  * the wallpaper fails, retry one hour later.
163  * @param {Element} item The wallpaper rss item element.
164  * @param {function} onSuccess Success callback.
165  * @param {function} onFailure Failure callback.
166  * @private
167  */
168 SurpriseWallpaper.prototype.setWallpaperFromRssItem_ = function(item,
169                                                                 onSuccess,
170                                                                 onFailure) {
171   var url = item.querySelector('link').textContent;
172   var layout = item.getElementsByTagNameNS(
173         Constants.WallpaperNameSpaceURI, 'layout')[0].textContent;
174   var self = this;
175   WallpaperUtil.fetchURL(url, 'arraybuffer', function(xhr) {
176     if (xhr.response != null) {
177       chrome.wallpaperPrivate.setCustomWallpaper(xhr.response, layout, false,
178                                                  'surprise_wallpaper',
179                                                  onSuccess);
180     } else {
181       onFailure();
182     }
183   }, onFailure);
184 };
185
186 /**
187  * Disables the wallpaper surprise me feature. Clear all alarms and states.
188  */
189 SurpriseWallpaper.prototype.disable = function() {
190   chrome.alarms.clearAll();
191   // Makes last changed date invalid.
192   WallpaperUtil.saveToStorage(Constants.AccessLastSurpriseWallpaperChangedDate,
193                               '', true);
194 };
195
196 /**
197  * Changes current wallpaper and sets up an alarm to schedule next change around
198  * midnight.
199  */
200 SurpriseWallpaper.prototype.next = function() {
201   var nextUpdate = this.nextUpdateTime(new Date());
202   chrome.alarms.create({when: nextUpdate});
203   this.tryChangeWallpaper();
204 };
205
206 /**
207  * Calculates when the next wallpaper change should be triggered.
208  * @param {Date} now Current time.
209  * @return {number} The time when next wallpaper change should happen.
210  */
211 SurpriseWallpaper.prototype.nextUpdateTime = function(now) {
212   var nextUpdate = new Date(now.setDate(now.getDate() + 1)).toDateString();
213   return new Date(nextUpdate).getTime();
214 };
215
216 chrome.app.runtime.onLaunched.addListener(function() {
217   if (wallpaperPickerWindow && !wallpaperPickerWindow.contentWindow.closed) {
218     wallpaperPickerWindow.focus();
219     chrome.wallpaperPrivate.minimizeInactiveWindows();
220     return;
221   }
222
223   chrome.app.window.create('main.html', {
224     frame: 'none',
225     width: WALLPAPER_PICKER_WIDTH,
226     height: WALLPAPER_PICKER_HEIGHT,
227     resizable: false,
228     transparentBackground: true
229   }, function(w) {
230     wallpaperPickerWindow = w;
231     chrome.wallpaperPrivate.minimizeInactiveWindows();
232     w.onClosed.addListener(function() {
233       chrome.wallpaperPrivate.restoreMinimizedWindows();
234     });
235   });
236 });
237
238 chrome.storage.onChanged.addListener(function(changes, namespace) {
239   if (changes[Constants.AccessSurpriseMeEnabledKey]) {
240     if (changes[Constants.AccessSurpriseMeEnabledKey].newValue) {
241       SurpriseWallpaper.getInstance().next();
242     } else {
243       SurpriseWallpaper.getInstance().disable();
244     }
245   }
246
247   if (changes[Constants.AccessSyncWallpaperInfoKey]) {
248     var newValue = changes[Constants.AccessSyncWallpaperInfoKey].newValue;
249     Constants.WallpaperLocalStorage.get(Constants.AccessLocalWallpaperInfoKey,
250                                         function(items) {
251       // Normally, the wallpaper info saved in local storage and sync storage
252       // are the same. If the synced value changed by sync service, they may
253       // different. In that case, change wallpaper to the one saved in sync
254       // storage and update the local value.
255       var localValue = items[Constants.AccessLocalWallpaperInfoKey];
256       if (localValue == undefined ||
257           localValue.url != newValue.url ||
258           localValue.layout != newValue.layout ||
259           localValue.source != newValue.source) {
260         if (newValue.source == Constants.WallpaperSourceEnum.Online) {
261           // TODO(bshe): Consider schedule an alarm to set online wallpaper
262           // later when failed. Note that we need to cancel the retry if user
263           // set another wallpaper before retry alarm invoked.
264           WallpaperUtil.setOnlineWallpaper(newValue.url, newValue.layout,
265             function() {}, function() {});
266         }
267         WallpaperUtil.saveToStorage(Constants.AccessLocalWallpaperInfoKey,
268                                     newValue, false);
269       }
270     });
271   }
272 });
273