Index: chrome/browser/resources/chromeos/login/user_pod_row.js |
diff --git a/chrome/browser/resources/chromeos/login/user_pod_row.js b/chrome/browser/resources/chromeos/login/user_pod_row.js |
index c1b03eed5bfd9d8bbddcc70519420d319b05f086..cf42e9fddd02a6e0d4eea1e0db0a0a8e76769a4d 100644 |
--- a/chrome/browser/resources/chromeos/login/user_pod_row.js |
+++ b/chrome/browser/resources/chromeos/login/user_pod_row.js |
@@ -22,18 +22,34 @@ cr.define('login', function() { |
var PRESELECT_FIRST_POD = true; |
/** |
- * Wallpaper load delay in milliseconds. |
+ * Minimum wallpaper load delay in milliseconds. |
* @type {number} |
* @const |
*/ |
- var WALLPAPER_LOAD_DELAY_MS = 500; |
+ var WALLPAPER_LOAD_MIN_DELAY_MS = 100; |
/** |
- * Wallpaper load delay in milliseconds. TODO(nkostylev): Tune this constant. |
+ * If last walpaper load time cannot be calculated, assume this value. |
* @type {number} |
* @const |
*/ |
- var WALLPAPER_BOOT_LOAD_DELAY_MS = 100; |
+ var WALLPAPER_DEFAULT_LOAD_TIME_MS = 200; |
+ |
+ /** |
+ * Min and Max average wallpaper load time. |
+ * Delay to next wallpaper load is 2 * <average load time>. |
+ * @type {number} |
+ * @const |
+ */ |
+ var WALLPAPER_MIN_LOAD_TIME_MS = 50; |
+ var WALLPAPER_MAX_LOAD_TIME_MS = 2000; |
+ |
+ /** |
+ * Number last wallpaper load times to remember. |
+ * @type {number} |
+ * @const |
+ */ |
+ var WALLPAPER_LOAD_STATS_MAX_LENGTH = 4; |
/** |
* Maximum time for which the pod row remains hidden until all user images |
@@ -924,17 +940,9 @@ cr.define('login', function() { |
// Whether this user pod row is shown for the first time. |
firstShown_: true, |
- // Whether the initial wallpaper load after boot has been requested. Used |
- // only if |Oobe.getInstance().shouldLoadWallpaperOnBoot()| is true. |
- bootWallpaperLoaded_: false, |
- |
// True if inside focusPod(). |
insideFocusPod_: false, |
- // True if user pod has been activated with keyboard. |
- // In case of activation with keyboard we delay wallpaper change. |
- keyboardActivated_: false, |
- |
// Focused pod. |
focusedPod_: undefined, |
@@ -948,6 +956,28 @@ cr.define('login', function() { |
// prevent loading intermediate wallpapers. |
loadWallpaperTimeout_: null, |
+ // When waiting for wallpaper load, remember load start time. |
+ // This is actually associative array with key = username and value = |
+ // start time. |
+ wallpaperLoadInProgress_: {}, |
+ |
+ // Wait a delay and then load this wallpaper. Value = username. |
+ wallpaperLoadPending: undefined, |
+ |
+ // Wait untill this Date before loading next wallpaper. |
+ wallpaperLoadTryNextAfter: undefined, |
+ |
+ // Username, owner of current wallpaper. |
+ wallpaperCurrent: '', |
+ |
+ wallpaperLoadStats: { |
+ // Array of times (in milliseconds) of last wallpaper load attempts. |
+ // Length is limited by WALLPAPER_LOAD_STATS_MAX_LENGTH. |
+ history: [], |
+ // sum(history) |
+ totalTimeMs: 0 |
+ }, |
+ |
// Pods whose initial images haven't been loaded yet. |
podsWithPendingImages_: [], |
@@ -1189,6 +1219,39 @@ cr.define('login', function() { |
}, |
/** |
+ * Schedules wallpaper load. |
+ */ |
+ scheduleLoadWallpaper: function(email) { |
+ if (this.wallpaperLoadPending && this.wallpaperLoadPending == email) |
+ return; |
+ this.wallpaperLoadPending = email; |
+ if (this.wallpaperLoadInProgress_.hasOwnProperty(email)) { |
+ clearTimeout(this.loadWallpaperTimeout_); |
+ delete this.wallpaperLoadPending; |
+ return; |
+ } |
+ if ((Object.getOwnPropertyNames(this.wallpaperLoadInProgress_).length == |
+ 0) && (this.wallpaperCurrent == email)) { |
+ delete this.wallpaperLoadPending; |
+ return; |
+ } |
+ if (this.loadWallpaperTimeout_) { |
+ clearTimeout(this.loadWallpaperTimeout_); |
+ } |
+ var now = new Date(); |
+ var timeout = WALLPAPER_LOAD_MIN_DELAY_MS; |
+ if (this.wallpaperLoadTryNextAfter && |
+ (now < this.wallpaperLoadTryNextAfter) && |
+ (this.wallpaperLoadTryNextAfter.getTime() - |
+ now.getTime() > WALLPAPER_LOAD_MIN_DELAY_MS)) |
+ timeout = this.wallpaperLoadTryNextAfter.getTime() - |
+ now.getTime(); |
+ |
+ this.loadWallpaperTimeout_ = window.setTimeout( |
+ this.loadWallpaper_.bind(this), timeout); |
+ }, |
+ |
+ /** |
* Focuses a given user pod or clear focus when given null. |
* @param {UserPod=} podToFocus User pod to focus (undefined clears focus). |
* @param {boolean=} opt_force If true, forces focus update even when |
@@ -1231,15 +1294,8 @@ cr.define('login', function() { |
podToFocus.classList.add('focused'); |
podToFocus.reset(true); // Reset and give focus. |
chrome.send('focusPod', [podToFocus.user.emailAddress]); |
- if (hadFocus && this.keyboardActivated_) { |
- // Delay wallpaper loading to let user tab through pods without lag. |
- this.loadWallpaperTimeout_ = window.setTimeout( |
- this.loadWallpaper_.bind(this), WALLPAPER_LOAD_DELAY_MS); |
- } else if (!this.firstShown_) { |
- // Load wallpaper immediately if there no pod was focused |
- // previously, and it is not a boot into user pod list case. |
- this.loadWallpaper_(); |
- } |
+ |
+ this.scheduleLoadWallpaper(podToFocus.user.emailAddress); |
this.firstShown_ = false; |
this.lastFocusedPod_ = podToFocus; |
} |
@@ -1248,12 +1304,20 @@ cr.define('login', function() { |
}, |
/** |
- * Loads wallpaper for the active user pod, if any. |
+ * Loads pending wallpaper, if any. |
* @private |
*/ |
loadWallpaper_: function() { |
- if (this.focusedPod_) |
- chrome.send('loadWallpaper', [this.focusedPod_.user.username]); |
+ if (this.wallpaperLoadPending) { |
+ var email = this.wallpaperLoadPending; |
+ delete this.wallpaperLoadPending; |
+ if (email == this.wallpaperCurrent) |
+ return; |
+ if (this.wallpaperLoadInProgress_[email]) |
+ return; |
+ this.wallpaperLoadInProgress_[email] = new Date(); |
+ chrome.send('loadWallpaper', [email]); |
+ } |
}, |
/** |
@@ -1261,7 +1325,58 @@ cr.define('login', function() { |
*/ |
loadLastWallpaper: function() { |
if (this.lastFocusedPod_) |
- chrome.send('loadWallpaper', [this.lastFocusedPod_.user.username]); |
+ this.scheduleLoadWallpaper(this.lastFocusedPod_.user.username); |
+ }, |
+ |
+ /** |
+ * Calculates average wallpaper load time. |
+ */ |
+ getWallpaperLoadAvg_: function() { |
+ var avg = WALLPAPER_DEFAULT_LOAD_TIME_MS; |
+ if (this.wallpaperLoadStats.history.length) { |
+ avg = this.wallpaperLoadStats.totalTimeMs / |
+ this.wallpaperLoadStats.history.length; |
+ if (avg < WALLPAPER_MIN_LOAD_TIME_MS) { |
+ avg = WALLPAPER_MIN_LOAD_TIME_MS; |
+ } |
+ if (avg > WALLPAPER_MAX_LOAD_TIME_MS) { |
+ avg = WALLPAPER_MAX_LOAD_TIME_MS; |
+ } |
+ } |
+ return avg; |
+ }, |
+ |
+ /** |
+ * Handles 'onWallpaperLoaded' event. Recalculates statistics and |
+ * [re]schedules next wallpaper load. |
+ */ |
+ onWallpaperLoaded: function(email) { |
+ this.wallpaperCurrent = email; |
+ var started = this.wallpaperLoadInProgress_[email]; |
+ delete this.wallpaperLoadInProgress_[email]; |
+ var finished = new Date(); |
+ var elapsed = started ? finished.getTime() - started.getTime() : |
+ WALLPAPER_DEFAULT_LOAD_TIME_MS; |
+ this.wallpaperLoadStats.history.push(elapsed); |
+ this.wallpaperLoadStats.totalTimeMs += elapsed; |
+ if (this.wallpaperLoadStats.history.length > |
+ WALLPAPER_LOAD_STATS_MAX_LENGTH) { |
+ var tt = this.wallpaperLoadStats.history.shift(); |
+ this.wallpaperLoadStats.totalTimeMs -= tt; |
+ } |
+ var nextAfter = new Date(); |
+ nextAfter.setTime(nextAfter.getTime() + |
+ 2 * this.getWallpaperLoadAvg_()); |
+ this.wallpaperLoadTryNextAfter = nextAfter; |
+ if (this.wallpaperLoadPending) { |
+ var newWallpaperEmail = this.wallpaperLoadPending; |
+ delete this.wallpaperLoadPending; |
+ if (newWallpaperEmail == email) { |
+ clearTimeout(this.loadWallpaperTimeout_); |
+ } else { |
+ this.scheduleLoadWallpaper(newWallpaperEmail); |
+ } |
+ } |
}, |
/** |
@@ -1525,13 +1640,7 @@ cr.define('login', function() { |
focusedPod.reset(true); |
// Notify screen that it is ready. |
screen.onShow(); |
- // Boot transition: load wallpaper. |
- if (!self.bootWallpaperLoaded_ && |
- Oobe.getInstance().shouldLoadWallpaperOnBoot()) { |
- self.loadWallpaperTimeout_ = window.setTimeout( |
- self.loadWallpaper_.bind(self), WALLPAPER_BOOT_LOAD_DELAY_MS); |
- self.bootWallpaperLoaded_ = true; |
- } |
+ self.scheduleLoadWallpaper(focusedPod.user.username); |
} |
}); |
} |