Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ui / login / account_picker / screen_account_picker.js
blob7f7635d7c96ed31de2f72465834824375670b05b
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.
5 /**
6  * @fileoverview Account picker screen implementation.
7  */
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;
17   return {
18     EXTERNAL_API: [
19       'loadUsers',
20       'runAppForTesting',
21       'setApps',
22       'setShouldShowApps',
23       'showAppError',
24       'updateUserImage',
25       'setCapsLockState',
26       'forceLockedUserPodFocus',
27       'removeUser',
28       'showBannerMessage',
29       'showUserPodCustomIcon',
30       'hideUserPodCustomIcon',
31       'setAuthType',
32       'setTouchViewState',
33       'setPublicSessionDisplayName',
34       'setPublicSessionLocales',
35       'setPublicSessionKeyboardLayouts',
36     ],
38     preferredWidth_: 0,
39     preferredHeight_: 0,
41     // Whether this screen is shown for the first time.
42     firstShown_: true,
44     // Whether this screen is currently being shown.
45     showing_: false,
47     /** @override */
48     decorate: function() {
49       login.PodRow.decorate($('pod-row'));
50     },
52     /** @override */
53     getPreferredSize: function() {
54       return {width: this.preferredWidth_, height: this.preferredHeight_};
55     },
57     /** @override */
58     onWindowResize: function() {
59       $('pod-row').onWindowResize();
61       // Reposition the error bubble, if it is showing. Since we are just
62       // moving the bubble, the number of login attempts tried doesn't matter.
63       var errorBubble = $('bubble');
64       if (errorBubble && !errorBubble.hidden)
65         this.showErrorBubble(0, undefined  /* Reuses the existing message. */);
66     },
68     /**
69      * Sets preferred size for account picker screen.
70      */
71     setPreferredSize: function(width, height) {
72       this.preferredWidth_ = width;
73       this.preferredHeight_ = height;
74     },
76     /**
77      * When the account picker is being used to lock the screen, pressing the
78      * exit accelerator key will sign out the active user as it would when
79      * they are signed in.
80      */
81     exit: function() {
82       // Check and disable the sign out button so that we can never have two
83       // sign out requests generated in a row.
84       if ($('pod-row').lockedPod && !$('sign-out-user-button').disabled) {
85         $('sign-out-user-button').disabled = true;
86         chrome.send('signOutUser');
87       }
88     },
90     /* Cancel user adding if ESC was pressed.
91      */
92     cancel: function() {
93       if (Oobe.getInstance().displayType == DISPLAY_TYPE.USER_ADDING)
94         chrome.send('cancelUserAdding');
95     },
97     /**
98      * Event handler that is invoked just after the frame is shown.
99      * @param {string} data Screen init payload.
100      */
101     onAfterShow: function(data) {
102       $('pod-row').handleAfterShow();
103     },
105     /**
106      * Event handler that is invoked just before the frame is shown.
107      * @param {string} data Screen init payload.
108      */
109     onBeforeShow: function(data) {
110       this.showing_ = true;
111       chrome.send('loginUIStateChanged', ['account-picker', true]);
112       $('login-header-bar').signinUIState = SIGNIN_UI_STATE.ACCOUNT_PICKER;
113       chrome.send('hideCaptivePortal');
114       var podRow = $('pod-row');
115       podRow.handleBeforeShow();
117       // In case of the preselected pod onShow will be called once pod
118       // receives focus.
119       if (!podRow.preselectedPod)
120         this.onShow();
121     },
123     /**
124      * Event handler invoked when the page is shown and ready.
125      */
126     onShow: function() {
127       if (!this.showing_) {
128         // This method may be called asynchronously when the pod row finishes
129         // initializing. However, at that point, the screen may have been hidden
130         // again already. If that happens, ignore the onShow() call.
131         return;
132       }
133       chrome.send('getTouchViewState');
134       if (!this.firstShown_) return;
135       this.firstShown_ = false;
137       // Ensure that login is actually visible.
138       window.requestAnimationFrame(function() {
139         chrome.send('accountPickerReady');
140         chrome.send('loginVisible', ['account-picker']);
141       });
142     },
144     /**
145      * Event handler that is invoked just before the frame is hidden.
146      */
147     onBeforeHide: function() {
148       this.showing_ = false;
149       chrome.send('loginUIStateChanged', ['account-picker', false]);
150       $('login-header-bar').signinUIState = SIGNIN_UI_STATE.HIDDEN;
151       $('pod-row').handleHide();
152     },
154     /**
155      * Shows sign-in error bubble.
156      * @param {number} loginAttempts Number of login attemps tried.
157      * @param {HTMLElement} content Content to show in bubble.
158      */
159     showErrorBubble: function(loginAttempts, error) {
160       var activatedPod = $('pod-row').activatedPod;
161       if (!activatedPod) {
162         $('bubble').showContentForElement($('pod-row'),
163                                           cr.ui.Bubble.Attachment.RIGHT,
164                                           error);
165         return;
166       }
167       // Show web authentication if this is not a supervised user.
168       if (loginAttempts > MAX_LOGIN_ATTEMPTS_IN_POD &&
169           !activatedPod.user.supervisedUser) {
170         chrome.send('maxIncorrectPasswordAttempts',
171             [activatedPod.user.emailAddress]);
172         activatedPod.showSigninUI();
173       } else {
174         if (loginAttempts == 1) {
175           chrome.send('firstIncorrectPasswordAttempt',
176               [activatedPod.user.emailAddress]);
177         }
178         // We want bubble's arrow to point to the first letter of input.
179         /** @const */ var BUBBLE_OFFSET = 7;
180         /** @const */ var BUBBLE_PADDING = 4;
181         $('bubble').showContentForElement(activatedPod.mainInput,
182                                           cr.ui.Bubble.Attachment.BOTTOM,
183                                           error,
184                                           BUBBLE_OFFSET, BUBBLE_PADDING);
185         // Move error bubble up if it overlaps the shelf.
186         var maxHeight =
187             cr.ui.LoginUITools.getMaxHeightBeforeShelfOverlapping($('bubble'));
188         if (maxHeight < $('bubble').offsetHeight) {
189           $('bubble').showContentForElement(activatedPod.mainInput,
190                                             cr.ui.Bubble.Attachment.TOP,
191                                             error,
192                                             BUBBLE_OFFSET, BUBBLE_PADDING);
193         }
194       }
195     },
197     /**
198      * Loads given users in pod row.
199      * @param {array} users Array of user.
200      * @param {boolean} showGuest Whether to show guest session button.
201      */
202     loadUsers: function(users, showGuest) {
203       $('pod-row').loadPods(users);
204       $('login-header-bar').showGuestButton = showGuest;
205     },
207     /**
208      * Runs app with a given id from the list of loaded apps.
209      * @param {!string} app_id of an app to run.
210      * @param {boolean=} opt_diagnostic_mode Whether to run the app in
211      *     diagnostic mode.  Default is false.
212      */
213     runAppForTesting: function(app_id, opt_diagnostic_mode) {
214       $('pod-row').findAndRunAppForTesting(app_id, opt_diagnostic_mode);
215     },
217     /**
218      * Adds given apps to the pod row.
219      * @param {array} apps Array of apps.
220      */
221     setApps: function(apps) {
222       $('pod-row').setApps(apps);
223     },
225     /**
226      * Sets the flag of whether app pods should be visible.
227      * @param {boolean} shouldShowApps Whether to show app pods.
228      */
229     setShouldShowApps: function(shouldShowApps) {
230       $('pod-row').setShouldShowApps(shouldShowApps);
231     },
233     /**
234      * Shows the given kiosk app error message.
235      * @param {!string} message Error message to show.
236      */
237     showAppError: function(message) {
238       // TODO(nkostylev): Figure out a way to show kiosk app launch error
239       // pointing to the kiosk app pod.
240       /** @const */ var BUBBLE_PADDING = 12;
241       $('bubble').showTextForElement($('pod-row'),
242                                      message,
243                                      cr.ui.Bubble.Attachment.BOTTOM,
244                                      $('pod-row').offsetWidth / 2,
245                                      BUBBLE_PADDING);
246     },
248     /**
249      * Updates current image of a user.
250      * @param {string} username User for which to update the image.
251      */
252     updateUserImage: function(username) {
253       $('pod-row').updateUserImage(username);
254     },
256     /**
257      * Updates Caps Lock state (for Caps Lock hint in password input field).
258      * @param {boolean} enabled Whether Caps Lock is on.
259      */
260     setCapsLockState: function(enabled) {
261       $('pod-row').classList.toggle('capslock-on', enabled);
262     },
264     /**
265      * Enforces focus on user pod of locked user.
266      */
267     forceLockedUserPodFocus: function() {
268       var row = $('pod-row');
269       if (row.lockedPod)
270         row.focusPod(row.lockedPod, true);
271     },
273     /**
274      * Remove given user from pod row if it is there.
275      * @param {string} user name.
276      */
277     removeUser: function(username) {
278       $('pod-row').removeUserPod(username);
279     },
281     /**
282      * Displays a banner containing |message|. If the banner is already present
283      * this function updates the message in the banner. This function is used
284      * by the chrome.screenlockPrivate.showMessage API.
285      * @param {string} message Text to be displayed
286      */
287     showBannerMessage: function(message) {
288       var banner = $('signin-banner');
289       banner.textContent = message;
290       banner.classList.toggle('message-set', true);
291     },
293     /**
294      * Shows a custom icon in the user pod of |username|. This function
295      * is used by the chrome.screenlockPrivate API.
296      * @param {string} username Username of pod to add button
297      * @param {!{id: !string,
298      *           hardlockOnClick: boolean,
299      *           isTrialRun: boolean,
300      *           tooltip: ({text: string, autoshow: boolean} | undefined)}} icon
301      *     The icon parameters.
302      */
303     showUserPodCustomIcon: function(username, icon) {
304       $('pod-row').showUserPodCustomIcon(username, icon);
305     },
307     /**
308      * Hides the custom icon in the user pod of |username| added by
309      * showUserPodCustomIcon(). This function is used by the
310      * chrome.screenlockPrivate API.
311      * @param {string} username Username of pod to remove button
312      */
313     hideUserPodCustomIcon: function(username) {
314       $('pod-row').hideUserPodCustomIcon(username);
315     },
317     /**
318      * Sets the authentication type used to authenticate the user.
319      * @param {string} username Username of selected user
320      * @param {number} authType Authentication type, must be a valid value in
321      *                          the AUTH_TYPE enum in user_pod_row.js.
322      * @param {string} value The initial value to use for authentication.
323      */
324     setAuthType: function(username, authType, value) {
325       $('pod-row').setAuthType(username, authType, value);
326     },
328     /**
329      * Sets the state of touch view mode.
330      * @param {boolean} isTouchViewEnabled true if the mode is on.
331      */
332     setTouchViewState: function(isTouchViewEnabled) {
333       $('pod-row').setTouchViewState(isTouchViewEnabled);
334     },
336     /**
337      * Updates the display name shown on a public session pod.
338      * @param {string} userID The user ID of the public session
339      * @param {string} displayName The new display name
340      */
341     setPublicSessionDisplayName: function(userID, displayName) {
342       $('pod-row').setPublicSessionDisplayName(userID, displayName);
343     },
345     /**
346      * Updates the list of locales available for a public session.
347      * @param {string} userID The user ID of the public session
348      * @param {!Object} locales The list of available locales
349      * @param {string} defaultLocale The locale to select by default
350      * @param {boolean} multipleRecommendedLocales Whether |locales| contains
351      *     two or more recommended locales
352      */
353     setPublicSessionLocales: function(userID,
354                                       locales,
355                                       defaultLocale,
356                                       multipleRecommendedLocales) {
357       $('pod-row').setPublicSessionLocales(userID,
358                                            locales,
359                                            defaultLocale,
360                                            multipleRecommendedLocales);
361     },
363     /**
364      * Updates the list of available keyboard layouts for a public session pod.
365      * @param {string} userID The user ID of the public session
366      * @param {string} locale The locale to which this list of keyboard layouts
367      *     applies
368      * @param {!Object} list List of available keyboard layouts
369      */
370     setPublicSessionKeyboardLayouts: function(userID, locale, list) {
371       $('pod-row').setPublicSessionKeyboardLayouts(userID, locale, list);
372     }
373   };