Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: chrome/browser/resources/chromeos/login/user_pod_row.js

Issue 24625003: Delay wallpaper load by 2 * average wallpaper load time. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Catch WallpaperAnimationFinished event and inform JS. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview User pod row implementation. 6 * @fileoverview User pod row implementation.
7 */ 7 */
8 8
9 cr.define('login', function() { 9 cr.define('login', function() {
10 /** 10 /**
11 * Number of displayed columns depending on user pod count. 11 * Number of displayed columns depending on user pod count.
12 * @type {Array.<number>} 12 * @type {Array.<number>}
13 * @const 13 * @const
14 */ 14 */
15 var COLUMNS = [0, 1, 2, 3, 4, 5, 4, 4, 4, 5, 5, 6, 6, 5, 5, 6, 6, 6, 6]; 15 var COLUMNS = [0, 1, 2, 3, 4, 5, 4, 4, 4, 5, 5, 6, 6, 5, 5, 6, 6, 6, 6];
16 16
17 /** 17 /**
18 * Whether to preselect the first pod automatically on login screen. 18 * Whether to preselect the first pod automatically on login screen.
19 * @type {boolean} 19 * @type {boolean}
20 * @const 20 * @const
21 */ 21 */
22 var PRESELECT_FIRST_POD = true; 22 var PRESELECT_FIRST_POD = true;
23 23
24 /** 24 /**
25 * Wallpaper load delay in milliseconds. 25 * Minimum wallpaper load delay in milliseconds.
26 * @type {number} 26 * @type {number}
27 * @const 27 * @const
28 */ 28 */
29 var WALLPAPER_LOAD_DELAY_MS = 500; 29 var WALLPAPER_LOAD_MIN_DELAY_MS = 100;
30 30
31 /** 31 /**
32 * Wallpaper load delay in milliseconds. TODO(nkostylev): Tune this constant. 32 * If last walpaper load time cannot be calculated, assume this value.
33 * @type {number} 33 * @type {number}
34 * @const 34 * @const
35 */ 35 */
36 var WALLPAPER_BOOT_LOAD_DELAY_MS = 100; 36 var WALLPAPER_DEFAULT_LOAD_TIME_MS = 200;
37
38 /**
39 * Min and Max average wallpaper load time.
40 * Delay to next wallpaper load is 2 * <average load time>.
41 * @type {number}
42 * @const
43 */
44 var WALLPAPER_MIN_LOAD_TIME_MS = 50;
45 var WALLPAPER_MAX_LOAD_TIME_MS = 2000;
46
47 /**
48 * Number last wallpaper load times to remember.
49 * @type {number}
50 * @const
51 */
52 var WALLPAPER_LOAD_STATS_MAX_LENGTH = 4;
37 53
38 /** 54 /**
39 * Maximum time for which the pod row remains hidden until all user images 55 * Maximum time for which the pod row remains hidden until all user images
40 * have been loaded. 56 * have been loaded.
41 * @type {number} 57 * @type {number}
42 * @const 58 * @const
43 */ 59 */
44 var POD_ROW_IMAGES_LOAD_TIMEOUT_MS = 3000; 60 var POD_ROW_IMAGES_LOAD_TIMEOUT_MS = 3000;
45 61
46 /** 62 /**
(...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 * @extends {HTMLDivElement} 933 * @extends {HTMLDivElement}
918 */ 934 */
919 var PodRow = cr.ui.define('podrow'); 935 var PodRow = cr.ui.define('podrow');
920 936
921 PodRow.prototype = { 937 PodRow.prototype = {
922 __proto__: HTMLDivElement.prototype, 938 __proto__: HTMLDivElement.prototype,
923 939
924 // Whether this user pod row is shown for the first time. 940 // Whether this user pod row is shown for the first time.
925 firstShown_: true, 941 firstShown_: true,
926 942
927 // Whether the initial wallpaper load after boot has been requested. Used
928 // only if |Oobe.getInstance().shouldLoadWallpaperOnBoot()| is true.
929 bootWallpaperLoaded_: false,
930
931 // True if inside focusPod(). 943 // True if inside focusPod().
932 insideFocusPod_: false, 944 insideFocusPod_: false,
933 945
934 // True if user pod has been activated with keyboard.
935 // In case of activation with keyboard we delay wallpaper change.
936 keyboardActivated_: false,
937
938 // Focused pod. 946 // Focused pod.
939 focusedPod_: undefined, 947 focusedPod_: undefined,
940 948
941 // Activated pod, i.e. the pod of current login attempt. 949 // Activated pod, i.e. the pod of current login attempt.
942 activatedPod_: undefined, 950 activatedPod_: undefined,
943 951
944 // Pod that was most recently focused, if any. 952 // Pod that was most recently focused, if any.
945 lastFocusedPod_: undefined, 953 lastFocusedPod_: undefined,
946 954
947 // When moving through users quickly at login screen, set a timeout to 955 // When moving through users quickly at login screen, set a timeout to
948 // prevent loading intermediate wallpapers. 956 // prevent loading intermediate wallpapers.
949 loadWallpaperTimeout_: null, 957 loadWallpaperTimeout_: null,
950 958
959 // When waiting for wallpaper load, remember load start time.
960 // This is actually associative array with key = username and value =
961 // start time.
962 wallpaperLoadInProgress_: {},
963
964 // Wait a delay and then load this wallpaper. Value = username.
965 wallpaperLoadPending: undefined,
966
967 // Wait untill this Date before loading next wallpaper.
968 wallpaperLoadTryNextAfter: undefined,
969
970 // Username, owner of current wallpaper.
971 wallpaperCurrent: '',
972
973 wallpaperLoadStats: {
974 // Array of times (in milliseconds) of last wallpaper load attempts.
975 // Length is limited by WALLPAPER_LOAD_STATS_MAX_LENGTH.
976 history: [],
977 // sum(history)
978 totalTimeMs: 0
979 },
980
951 // Pods whose initial images haven't been loaded yet. 981 // Pods whose initial images haven't been loaded yet.
952 podsWithPendingImages_: [], 982 podsWithPendingImages_: [],
953 983
954 /** @override */ 984 /** @override */
955 decorate: function() { 985 decorate: function() {
956 this.style.left = 0; 986 this.style.left = 0;
957 987
958 // Event listeners that are installed for the time period during which 988 // Event listeners that are installed for the time period during which
959 // the element is visible. 989 // the element is visible.
960 this.listeners_ = { 990 this.listeners_ = {
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 /** 1212 /**
1183 * Whether the pod is currently focused. 1213 * Whether the pod is currently focused.
1184 * @param {UserPod} pod Pod to check for focus. 1214 * @param {UserPod} pod Pod to check for focus.
1185 * @return {boolean} Pod focus status. 1215 * @return {boolean} Pod focus status.
1186 */ 1216 */
1187 isFocused: function(pod) { 1217 isFocused: function(pod) {
1188 return this.focusedPod_ == pod; 1218 return this.focusedPod_ == pod;
1189 }, 1219 },
1190 1220
1191 /** 1221 /**
1222 * Schedules wallpaper load.
1223 */
1224 scheduleLoadWallpaper: function(email) {
1225 if (this.wallpaperLoadPending && this.wallpaperLoadPending == email)
1226 return;
1227 this.wallpaperLoadPending = email;
1228 if (this.wallpaperLoadInProgress_.hasOwnProperty(email)) {
1229 clearTimeout(this.loadWallpaperTimeout_);
1230 delete this.wallpaperLoadPending;
1231 return;
1232 }
1233 if ((Object.getOwnPropertyNames(this.wallpaperLoadInProgress_).length ==
1234 0) && (this.wallpaperCurrent == email)) {
1235 delete this.wallpaperLoadPending;
1236 return;
1237 }
1238 if (this.loadWallpaperTimeout_) {
1239 clearTimeout(this.loadWallpaperTimeout_);
1240 }
1241 var now = new Date();
1242 var timeout = WALLPAPER_LOAD_MIN_DELAY_MS;
1243 if (this.wallpaperLoadTryNextAfter &&
1244 (now < this.wallpaperLoadTryNextAfter) &&
1245 (this.wallpaperLoadTryNextAfter.getTime() -
1246 now.getTime() > WALLPAPER_LOAD_MIN_DELAY_MS))
1247 timeout = this.wallpaperLoadTryNextAfter.getTime() -
1248 now.getTime();
1249
1250 this.loadWallpaperTimeout_ = window.setTimeout(
1251 this.loadWallpaper_.bind(this), timeout);
1252 },
1253
1254 /**
1192 * Focuses a given user pod or clear focus when given null. 1255 * Focuses a given user pod or clear focus when given null.
1193 * @param {UserPod=} podToFocus User pod to focus (undefined clears focus). 1256 * @param {UserPod=} podToFocus User pod to focus (undefined clears focus).
1194 * @param {boolean=} opt_force If true, forces focus update even when 1257 * @param {boolean=} opt_force If true, forces focus update even when
1195 * podToFocus is already focused. 1258 * podToFocus is already focused.
1196 */ 1259 */
1197 focusPod: function(podToFocus, opt_force) { 1260 focusPod: function(podToFocus, opt_force) {
1198 if (this.isFocused(podToFocus) && !opt_force) { 1261 if (this.isFocused(podToFocus) && !opt_force) {
1199 this.keyboardActivated_ = false; 1262 this.keyboardActivated_ = false;
1200 return; 1263 return;
1201 } 1264 }
(...skipping 22 matching lines...) Expand all
1224 if (!this.isFocused(podToFocus)) 1287 if (!this.isFocused(podToFocus))
1225 Oobe.clearErrors(); 1288 Oobe.clearErrors();
1226 1289
1227 var hadFocus = !!this.focusedPod_; 1290 var hadFocus = !!this.focusedPod_;
1228 this.focusedPod_ = podToFocus; 1291 this.focusedPod_ = podToFocus;
1229 if (podToFocus) { 1292 if (podToFocus) {
1230 podToFocus.classList.remove('faded'); 1293 podToFocus.classList.remove('faded');
1231 podToFocus.classList.add('focused'); 1294 podToFocus.classList.add('focused');
1232 podToFocus.reset(true); // Reset and give focus. 1295 podToFocus.reset(true); // Reset and give focus.
1233 chrome.send('focusPod', [podToFocus.user.emailAddress]); 1296 chrome.send('focusPod', [podToFocus.user.emailAddress]);
1234 if (hadFocus && this.keyboardActivated_) { 1297
1235 // Delay wallpaper loading to let user tab through pods without lag. 1298 this.scheduleLoadWallpaper(podToFocus.user.emailAddress);
1236 this.loadWallpaperTimeout_ = window.setTimeout(
1237 this.loadWallpaper_.bind(this), WALLPAPER_LOAD_DELAY_MS);
1238 } else if (!this.firstShown_) {
1239 // Load wallpaper immediately if there no pod was focused
1240 // previously, and it is not a boot into user pod list case.
1241 this.loadWallpaper_();
1242 }
1243 this.firstShown_ = false; 1299 this.firstShown_ = false;
1244 this.lastFocusedPod_ = podToFocus; 1300 this.lastFocusedPod_ = podToFocus;
1245 } 1301 }
1246 this.insideFocusPod_ = false; 1302 this.insideFocusPod_ = false;
1247 this.keyboardActivated_ = false; 1303 this.keyboardActivated_ = false;
1248 }, 1304 },
1249 1305
1250 /** 1306 /**
1251 * Loads wallpaper for the active user pod, if any. 1307 * Loads pending wallpaper, if any.
1252 * @private 1308 * @private
1253 */ 1309 */
1254 loadWallpaper_: function() { 1310 loadWallpaper_: function() {
1255 if (this.focusedPod_) 1311 if (this.wallpaperLoadPending) {
1256 chrome.send('loadWallpaper', [this.focusedPod_.user.username]); 1312 var email = this.wallpaperLoadPending;
1313 delete this.wallpaperLoadPending;
1314 if (email == this.wallpaperCurrent)
1315 return;
1316 if (this.wallpaperLoadInProgress_[email])
1317 return;
1318 this.wallpaperLoadInProgress_[email] = new Date();
1319 chrome.send('loadWallpaper', [email]);
1320 }
1257 }, 1321 },
1258 1322
1259 /** 1323 /**
1260 * Resets wallpaper to the last active user's wallpaper, if any. 1324 * Resets wallpaper to the last active user's wallpaper, if any.
1261 */ 1325 */
1262 loadLastWallpaper: function() { 1326 loadLastWallpaper: function() {
1263 if (this.lastFocusedPod_) 1327 if (this.lastFocusedPod_)
1264 chrome.send('loadWallpaper', [this.lastFocusedPod_.user.username]); 1328 this.scheduleLoadWallpaper(this.lastFocusedPod_.user.username);
1265 }, 1329 },
1266 1330
1267 /** 1331 /**
1332 * Calculates average wallpaper load time.
1333 */
1334 getWallpaperLoadAvg_: function() {
1335 var avg = WALLPAPER_DEFAULT_LOAD_TIME_MS;
1336 if (this.wallpaperLoadStats.history.length) {
1337 avg = this.wallpaperLoadStats.totalTimeMs /
1338 this.wallpaperLoadStats.history.length;
1339 if (avg < WALLPAPER_MIN_LOAD_TIME_MS) {
1340 avg = WALLPAPER_MIN_LOAD_TIME_MS;
1341 }
1342 if (avg > WALLPAPER_MAX_LOAD_TIME_MS) {
1343 avg = WALLPAPER_MAX_LOAD_TIME_MS;
1344 }
1345 }
1346 return avg;
1347 },
1348
1349 /**
1350 * Handles 'onWallpaperLoaded' event. Recalculates statistics and
1351 * [re]schedules next wallpaper load.
1352 */
1353 onWallpaperLoaded: function(email) {
1354 this.wallpaperCurrent = email;
1355 var started = this.wallpaperLoadInProgress_[email];
1356 delete this.wallpaperLoadInProgress_[email];
1357 var finished = new Date();
1358 var elapsed = started ? finished.getTime() - started.getTime() :
1359 WALLPAPER_DEFAULT_LOAD_TIME_MS;
1360 this.wallpaperLoadStats.history.push(elapsed);
1361 this.wallpaperLoadStats.totalTimeMs += elapsed;
1362 if (this.wallpaperLoadStats.history.length >
1363 WALLPAPER_LOAD_STATS_MAX_LENGTH) {
1364 var tt = this.wallpaperLoadStats.history.shift();
1365 this.wallpaperLoadStats.totalTimeMs -= tt;
1366 }
1367 var nextAfter = new Date();
1368 nextAfter.setTime(nextAfter.getTime() +
1369 2 * this.getWallpaperLoadAvg_());
1370 this.wallpaperLoadTryNextAfter = nextAfter;
1371 if (this.wallpaperLoadPending) {
1372 var newWallpaperEmail = this.wallpaperLoadPending;
1373 delete this.wallpaperLoadPending;
1374 if (newWallpaperEmail == email) {
1375 clearTimeout(this.loadWallpaperTimeout_);
1376 } else {
1377 this.scheduleLoadWallpaper(newWallpaperEmail);
1378 }
1379 }
1380 },
1381
1382 /**
1268 * Returns the currently activated pod. 1383 * Returns the currently activated pod.
1269 * @type {UserPod} 1384 * @type {UserPod}
1270 */ 1385 */
1271 get activatedPod() { 1386 get activatedPod() {
1272 return this.activatedPod_; 1387 return this.activatedPod_;
1273 }, 1388 },
1274 set activatedPod(pod) { 1389 set activatedPod(pod) {
1275 if (pod && pod.activate()) 1390 if (pod && pod.activate())
1276 this.activatedPod_ = pod; 1391 this.activatedPod_ = pod;
1277 }, 1392 },
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 if (this.focusedPod_) { 1633 if (this.focusedPod_) {
1519 var focusedPod = this.focusedPod_; 1634 var focusedPod = this.focusedPod_;
1520 var screen = this.parentNode; 1635 var screen = this.parentNode;
1521 var self = this; 1636 var self = this;
1522 focusedPod.addEventListener('webkitTransitionEnd', function f(e) { 1637 focusedPod.addEventListener('webkitTransitionEnd', function f(e) {
1523 if (e.target == focusedPod) { 1638 if (e.target == focusedPod) {
1524 focusedPod.removeEventListener('webkitTransitionEnd', f); 1639 focusedPod.removeEventListener('webkitTransitionEnd', f);
1525 focusedPod.reset(true); 1640 focusedPod.reset(true);
1526 // Notify screen that it is ready. 1641 // Notify screen that it is ready.
1527 screen.onShow(); 1642 screen.onShow();
1528 // Boot transition: load wallpaper. 1643 self.scheduleLoadWallpaper(focusedPod.user.username);
1529 if (!self.bootWallpaperLoaded_ &&
1530 Oobe.getInstance().shouldLoadWallpaperOnBoot()) {
1531 self.loadWallpaperTimeout_ = window.setTimeout(
1532 self.loadWallpaper_.bind(self), WALLPAPER_BOOT_LOAD_DELAY_MS);
1533 self.bootWallpaperLoaded_ = true;
1534 }
1535 } 1644 }
1536 }); 1645 });
1537 } 1646 }
1538 }, 1647 },
1539 1648
1540 /** 1649 /**
1541 * Called right before the pod row is shown. 1650 * Called right before the pod row is shown.
1542 */ 1651 */
1543 handleBeforeShow: function() { 1652 handleBeforeShow: function() {
1544 for (var event in this.listeners_) { 1653 for (var event in this.listeners_) {
(...skipping 27 matching lines...) Expand all
1572 if (this.podsWithPendingImages_.length == 0) { 1681 if (this.podsWithPendingImages_.length == 0) {
1573 this.classList.remove('images-loading'); 1682 this.classList.remove('images-loading');
1574 } 1683 }
1575 } 1684 }
1576 }; 1685 };
1577 1686
1578 return { 1687 return {
1579 PodRow: PodRow 1688 PodRow: PodRow
1580 }; 1689 };
1581 }); 1690 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698