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 |