Commit caba515e authored by Kyle Horimoto's avatar Kyle Horimoto Committed by Commit Bot

[CrOS MultiDevice] Remove UiMode in favor of MultiDeviceSetupDelegate.

Before this CL, the <multidevice-setup> element was told what "UI mode"
(i.e., OOBE vs. post-OOBE) and behaved differently depending on what
mode was active. This abstraction was leaky, since it caused the element
to change its logic based on what its client at a higher level was.

This CL adds a MultiDeviceSetupDelegate interface and injects this
interface into the <multidevice-setup> element, which uses it to perform
tasks such as setting the host device. One concrete implementation of
this interface is provided for the post-OOBE case; a future CL will add
an implementation for OOBE.

This CL also removes multidevice_setup_dialog.js in favor of adding a
new <multidevice-setup-post-oobe> element.

Bug: 884058
Change-Id: I76b6553928e706da4870339d306bc32bea7ac3e6
Reviewed-on: https://chromium-review.googlesource.com/1247525Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Reviewed-by: default avatarRyan Hansberry <hansberry@chromium.org>
Commit-Queue: Kyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#595258}
parent ef5f45ae
......@@ -6,14 +6,34 @@ import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [
":multidevice_setup_dialog",
":multidevice_setup_post_oobe",
":post_oobe_delegate",
]
}
js_library("multidevice_setup_dialog") {
js_library("multidevice_setup_post_oobe") {
deps = [
"//ui/webui/resources/cr_components/chromeos/multidevice_setup:multidevice_setup",
"//ui/webui/resources/cr_components/chromeos/multidevice_setup:ui_mode",
"//ui/webui/resources/js:util",
":post_oobe_delegate",
]
}
js_library("post_oobe_delegate") {
deps = [
"//ui/webui/resources/cr_components/chromeos/multidevice_setup:mojo_api",
"//ui/webui/resources/cr_components/chromeos/multidevice_setup:multidevice_setup_delegate",
"//ui/webui/resources/js:cr",
]
extra_deps = [
"//chromeos/services/device_sync/public/mojom:mojom_js",
"//chromeos/services/multidevice_setup/public/mojom:mojom_js",
"//mojo/public/mojom/base:base_js",
]
externs_list = [
"$root_gen_dir/chromeos/services/device_sync/public/mojom/device_sync.mojom.externs.js",
"$root_gen_dir/chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.externs.js",
"$root_gen_dir/mojo/public/mojom/base/time.mojom.externs.js",
"$externs_path/mojo.js",
]
}
......@@ -16,13 +16,11 @@
</style>
</head>
<body>
<multidevice-setup id="main-element"></multidevice-setup>
<link rel="stylesheet" href="chrome://resources/css/md_colors.css">
<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
<link rel="import" href="chrome://resources/html/util.html">
<link rel="import" href="i18n_setup.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/ui_mode.html">
<link rel="import" href="multidevice_setup_post_oobe.html">
<multidevice-setup-post-oobe id="main-element"></multidevice-setup-post-oobe>
</body>
<script src="multidevice_setup_dialog.js"></script>
</html>
// Copyright 2018 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.
function closeUi() {
console.log('Closing Unified MultiDevice Setup WebUI');
chrome.send('dialogClose');
}
$('main-element').uiMode = multidevice_setup.UiMode.POST_OOBE;
$('main-element').addEventListener('setup-exited', () => closeUi());
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/multidevice_setup_shared_css.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html">
<link rel="import" href="post_oobe_delegate.html">
<dom-module id="multidevice-setup-post-oobe">
<template>
<style include="multidevice-setup-shared"></style>
<multidevice-setup delegate="[[delegate_]]"
on-setup-exited="onExitRequested_">
</multidevice-setup>
</template>
<script src="multidevice_setup_post_oobe.js">
</script>
</dom-module>
// Copyright 2018 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.
/**
* MultiDevice setup flow which is shown after OOBE has completed.
*/
Polymer({
is: 'multidevice-setup-post-oobe',
properties: {
/** @private {!multidevice_setup.MultiDeviceSetupDelegate} */
delegate_: Object,
},
/** @override */
attached: function() {
this.delegate_ = new multidevice_setup.PostOobeDelegate();
},
/** @private */
onExitRequested_: function() {
chrome.send('dialogClose');
},
});
......@@ -20,8 +20,17 @@
flattenhtml="true"
allowexternalscript="true"
type="chrome_html" />
<structure name="IDR_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_DIALOG_JS"
file="multidevice_setup_dialog.js"
<structure name="IDR_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_POST_OOBE_HTML"
file="multidevice_setup_post_oobe.html"
type="chrome_html" />
<structure name="IDR_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_POST_OOBE_JS"
file="multidevice_setup_post_oobe.js"
type="chrome_html" />
<structure name="IDR_MULTIDEVICE_SETUP_POST_OOBE_DELEGATE_HTML"
file="post_oobe_delegate.html"
type="chrome_html" />
<structure name="IDR_MULTIDEVICE_SETUP_POST_OOBE_DELEGATE_JS"
file="post_oobe_delegate.js"
type="chrome_html" />
</structures>
</release>
......
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/mojo_api.html">
<script src="post_oobe_delegate.js"></script>
// Copyright 2018 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.
cr.define('multidevice_setup', function() {
/** @implements {multidevice_setup.MultiDeviceSetupDelegate} */
class PostOobeDelegate {
/** @override */
isPasswordRequiredToSetHost() {
return true;
}
/** @override */
setHostDevice(hostDeviceId, opt_authToken) {
// An authentication token is required to set the host device post-OOBE.
assert(!!opt_authToken);
// Note: A cast is needed here because currently all Mojo functions which
// return a promise are typed only as {Promise}. The setHostDevice()
// function always returns a {!Promise<{success: boolean}>} (see
// multidevice_setup.mojom).
return /** @type {!Promise<{success: boolean}>} */ (
multidevice_setup.MojoInterfaceProviderImpl.getInstance()
.getInterfacePtr()
.setHostDevice(hostDeviceId, opt_authToken));
}
/** @override */
shouldExitSetupFlowAfterSettingHost() {
return false;
}
}
return {
PostOobeDelegate: PostOobeDelegate,
};
});
......@@ -4,6 +4,47 @@
/** @fileoverview Suite of integration tests for MultiDevice setup WebUI. */
cr.define('multidevice_setup', () => {
/** @implements {multidevice_setup.MultiDeviceSetupDelegate} */
class FakeDelegate {
constructor() {
/** @private {boolean} */
this.isPasswordRequiredToSetHost_ = true;
/** @private {boolean} */
this.shouldSetHostSucceed_ = true;
}
set isPasswordRequired(isPasswordRequired) {
this.isPasswordRequiredToSetHost_ = isPasswordRequired;
}
/** @override */
isPasswordRequiredToSetHost() {
return this.isPasswordRequiredToSetHost_;
}
set shouldSetHostSucceed(shouldSetHostSucceed) {
this.shouldSetHostSucceed_ = shouldSetHostSucceed;
}
/** @override */
setHostDevice(hostDeviceId, opt_authToken) {
return new Promise((resolve) => {
resolve({success: this.shouldSetHostSucceed_});
});
}
set shouldExitSetupFlowAfterHostSet(shouldExitSetupFlowAfterHostSet) {
this.shouldExitSetupFlowAfterSettingHost_ =
shouldExitSetupFlowAfterHostSet;
}
/** @override */
shouldExitSetupFlowAfterSettingHost() {
return this.shouldExitSetupFlowAfterSettingHost_;
}
}
function registerIntegrationTests() {
suite('MultiDeviceSetup', () => {
/**
......@@ -30,8 +71,8 @@ cr.define('multidevice_setup', () => {
setup(() => {
multiDeviceSetupElement = document.createElement('multidevice-setup');
multiDeviceSetupElement.delegate = new FakeDelegate();
multiDeviceSetupElement.multideviceSetup_ = new FakeMojoService();
multiDeviceSetupElement.uiMode = multidevice_setup.UiMode.POST_OOBE;
document.body.appendChild(multiDeviceSetupElement);
forwardButton = multiDeviceSetupElement.$$('button-bar').$$('#forward');
......@@ -39,6 +80,13 @@ cr.define('multidevice_setup', () => {
multiDeviceSetupElement.$$('button-bar').$$('#backward');
});
/** @param {boolean} isOobeMode */
function setMode(isOobeMode) {
multiDeviceSetupElement.delegate.isPasswordRequired = !isOobeMode;
multiDeviceSetupElement.delegate.shouldExitSetupFlowAfterHostSet =
isOobeMode;
}
/** @param {string} visiblePageName */
function setVisiblePage(visiblePageName) {
multiDeviceSetupElement.visiblePageName_ = visiblePageName;
......@@ -65,9 +113,9 @@ cr.define('multidevice_setup', () => {
done();
});
setMode(true /* isOobeMode */);
setVisiblePage(START);
multiDeviceSetupElement.multideviceSetup_.shouldSetHostSucceed = true;
multiDeviceSetupElement.uiMode = multidevice_setup.UiMode.OOBE;
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
backwardButton.click();
});
......@@ -76,16 +124,13 @@ cr.define('multidevice_setup', () => {
'StartSetupPage forward button sets host in background and ' +
'goes to PasswordPage (OOBE).',
done => {
multiDeviceSetupElement.addEventListener(
'visible-page-name_-changed', () => {
if (multiDeviceSetupElement.visiblePageName_ == PASSWORD)
done();
});
multiDeviceSetupElement.addEventListener('setup-exited', () => {
done();
});
setMode(true /* isOobeMode */);
setVisiblePage(START);
multiDeviceSetupElement.multideviceSetup_.shouldSetHostSucceed =
true;
multiDeviceSetupElement.uiMode = multidevice_setup.UiMode.OOBE;
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
multiDeviceSetupElement.async(() => {
forwardButton.click();
......@@ -97,9 +142,9 @@ cr.define('multidevice_setup', () => {
test('StartSetupPage backward button closes UI (post-OOBE)', done => {
multiDeviceSetupElement.addEventListener('setup-exited', () => done());
setMode(false /* isOobeMode */);
setVisiblePage(START);
multiDeviceSetupElement.multideviceSetup_.shouldSetHostSucceed = true;
multiDeviceSetupElement.uiMode = multidevice_setup.UiMode.POST_OOBE;
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
backwardButton.click();
});
......@@ -107,9 +152,9 @@ cr.define('multidevice_setup', () => {
test('PasswordPage backward button closes UI (post-OOBE)', done => {
multiDeviceSetupElement.addEventListener('setup-exited', () => done());
setMode(false /* isOobeMode */);
setVisiblePage(PASSWORD);
multiDeviceSetupElement.multideviceSetup_.shouldSetHostSucceed = true;
multiDeviceSetupElement.uiMode = multidevice_setup.UiMode.POST_OOBE;
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
backwardButton.click();
});
......@@ -124,10 +169,9 @@ cr.define('multidevice_setup', () => {
done();
});
setMode(false /* isOobeMode */);
setVisiblePage(PASSWORD);
multiDeviceSetupElement.multideviceSetup_.shouldSetHostSucceed =
true;
multiDeviceSetupElement.uiMode = multidevice_setup.UiMode.POST_OOBE;
multiDeviceSetupElement.delegate.shouldSetHostSucceed = true;
multiDeviceSetupElement.async(() => {
forwardButton.click();
......
......@@ -13,20 +13,14 @@ js_type_check("closure_compile") {
":mojo_api",
":multidevice_setup",
":multidevice_setup_browser_proxy",
":multidevice_setup_delegate",
":setup_failed_page",
":setup_succeeded_page",
":start_setup_page",
":ui_mode",
":ui_page_container_behavior",
]
}
js_library("multidevice_setup_browser_proxy") {
deps = [
"//ui/webui/resources/js:cr",
]
}
js_library("button_bar") {
}
......@@ -50,6 +44,9 @@ js_library("fake_mojo_service") {
}
js_library("mojo_api") {
deps = [
"//ui/webui/resources/js:cr",
]
}
js_library("multidevice_setup") {
......@@ -57,11 +54,11 @@ js_library("multidevice_setup") {
":button_bar",
":fake_mojo_service",
":mojo_api",
":multidevice_setup_delegate",
":password_page",
":setup_failed_page",
":setup_succeeded_page",
":start_setup_page",
":ui_mode",
"//ui/webui/resources/js:cr",
]
......@@ -79,6 +76,18 @@ js_library("multidevice_setup") {
]
}
js_library("multidevice_setup_browser_proxy") {
deps = [
"//ui/webui/resources/js:cr",
]
}
js_library("multidevice_setup_delegate") {
deps = [
"//ui/webui/resources/js:cr",
]
}
js_library("password_page") {
deps = [
":multidevice_setup_browser_proxy",
......@@ -109,12 +118,6 @@ js_library("start_setup_page") {
]
}
js_library("ui_mode") {
deps = [
"//ui/webui/resources/js:cr",
]
}
js_library("ui_page_container_behavior") {
deps = [
"//ui/webui/resources/js:cr",
......
......@@ -3,12 +3,12 @@
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/button_bar.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/fake_mojo_service.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/mojo_api.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/multidevice_setup_delegate.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/multidevice_setup_shared_css.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/password_page.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/setup_failed_page.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/setup_succeeded_page.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/start_setup_page.html">
<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/ui_mode.html">
<link rel="import" href="chrome://resources/html/cr.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html">
......@@ -35,14 +35,19 @@
<iron-pages attr-for-selected="is"
selected="[[visiblePageName_]]"
selected-item="{{visiblePage_}}">
<password-page id="passwordPage"
auth-token="{{authToken_}}"
forward-button-disabled="{{passwordPageForwardButtonDisabled_}}"
password-field-valid="{{passwordFieldValid}}"
on-user-submitted-password="onUserSubmittedPassword_">
</password-page>
<template is="dom-if" if="[[shouldPasswordPageBeIncluded_(delegate)]]"
restamp>
<password-page auth-token="{{authToken_}}"
forward-button-disabled="{{passwordPageForwardButtonDisabled_}}"
password-field-valid="{{passwordFieldValid}}"
on-user-submitted-password="onUserSubmittedPassword_">
</password-page>
</template>
<setup-failed-page></setup-failed-page>
<setup-succeeded-page></setup-succeeded-page>
<template is="dom-if"
if="[[shouldSetupSucceededPageBeIncluded_(delegate)]]" restamp>
<setup-succeeded-page></setup-succeeded-page>
</template>
<start-setup-page devices="[[devices_]]"
selected-device-id="{{selectedDeviceId_}}">
</start-setup-page>
......
......@@ -20,11 +20,10 @@ cr.define('multidevice_setup', function() {
properties: {
/**
* Indicates whether UI was opened during OOBE flow or afterward.
*
* @type {!multidevice_setup.UiMode}
* Delegate object which performs differently in OOBE vs. non-OOBE mode.
* @type {!multidevice_setup.MultiDeviceSetupDelegate}
*/
uiMode: Number,
delegate: Object,
/**
* Element name of the currently visible page.
......@@ -34,8 +33,7 @@ cr.define('multidevice_setup', function() {
visiblePageName_: {
type: String,
value: PageName.START,
// For testing purporses only
notify: true,
notify: true, // For testing purporses only.
},
/**
......@@ -145,39 +143,46 @@ cr.define('multidevice_setup', function() {
this.visiblePageName_ = PageName.START;
return;
case PageName.PASSWORD:
this.$.passwordPage.clearPasswordTextInput();
let deviceId = /** @type {string} */ (this.selectedDeviceId_);
this.multideviceSetup_.setHostDevice(deviceId, this.authToken_)
.then((responseParams) => {
if (!responseParams.success) {
console.warn(
'Failure setting device with device ID: ' +
this.selectedDeviceId_);
return;
}
switch (this.uiMode) {
case multidevice_setup.UiMode.OOBE:
this.exitSetupFlow_();
return;
case multidevice_setup.UiMode.POST_OOBE:
this.visiblePageName_ = PageName.SUCCESS;
return;
}
})
.catch((error) => {
console.warn('Mojo service failure: ' + error);
});
this.$$('password-page').clearPasswordTextInput();
this.setHostDevice_();
return;
case PageName.SUCCESS:
this.exitSetupFlow_();
return;
case PageName.START:
this.visiblePageName_ = PageName.PASSWORD;
if (this.delegate.isPasswordRequiredToSetHost())
this.visiblePageName_ = PageName.PASSWORD;
else
this.setHostDevice_();
return;
}
},
/** @private */
setHostDevice_: function() {
// An authentication token must be set if a password is required.
assert(this.delegate.isPasswordRequiredToSetHost() == !!this.authToken_);
let deviceId = /** @type {string} */ (this.selectedDeviceId_);
this.delegate.setHostDevice(deviceId, this.authToken_)
.then((responseParams) => {
if (!responseParams.success) {
console.warn('Failure setting host with device ID: ' + deviceId);
return;
}
if (this.delegate.shouldExitSetupFlowAfterSettingHost()) {
this.exitSetupFlow_();
return;
}
this.visiblePageName_ = PageName.SUCCESS;
})
.catch((error) => {
console.warn('Mojo service failure: ' + error);
});
},
/** @private */
onUserSubmittedPassword_: function() {
this.onForwardNavigationRequested_();
......@@ -192,13 +197,28 @@ cr.define('multidevice_setup', function() {
this.passwordPageForwardButtonDisabled_;
},
/**
* @return {boolean}
* @private
*/
shouldPasswordPageBeIncluded_: function() {
return this.delegate.isPasswordRequiredToSetHost();
},
/**
* @return {boolean}
* @private
*/
shouldSetupSucceededPageBeIncluded_: function() {
return !this.delegate.shouldExitSetupFlowAfterSettingHost();
},
/**
* Notifies observers that the setup flow has completed.
*
* @private
*/
exitSetupFlow_: function() {
console.log('Exiting Setup Flow');
this.fire('setup-exited');
},
});
......
<link rel="import" href="chrome://resources/html/cr.html">
<script src="chrome://resources/cr_components/chromeos/multidevice_setup/ui_mode.js">
<script src="chrome://resources/cr_components/chromeos/multidevice_setup/multidevice_setup_delegate.js">
</script>
// Copyright 2018 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.
cr.define('multidevice_setup', function() {
/**
* Interface which provides the ability to set the host device and perform
* related logic.
* @interface
*/
class MultiDeviceSetupDelegate {
/** @return {boolean} */
isPasswordRequiredToSetHost() {}
/**
* @param {string} hostDeviceId The ID of the host to set.
* @param {string=} opt_authToken An auth token to authenticate the request;
* only necessary if isPasswordRequiredToSetHost() returns true.
* @return {!Promise<{success: boolean}>}
*/
setHostDevice(hostDeviceId, opt_authToken) {}
/** @return {boolean} */
shouldExitSetupFlowAfterSettingHost() {}
}
return {
MultiDeviceSetupDelegate: MultiDeviceSetupDelegate,
};
});
// Copyright 2018 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.
cr.define('multidevice_setup', function() {
/** @enum {number} */
const UiMode = {
OOBE: 1,
POST_OOBE: 2,
};
return {
UiMode: UiMode,
};
});
......@@ -280,6 +280,14 @@
file="cr_components/chromeos/multidevice_setup/multidevice_setup.js"
type="chrome_html"
compress="gzip" />
<structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_DELEGATE_HTML"
file="cr_components/chromeos/multidevice_setup/multidevice_setup_delegate.html"
type="chrome_html"
compress="gzip" />
<structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_DELEGATE_JS"
file="cr_components/chromeos/multidevice_setup/multidevice_setup_delegate.js"
type="chrome_html"
compress="gzip" />
<structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_SHARED_CSS_HTML"
file="cr_components/chromeos/multidevice_setup/multidevice_setup_shared_css.html"
type="chrome_html"
......@@ -316,14 +324,6 @@
file="cr_components/chromeos/multidevice_setup/start_setup_page.js"
type="chrome_html"
compress="gzip" />
<structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_UI_MODE_HTML"
file="cr_components/chromeos/multidevice_setup/ui_mode.html"
type="chrome_html"
compress="gzip" />
<structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_UI_MODE_JS"
file="cr_components/chromeos/multidevice_setup/ui_mode.js"
type="chrome_html"
compress="gzip" />
<structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_UI_PAGE_CONTAINER_BEHAVIOR_HTML"
file="cr_components/chromeos/multidevice_setup/ui_page_container_behavior.html"
type="chrome_html"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment