Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / login / wallpaper_loader.js
blob4903bf5b0e31e81e85247af57d8083838f2b6267
1 // Copyright 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 cr.define('login', function() {
7   /**
8    * Minimum wallpaper load delay in milliseconds.
9    * @type {number}
10    * @const
11    */
12   var WALLPAPER_LOAD_MIN_DELAY_MS = 100;
14   /**
15    * If last walpaper load time cannot be calculated, assume this value.
16    * @type {number}
17    * @const
18    */
19   var WALLPAPER_DEFAULT_LOAD_TIME_MS = 200;
21   /**
22    * Min and Max average wallpaper load time.
23    * Delay to next wallpaper load is 2 * <average load time>.
24    * @type {number}
25    * @const
26    */
27   var WALLPAPER_MIN_LOAD_TIME_MS = 50;
28   var WALLPAPER_MAX_LOAD_TIME_MS = 2000;
30   /**
31    * Number last wallpaper load times to remember.
32    * @type {number}
33    * @const
34    */
35   var WALLPAPER_LOAD_STATS_MAX_LENGTH = 4;
38   /**
39    * Creates a new pod row element.
40    * @constructor
41    * @extends {HTMLDivElement}
42    */
43   var WallpaperLoader = function() {
44     this.wallpaperLoadInProgress_ = {
45         name: '',
46         date: undefined
47     };
48     this.loadStats_ = [];
49   };
51   WallpaperLoader.prototype = {
52     // When moving through users quickly at login screen, set a timeout to
53     // prevent loading intermediate wallpapers.
54     beforeLoadTimeout_: null,
56     // If we do not receive notification on WallpaperLoaded within timeout,
57     // probably an error happened and the wallpaper is just bad. Skip it
58     // and unblock loader.
59     loadTimeout_: null,
61     // When waiting for wallpaper load, remember load start time.
62     // wallpaperLoadInProgress_: { name: '', date: undefined }
63     wallpaperLoadInProgress_: undefined,
65     // Wait a delay and then load this wallpaper. Value = username.
66     wallpaperLoadPending_: undefined,
68     // Wait untill this Date before loading next wallpaper.
69     wallpaperLoadTryNextAfter_: undefined,
71     // Username, owner of current wallpaper.
72     currentWallpaper_: '',
74     // Array of times (in milliseconds) of last wallpaper load attempts.
75     // Length is limited by WALLPAPER_LOAD_STATS_MAX_LENGTH.
76     loadStats_: undefined,
78     // Force next load request even if requested wallpaper is already loaded.
79     forceLoad_: false,
81     /**
82      * Stop load timer. Clear pending record.
83      */
84     reset: function() {
85       delete this.wallpaperLoadPending_;
87       if (this.beforeLoadTimeout_ != null)
88         window.clearTimeout(this.beforeLoadTimeout_);
89       this.beforeLoadTimeout_ = null;
91       if (this.loadTimeout_ != null)
92         window.clearTimeout(this.loadTimeout_);
93       this.loadTimeout_ = null;
95       this.wallpaperLoadInProgress_.name = '';
96     },
98     /**
99      * Schedules wallpaper load.
100      */
101     scheduleLoad: function(email, force) {
102       if (force || this.forceLoad_) {
103         this.forceLoad_ = true;
104       } else {
105         if (this.wallpaperLoadPending_ && this.wallpaperLoadPending_ == email)
106           return;
107         if ((this.wallpaperLoadInProgress_.name == '') &&
108             (this.currentWallpaper_ == email))
109           return;
110       }
111       this.reset();
113       this.wallpaperLoadPending_ = email;
114       var now = new Date();
115       var timeout = WALLPAPER_LOAD_MIN_DELAY_MS;
116       if (this.wallpaperLoadTryNextAfter_)
117         timeout = Math.max(timeout, this.wallpaperLoadTryNextAfter_ - now);
119       this.beforeLoadTimeout_ = window.setTimeout(
120           this.loadWallpaper_.bind(this), timeout);
121     },
124     /**
125      * Loads pending wallpaper, if any.
126      * @private
127      */
128     loadWallpaper_: function() {
129       this.beforeLoadTimeout_ = null;
130       if (!this.wallpaperLoadPending_)
131         return;
132       if (!this.forceLoad_ && this.wallpaperLoadInProgress_.name != '')
133         return;
134       var email = this.wallpaperLoadPending_;
135       delete this.wallpaperLoadPending_;
136       if (!this.forceLoad_ && email == this.currentWallpaper_)
137         return;
138       this.wallpaperLoadInProgress_.name = email;
139       this.wallpaperLoadInProgress_.date = new Date();
140       this.forceLoad_ = false;
141       chrome.send('loadWallpaper', [email]);
143       var timeout = 3 * this.getWallpaperLoadTime_();
144       this.loadTimeout_ = window.setTimeout(
145           this.loadTimeoutFired_.bind(this), timeout);
146     },
148     /**
149      * Calculates average wallpaper load time.
150      */
151     calcLoadStatsAvg: function() {
152         return this.loadStats_.reduce(
153             function(previousValue, currentValue) {
154               return previousValue + currentValue;
155             }) / this.loadStats_.length;
156     },
158     /**
159      * Calculates average next wallpaper load delay time.
160      */
161     getWallpaperLoadTime_: function() {
162       var avg = WALLPAPER_DEFAULT_LOAD_TIME_MS;
164       if (this.loadStats_.length == 0)
165         return avg;
167       avg = this.calcLoadStatsAvg();
168       if (avg < WALLPAPER_MIN_LOAD_TIME_MS)
169         avg = WALLPAPER_MIN_LOAD_TIME_MS;
171       if (avg > WALLPAPER_MAX_LOAD_TIME_MS)
172         avg = WALLPAPER_MAX_LOAD_TIME_MS;
174       return avg;
175     },
177     /**
178      * Handles 'onWallpaperLoaded' event. Recalculates statistics and
179      * [re]schedules next wallpaper load.
180      */
181     onWallpaperLoaded: function(email) {
182       this.currentWallpaper_ = email;
183       if (email != this.wallpaperLoadInProgress_.name)
184           return;
186       window.clearTimeout(this.loadTimeout_);
187       this.loadTimeout_ = null;
189       this.wallpaperLoadInProgress_.name = '';
190       var started = this.wallpaperLoadInProgress_.date;
191       var finished = new Date();
192       var elapsed = started ? finished - started :
193           WALLPAPER_DEFAULT_LOAD_TIME_MS;
194       this.loadStats_.push(elapsed);
195       if (this.loadStats_.length > WALLPAPER_LOAD_STATS_MAX_LENGTH)
196         this.loadStats_.shift();
198       this.wallpaperLoadTryNextAfter_ = new Date(Date.now() + 2 *
199           this.getWallpaperLoadTime_());
200       if (this.wallpaperLoadPending_) {
201         var newWallpaperEmail = this.wallpaperLoadPending_;
202         this.reset();
203         this.scheduleLoad(newWallpaperEmail, this.forceLoad_);
204       }
205     },
207     /**
208      * Handles timeout of wallpaper load. Pretends load is completed to unblock
209      * loader.
210      */
211     loadTimeoutFired_: function() {
212       var email = this.wallpaperLoadInProgress_.name;
213       this.loadTimeout_ = null;
214       if (email == '')
215         return;
216       this.onWallpaperLoaded(email);
217     }
218   };
220   return {
221     WallpaperLoader: WallpaperLoader
222   };