1 // Copyright 2014 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. 4 5 /** 6 * @fileoverview Account picker screen implementation. 7 */ 8 9 login.createScreen('AccountPickerScreen', 'account-picker', function() { 10 /** 11 * Maximum number of offline login failures before online login. 12 * @type {number} 13 * @const 14 */ 15 var MAX_LOGIN_ATTEMPTS_IN_POD = 3; 16 /** 17 * Whether to preselect the first pod automatically on login screen. 18 * @type {boolean} 19 * @const 20 */ 21 var PRESELECT_FIRST_POD = true; 22 23 return { 24 EXTERNAL_API: [ 25 'loadUsers', 26 'runAppForTesting', 27 'setApps', 28 'setShouldShowApps', 29 'showAppError', 30 'updateUserImage', 31 'setCapsLockState', 32 'forceLockedUserPodFocus', 33 'removeUser', 34 'showBannerMessage', 35 'showUserPodCustomIcon', 36 'hideUserPodCustomIcon', 37 'setAuthType', 38 'showEasyUnlockBubble', 39 ], 40 41 preferredWidth_: 0, 42 preferredHeight_: 0, 43 44 // Whether this screen is shown for the first time. 45 firstShown_: true, 46 47 /** @override */ 48 decorate: function() { 49 login.PodRow.decorate($('pod-row')); 50 }, 51 52 /** @override */ 53 getPreferredSize: function() { 54 return {width: this.preferredWidth_, height: this.preferredHeight_}; 55 }, 56 57 /** @override */ 58 onWindowResize: function() { 59 $('pod-row').onWindowResize(); 60 }, 61 62 /** 63 * Sets preferred size for account picker screen. 64 */ 65 setPreferredSize: function(width, height) { 66 this.preferredWidth_ = width; 67 this.preferredHeight_ = height; 68 }, 69 70 /** 71 * When the account picker is being used to lock the screen, pressing the 72 * exit accelerator key will sign out the active user as it would when 73 * they are signed in. 74 */ 75 exit: function() { 76 // Check and disable the sign out button so that we can never have two 77 // sign out requests generated in a row. 78 if ($('pod-row').lockedPod && !$('sign-out-user-button').disabled) { 79 $('sign-out-user-button').disabled = true; 80 chrome.send('signOutUser'); 81 } 82 }, 83 84 /* Cancel user adding if ESC was pressed. 85 */ 86 cancel: function() { 87 if (Oobe.getInstance().displayType == DISPLAY_TYPE.USER_ADDING) 88 chrome.send('cancelUserAdding'); 89 }, 90 91 /** 92 * Event handler that is invoked just after the frame is shown. 93 * @param {string} data Screen init payload. 94 */ 95 onAfterShow: function(data) { 96 $('pod-row').handleAfterShow(); 97 }, 98 99 /** 100 * Event handler that is invoked just before the frame is shown. 101 * @param {string} data Screen init payload. 102 */ 103 onBeforeShow: function(data) { 104 chrome.send('loginUIStateChanged', ['account-picker', true]); 105 $('login-header-bar').signinUIState = SIGNIN_UI_STATE.ACCOUNT_PICKER; 106 chrome.send('hideCaptivePortal'); 107 var podRow = $('pod-row'); 108 podRow.handleBeforeShow(); 109 110 // In case of the preselected pod onShow will be called once pod 111 // receives focus. 112 if (!podRow.preselectedPod) 113 this.onShow(); 114 }, 115 116 /** 117 * Event handler invoked when the page is shown and ready. 118 */ 119 onShow: function() { 120 if (!this.firstShown_) return; 121 this.firstShown_ = false; 122 // TODO(nkostylev): Enable animation back when session start jank 123 // is reduced. See http://crosbug.com/11116 http://crosbug.com/18307 124 // $('pod-row').startInitAnimation(); 125 126 // Ensure that login is actually visible. 127 window.webkitRequestAnimationFrame(function() { 128 chrome.send('accountPickerReady'); 129 chrome.send('loginVisible', ['account-picker']); 130 }); 131 }, 132 133 /** 134 * Event handler that is invoked just before the frame is hidden. 135 */ 136 onBeforeHide: function() { 137 chrome.send('loginUIStateChanged', ['account-picker', false]); 138 $('login-header-bar').signinUIState = SIGNIN_UI_STATE.HIDDEN; 139 $('pod-row').handleHide(); 140 }, 141 142 /** 143 * Shows sign-in error bubble. 144 * @param {number} loginAttempts Number of login attemps tried. 145 * @param {HTMLElement} content Content to show in bubble. 146 */ 147 showErrorBubble: function(loginAttempts, error) { 148 var activatedPod = $('pod-row').activatedPod; 149 if (!activatedPod) { 150 $('bubble').showContentForElement($('pod-row'), 151 cr.ui.Bubble.Attachment.RIGHT, 152 error); 153 return; 154 } 155 // Show web authentication if this is not a locally managed user. 156 if (loginAttempts > MAX_LOGIN_ATTEMPTS_IN_POD && 157 !activatedPod.user.locallyManagedUser) { 158 activatedPod.showSigninUI(); 159 } else { 160 // We want bubble's arrow to point to the first letter of input. 161 /** @const */ var BUBBLE_OFFSET = 7; 162 /** @const */ var BUBBLE_PADDING = 4; 163 $('bubble').showContentForElement(activatedPod.mainInput, 164 cr.ui.Bubble.Attachment.BOTTOM, 165 error, 166 BUBBLE_OFFSET, BUBBLE_PADDING); 167 } 168 }, 169 170 /** 171 * Loads given users in pod row. 172 * @param {array} users Array of user. 173 * @param {boolean} animated Whether to use init animation. 174 * @param {boolean} showGuest Whether to show guest session button. 175 */ 176 loadUsers: function(users, animated, showGuest) { 177 $('pod-row').loadPods(users, animated); 178 $('login-header-bar').showGuestButton = showGuest; 179 180 // The desktop User Manager can send the index of a pod that should be 181 // initially focused. 182 var hash = window.location.hash; 183 if (hash) { 184 var podIndex = hash.substr(1); 185 if (podIndex) 186 $('pod-row').focusPodByIndex(podIndex, false); 187 } 188 }, 189 190 /** 191 * Runs app with a given id from the list of loaded apps. 192 * @param {!string} app_id of an app to run. 193 * @param {boolean=} opt_diagnostic_mode Whether to run the app in 194 * diagnostic mode. Default is false. 195 */ 196 runAppForTesting: function(app_id, opt_diagnostic_mode) { 197 $('pod-row').findAndRunAppForTesting(app_id, opt_diagnostic_mode); 198 }, 199 200 /** 201 * Adds given apps to the pod row. 202 * @param {array} apps Array of apps. 203 */ 204 setApps: function(apps) { 205 $('pod-row').setApps(apps); 206 }, 207 208 /** 209 * Sets the flag of whether app pods should be visible. 210 * @param {boolean} shouldShowApps Whether to show app pods. 211 */ 212 setShouldShowApps: function(shouldShowApps) { 213 $('pod-row').setShouldShowApps(shouldShowApps); 214 }, 215 216 /** 217 * Shows the given kiosk app error message. 218 * @param {!string} message Error message to show. 219 */ 220 showAppError: function(message) { 221 // TODO(nkostylev): Figure out a way to show kiosk app launch error 222 // pointing to the kiosk app pod. 223 /** @const */ var BUBBLE_PADDING = 12; 224 $('bubble').showTextForElement($('pod-row'), 225 message, 226 cr.ui.Bubble.Attachment.BOTTOM, 227 $('pod-row').offsetWidth / 2, 228 BUBBLE_PADDING); 229 }, 230 231 /** 232 * Updates current image of a user. 233 * @param {string} username User for which to update the image. 234 */ 235 updateUserImage: function(username) { 236 $('pod-row').updateUserImage(username); 237 }, 238 239 /** 240 * Updates Caps Lock state (for Caps Lock hint in password input field). 241 * @param {boolean} enabled Whether Caps Lock is on. 242 */ 243 setCapsLockState: function(enabled) { 244 $('pod-row').classList.toggle('capslock-on', enabled); 245 }, 246 247 /** 248 * Enforces focus on user pod of locked user. 249 */ 250 forceLockedUserPodFocus: function() { 251 var row = $('pod-row'); 252 if (row.lockedPod) 253 row.focusPod(row.lockedPod, true); 254 }, 255 256 /** 257 * Remove given user from pod row if it is there. 258 * @param {string} user name. 259 */ 260 removeUser: function(username) { 261 $('pod-row').removeUserPod(username); 262 }, 263 264 /** 265 * Displays a banner containing |message|. If the banner is already present 266 * this function updates the message in the banner. This function is used 267 * by the chrome.screenlockPrivate.showMessage API. 268 * @param {string} message Text to be displayed 269 */ 270 showBannerMessage: function(message) { 271 var banner = $('signin-banner'); 272 banner.textContent = message; 273 banner.classList.toggle('message-set', true); 274 }, 275 276 /** 277 * Shows a custom icon in the user pod of |username|. This function 278 * is used by the chrome.screenlockPrivate API. 279 * @param {string} username Username of pod to add button 280 * @param {{scale1x: string, scale2x: string}} icon Dictionary of URLs of 281 * the custom icon's representations for 1x and 2x scale factors. 282 */ 283 showUserPodCustomIcon: function(username, icon) { 284 $('pod-row').showUserPodCustomIcon(username, icon); 285 }, 286 287 /** 288 * Hides the custom icon in the user pod of |username| added by 289 * showUserPodCustomIcon(). This function is used by the 290 * chrome.screenlockPrivate API. 291 * @param {string} username Username of pod to remove button 292 */ 293 hideUserPodCustomIcon: function(username) { 294 $('pod-row').hideUserPodCustomIcon(username); 295 }, 296 297 /** 298 * Sets the authentication type used to authenticate the user. 299 * @param {string} username Username of selected user 300 * @param {number} authType Authentication type, must be a valid value in 301 * the AUTH_TYPE enum in user_pod_row.js. 302 * @param {string} value The initial value to use for authentication. 303 */ 304 setAuthType: function(username, authType, value) { 305 $('pod-row').setAuthType(username, authType, value); 306 }, 307 308 /** 309 * Shows a tooltip bubble explaining Easy Unlock. 310 */ 311 showEasyUnlockBubble: function() { 312 $('pod-row').showEasyUnlockBubble(); 313 } 314 }; 315 }); 316 317