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() {
8 * Minimum wallpaper load delay in milliseconds.
12 var WALLPAPER_LOAD_MIN_DELAY_MS = 100;
15 * If last walpaper load time cannot be calculated, assume this value.
19 var WALLPAPER_DEFAULT_LOAD_TIME_MS = 200;
22 * Min and Max average wallpaper load time.
23 * Delay to next wallpaper load is 2 * <average load time>.
27 var WALLPAPER_MIN_LOAD_TIME_MS = 50;
28 var WALLPAPER_MAX_LOAD_TIME_MS = 2000;
31 * Number last wallpaper load times to remember.
35 var WALLPAPER_LOAD_STATS_MAX_LENGTH = 4;
39 * Creates a new pod row element.
41 * @extends {HTMLDivElement}
43 var WallpaperLoader = function() {
44 this.wallpaperLoadInProgress_ = {
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.
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.
82 * Stop load timer. Clear pending record.
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 = '';
99 * Schedules wallpaper load.
101 scheduleLoad: function(email, force) {
102 if (force || this.forceLoad_) {
103 this.forceLoad_ = true;
105 if (this.wallpaperLoadPending_ && this.wallpaperLoadPending_ == email)
107 if ((this.wallpaperLoadInProgress_.name == '') &&
108 (this.currentWallpaper_ == email))
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);
125 * Loads pending wallpaper, if any.
128 loadWallpaper_: function() {
129 this.beforeLoadTimeout_ = null;
130 if (!this.wallpaperLoadPending_)
132 if (!this.forceLoad_ && this.wallpaperLoadInProgress_.name != '')
134 var email = this.wallpaperLoadPending_;
135 delete this.wallpaperLoadPending_;
136 if (!this.forceLoad_ && email == this.currentWallpaper_)
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);
149 * Calculates average wallpaper load time.
151 calcLoadStatsAvg: function() {
152 return this.loadStats_.reduce(
153 function(previousValue, currentValue) {
154 return previousValue + currentValue;
155 }) / this.loadStats_.length;
159 * Calculates average next wallpaper load delay time.
161 getWallpaperLoadTime_: function() {
162 var avg = WALLPAPER_DEFAULT_LOAD_TIME_MS;
164 if (this.loadStats_.length == 0)
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;
178 * Handles 'onWallpaperLoaded' event. Recalculates statistics and
179 * [re]schedules next wallpaper load.
181 onWallpaperLoaded: function(email) {
182 this.currentWallpaper_ = email;
183 if (email != this.wallpaperLoadInProgress_.name)
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_;
203 this.scheduleLoad(newWallpaperEmail, this.forceLoad_);
208 * Handles timeout of wallpaper load. Pretends load is completed to unblock
211 loadTimeoutFired_: function() {
212 var email = this.wallpaperLoadInProgress_.name;
213 this.loadTimeout_ = null;
216 this.onWallpaperLoaded(email);
221 WallpaperLoader: WallpaperLoader