| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 }); |
| OLD | NEW |