blob: a143d1d57471d48a7e849ffb8981a475387a8a45 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview Common OOBE controller methods for use in OOBE and login.
* This file is shared between OOBE and login. Add only methods that need to be
* shared between all *two* screens here.
*/
cr.define('cr.ui', function() {
var DisplayManager = cr.ui.login.DisplayManager;
/**
* Constructs an Out of box controller. It manages initialization of screens,
* transitions, error messages display.
* @extends {DisplayManager}
* @constructor
*/
function Oobe() {}
/**
* Delay in milliseconds between start of OOBE animation and start of
* header bar animation.
*/
var HEADER_BAR_DELAY_MS = 300;
cr.addSingletonGetter(Oobe);
Oobe.prototype = {
__proto__: DisplayManager.prototype,
};
/**
* Called when focus is returned from ash::SystemTray.
*/
Oobe.focusReturned = function() {
if (Oobe.getInstance().currentScreen &&
Oobe.getInstance().currentScreen.onFocusReturned) {
Oobe.getInstance().currentScreen.onFocusReturned();
}
};
/**
* Handle accelerators. These are passed from native code instead of a JS
* event handler in order to make sure that embedded iframes cannot swallow
* them.
* @param {string} name Accelerator name.
*/
Oobe.handleAccelerator = function(name) {
Oobe.getInstance().handleAccelerator(name);
};
/**
* Shows the given screen.
* @param {Object} screen Screen params dict, e.g. {id: screenId, data: data}
*/
Oobe.showScreen = function(screen) {
Oobe.getInstance().showScreen(screen);
};
/**
* Updates missin API keys message visibility.
* @param {boolean} show True if the message should be visible.
*/
Oobe.showAPIKeysNotice = function(show) {
$('api-keys-notice-container').hidden = !show;
};
/**
* Updates version label visibility.
* @param {boolean} show True if version label should be visible.
*/
Oobe.showVersion = function(show) {
Oobe.getInstance().showVersion(show);
};
/**
* Update body class to switch between OOBE UI and Login UI.
*/
Oobe.showOobeUI = function(showOobe) {
if (showOobe) {
document.body.classList.add('oobe-display');
// Callback to animate the header bar in.
var showHeaderBar = function() {
login.HeaderBar.animateIn(false, function() {
chrome.send('headerBarVisible');
});
};
// Start asynchronously so the OOBE welcome screen comes in first.
window.setTimeout(showHeaderBar, HEADER_BAR_DELAY_MS);
} else {
document.body.classList.remove('oobe-display');
Oobe.getInstance().prepareForLoginDisplay_();
// Ensure header bar is visible when switching to Login UI from oobe.
if (Oobe.getInstance().displayType == DISPLAY_TYPE.OOBE)
login.HeaderBar.animateIn(true);
}
Oobe.getInstance().headerHidden = false;
};
/**
* When |showShutdown| is set to "true", the shutdown button is shown and the
* reboot button hidden. If set to "false", the reboot button is visible and
* the shutdown button hidden.
*/
Oobe.showShutdown = function(showShutdown) {
$('login-header-bar').showShutdownButton = showShutdown;
$('login-header-bar').showRebootButton = !showShutdown;
};
/**
* Enables keyboard driven flow.
*/
Oobe.enableKeyboardFlow = function(value) {
// Don't show header bar for OOBE.
Oobe.getInstance().forceKeyboardFlow = value;
};
/**
* Disables signin UI.
*/
Oobe.disableSigninUI = function() {
DisplayManager.disableSigninUI();
};
/**
* Shows signin UI.
* @param {string} opt_email An optional email for signin UI.
*/
Oobe.showSigninUI = function(opt_email) {
DisplayManager.showSigninUI(opt_email);
};
/**
* Resets sign-in input fields.
* @param {boolean} forceOnline Whether online sign-in should be forced.
* If |forceOnline| is false previously used sign-in type will be used.
*/
Oobe.resetSigninUI = function(forceOnline) {
DisplayManager.resetSigninUI(forceOnline);
};
/**
* Shows sign-in error bubble.
* @param {number} loginAttempts Number of login attemps tried.
* @param {string} message Error message to show.
* @param {string} link Text to use for help link.
* @param {number} helpId Help topic Id associated with help link.
*/
Oobe.showSignInError = function(loginAttempts, message, link, helpId) {
DisplayManager.showSignInError(loginAttempts, message, link, helpId);
};
/**
* Shows password changed screen that offers migration.
* @param {boolean} showError Whether to show the incorrect password error.
*/
Oobe.showPasswordChangedScreen = function(showError, email) {
DisplayManager.showPasswordChangedScreen(showError, email);
};
/**
* Shows TPM error screen.
*/
Oobe.showTpmError = function() {
DisplayManager.showTpmError();
};
/**
* Shows Active Directory password change screen.
* @param {string} username Name of the user that should change the password.
*/
Oobe.showActiveDirectoryPasswordChangeScreen = function(username) {
DisplayManager.showActiveDirectoryPasswordChangeScreen(username);
};
/**
* Show user-pods.
*/
Oobe.showUserPods = function() {
$('pod-row').maybePreselectPod();
Oobe.showScreen({id: SCREEN_ACCOUNT_PICKER});
Oobe.resetSigninUI(true);
};
/**
* Clears error bubble.
*/
Oobe.clearErrors = function() {
DisplayManager.clearErrors();
};
/**
* Sets text content for a div with |labelId|.
* @param {string} labelId Id of the label div.
* @param {string} labelText Text for the label.
*/
Oobe.setLabelText = function(labelId, labelText) {
DisplayManager.setLabelText(labelId, labelText);
};
/**
* Sets the text content of the enterprise info message.
* If the text is empty, the entire notification will be hidden.
* @param {string} messageText The message text.
*/
Oobe.setEnterpriseInfo = function(messageText, assetId) {
DisplayManager.setEnterpriseInfo(messageText, assetId);
};
/**
* Sets the text content of the Bluetooth device info message.
* @param {string} bluetoothName The Bluetooth device name text.
*/
Oobe.setBluetoothDeviceInfo = function(bluetoothName) {
DisplayManager.setBluetoothDeviceInfo(bluetoothName);
};
/**
* Updates the device requisition string shown in the requisition prompt.
* @param {string} requisition The device requisition.
*/
Oobe.updateDeviceRequisition = function(requisition) {
Oobe.getInstance().updateDeviceRequisition(requisition);
};
/**
* Clears password field in user-pod.
*/
Oobe.clearUserPodPassword = function() {
DisplayManager.clearUserPodPassword();
};
/**
* Restores input focus to currently selected pod.
*/
Oobe.refocusCurrentPod = function() {
DisplayManager.refocusCurrentPod();
};
/**
* Some ForTesting APIs directly access to DOM. Because this script is loaded
* in header, DOM tree may not be available at beginning.
* In DOMContentLoaded, after Oobe.initialize() is done, this is marked to
* true, indicating ForTesting methods can be called.
* External script using ForTesting APIs should wait for this condition.
* @type {boolean}
*/
Oobe.readyForTesting = false;
/**
* Skip to login screen for telemetry.
*/
Oobe.skipToLoginForTesting = function() {
Oobe.disableSigninUI();
chrome.send('skipToLoginForTesting');
};
/**
* Skip to update screen for telemetry.
*/
Oobe.skipToUpdateForTesting = function() {
Oobe.disableSigninUI();
chrome.send('skipToUpdateForTesting');
};
/**
* Login for telemetry.
* @param {string} username Login username.
* @param {string} password Login password.
* @param {boolean} enterpriseEnroll Login as an enterprise enrollment?
*/
Oobe.loginForTesting = function(
username, password, gaia_id, enterpriseEnroll = false) {
// Helper method that runs |fn| after |screenName| is visible.
function waitForOobeScreen(screenName, fn) {
if (Oobe.getInstance().currentScreen &&
Oobe.getInstance().currentScreen.id === screenName) {
fn();
} else {
$('oobe').addEventListener('screenchanged', function handler(e) {
if (e.detail == screenName) {
$('oobe').removeEventListener('screenchanged', handler);
fn();
}
});
}
}
Oobe.disableSigninUI();
chrome.send('skipToLoginForTesting', [username]);
if (!enterpriseEnroll) {
chrome.send('completeLogin', [gaia_id, username, password, false]);
} else {
waitForOobeScreen('gaia-signin', function() {
chrome.send('toggleEnrollmentScreen');
chrome.send('toggleFakeEnrollment');
});
waitForOobeScreen('oauth-enrollment', function() {
chrome.send('oauthEnrollCompleteLogin', [username]);
});
}
};
/**
* Guest login for telemetry.
*/
Oobe.guestLoginForTesting = function() {
Oobe.skipToLoginForTesting();
chrome.send('launchIncognito');
};
/**
* Authenticate for telemetry - used for screenlocker.
* @param {string} username Login username.
* @param {string} password Login password.
*/
Oobe.authenticateForTesting = function(username, password) {
Oobe.disableSigninUI();
chrome.send('authenticateUser', [username, password, false]);
};
/**
* Gaia login screen for telemetry.
*/
Oobe.addUserForTesting = function() {
Oobe.skipToLoginForTesting();
chrome.send('addUser');
};
/**
* Shows the add user dialog. Used in browser tests.
*/
Oobe.showAddUserForTesting = function() {
chrome.send('showAddUser');
};
/**
* Hotrod requisition for telemetry.
*/
Oobe.remoraRequisitionForTesting = function() {
chrome.send('setDeviceRequisition', ['remora']);
};
/**
* Begin enterprise enrollment for telemetry.
*/
Oobe.switchToEnterpriseEnrollmentForTesting = function() {
chrome.send('toggleEnrollmentScreen');
};
/**
* Finish enterprise enrollment for telemetry.
*/
Oobe.enterpriseEnrollmentDone = function() {
chrome.send('oauthEnrollClose', ['done']);
};
/**
* Returns true if enrollment was successful. Dismisses the enrollment
* attribute screen if it's present.
*/
Oobe.isEnrollmentSuccessfulForTest = function() {
if (document.querySelector('.oauth-enroll-state-attribute-prompt'))
chrome.send('oauthEnrollAttributes', ['', '']);
return $('oauth-enrollment')
.classList.contains('oauth-enroll-state-success');
};
/**
* Starts online demo mode setup for telemetry.
*/
Oobe.setUpOnlineDemoModeForTesting = function() {
DemoModeTestHelper.setUp('online');
};
/**
* Shows/hides login UI control bar with buttons like [Shut down].
*/
Oobe.showControlBar = function(show) {
Oobe.getInstance().headerHidden = !show;
};
/**
* Changes some UI which depends on the virtual keyboard being shown/hidden.
*/
Oobe.setVirtualKeyboardShown = function(shown) {
Oobe.getInstance().virtualKeyboardShown = shown;
$('pod-row').setFocusedPodPinVisibility(!shown);
};
/**
* Sets the current size of the client area (display size).
* @param {number} width client area width
* @param {number} height client area height
*/
Oobe.setClientAreaSize = function(width, height) {
Oobe.getInstance().setClientAreaSize(width, height);
};
/**
* Get the primary display's name.
*
* Same as the displayInfo.name parameter returned by
* chrome.system.display.getInfo(), but unlike chrome.system it's available
* during OOBE.
*
* @return {string} The name of the primary display.
*/
Oobe.getPrimaryDisplayNameForTesting = function() {
return cr.sendWithPromise('getPrimaryDisplayNameForTesting');
};
/**
* Sets the number of users on the views login screen.
* @param {number} userCount The number of users.
*/
Oobe.setLoginUserCount = function(userCount) {
Oobe.getInstance().setLoginUserCount(userCount);
};
// Export
return {Oobe: Oobe};
});
var Oobe = cr.ui.Oobe;
// Allow selection events on components with editable text (password field)
// bug (http://code.google.com/p/chromium/issues/detail?id=125863)
disableTextSelectAndDrag(function(e) {
var src = e.target;
return src instanceof HTMLTextAreaElement ||
src instanceof HTMLInputElement && /text|password|search/.test(src.type);
});
(function() {
'use strict';
document.addEventListener('DOMContentLoaded', function() {
try {
Oobe.initialize();
} finally {
// TODO(crbug.com/712078): Do not set readyForTesting in case of that
// initialize() is failed. Currently, in some situation, initialize()
// raises an exception unexpectedly. It means testing APIs should not
// be called then. However, checking it here now causes bots failures
// unfortunately. So, as a short term workaround, here set
// readyForTesting even on failures, just to make test bots happy.
Oobe.readyForTesting = true;
}
});
// Install a global error handler so stack traces are included in logs.
window.onerror = function(message, file, line, column, error) {
console.error(error.stack);
};
})();