Commit e6ef7670 authored by Aga Wronska's avatar Aga Wronska Committed by Commit Bot

Invoke demo mode setup with 10 taps on OOBE welcome screen.

Bug: 857515
Test: DemoSetupTest
Change-Id: Iaa3106dacad12855c8c62bcff05bd91c2b6e0a1e
Reviewed-on: https://chromium-review.googlesource.com/1164253
Commit-Queue: Aga Wronska <agawronska@chromium.org>
Reviewed-by: default avatarJacob Dufault <jdufault@chromium.org>
Reviewed-by: default avatarMichael Giuffrida <michaelpg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#583133}
parent a011e05f
......@@ -8,6 +8,8 @@
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time_to_iso8601.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "chrome/browser/chromeos/login/demo_mode/demo_setup_controller.h"
......@@ -240,6 +242,15 @@ class DemoSetupTest : public LoginManagerTest {
EXPECT_TRUE(JSExecute("cr.ui.Oobe.handleAccelerator('demo_mode');"));
}
// Simulates multi-tap gesture that consists of |tapCount| clicks on the OOBE
// outer-container.
void MultiTapOobeContainer(int tapsCount) {
const std::string query = base::StrCat(
{"for (var i = 0; i < ", base::NumberToString(tapsCount), "; ++i)",
"{ document.querySelector('#outer-container').click(); }"});
EXPECT_TRUE(JSExecute(query));
}
void ClickOkOnConfirmationDialog() {
EXPECT_TRUE(JSExecute("document.querySelector('.cr-dialog-ok').click();"));
}
......@@ -415,12 +426,6 @@ class DemoSetupTest : public LoginManagerTest {
base::RunLoop().RunUntilIdle();
}
private:
void DisableConfirmationDialogAnimations() {
EXPECT_TRUE(
JSExecute("cr.ui.dialogs.BaseDialog.ANIMATE_STABLE_DURATION = 0;"));
}
bool JSExecute(const std::string& script) {
return content::ExecuteScript(web_contents(), script);
}
......@@ -429,6 +434,21 @@ class DemoSetupTest : public LoginManagerTest {
content::ExecuteScriptAsync(web_contents(), script);
}
// Sets fake time in MultiTapDetector to remove dependency on real time in
// test environment.
void SetFakeTimeForMultiTapDetector(base::Time fake_time) {
const std::string query =
base::StrCat({"MultiTapDetector.FAKE_TIME_FOR_TESTS = new Date('",
base::TimeToISO8601(fake_time), "');"});
EXPECT_TRUE(JSExecute(query));
}
private:
void DisableConfirmationDialogAnimations() {
EXPECT_TRUE(
JSExecute("cr.ui.dialogs.BaseDialog.ANIMATE_STABLE_DURATION = 0;"));
}
// TODO(agawronska): Maybe create a separate test fixture for offline setup.
base::ScopedTempDir fake_policy_dir_;
policy::MockCloudPolicyStore mock_policy_store_;
......@@ -460,6 +480,33 @@ IN_PROC_BROWSER_TEST_F(DemoSetupTest, ShowConfirmationDialogAndCancel) {
EXPECT_FALSE(IsScreenShown(OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES));
}
IN_PROC_BROWSER_TEST_F(DemoSetupTest, InvokeWithTaps) {
// Use fake time to avoid flakiness.
SetFakeTimeForMultiTapDetector(base::Time::UnixEpoch());
EXPECT_FALSE(IsConfirmationDialogShown());
MultiTapOobeContainer(10);
EXPECT_TRUE(IsConfirmationDialogShown());
}
IN_PROC_BROWSER_TEST_F(DemoSetupTest, DoNotInvokeWithNonConsecutiveTaps) {
// Use fake time to avoid flakiness.
const base::Time kFakeTime = base::Time::UnixEpoch();
SetFakeTimeForMultiTapDetector(kFakeTime);
EXPECT_FALSE(IsConfirmationDialogShown());
MultiTapOobeContainer(5);
EXPECT_FALSE(IsConfirmationDialogShown());
// Advance time to make interval in between taps longer than expected by
// multi-tap gesture detector.
SetFakeTimeForMultiTapDetector(kFakeTime +
base::TimeDelta::FromMilliseconds(500));
MultiTapOobeContainer(5);
EXPECT_FALSE(IsConfirmationDialogShown());
}
IN_PROC_BROWSER_TEST_F(DemoSetupTest, OnlineSetupFlowSuccess) {
// Simulate successful online setup.
EnterpriseEnrollmentHelper::SetupEnrollmentHelperMock(
......
......@@ -178,14 +178,8 @@ WebUILoginView::WebUILoginView(const WebViewSettings& settings)
ui::VKEY_S, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN)] =
kAccelNameBootstrappingSlave;
const bool is_demo_mode_enabled =
base::CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kEnableDemoMode);
if (is_demo_mode_enabled) {
accel_map_[ui::Accelerator(ui::VKEY_D,
ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)] =
kAccelNameDemoMode;
}
accel_map_[ui::Accelerator(
ui::VKEY_D, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)] = kAccelNameDemoMode;
accel_map_[ui::Accelerator(ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN)] =
kAccelSendFeedback;
......
// 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.
/**
* @fileoverview Multi-tap gesture detector for web UI OOBE.
*/
/** Multi-tap gesture detector. */
class MultiTapDetector {
/**
* @param {!Element} element UI element to attach the multi-tap detector to.
* @param {number} tapsCount Number of taps in multi-tap gesture to detect.
* @param {!function()} callback Callback to be called when multi-tap gesture
* is detected.
*/
constructor(element, tapsCount, callback) {
assert(callback);
assert(tapsCount > 0);
assert(element);
/** @private {number} */
this.tapsSeen_ = 0;
/** @private {?Date} */
this.lastTapTime_ = null;
this.callback_ = callback;
this.tapsCount_ = tapsCount;
element.addEventListener('click', this.onTap_.bind(this));
}
/**
* Returns current time or fake time for testing if set.
* @return {!Date}
* @private
*/
getCurrentTime_() {
return MultiTapDetector.FAKE_TIME_FOR_TESTS ?
MultiTapDetector.FAKE_TIME_FOR_TESTS :
new Date();
}
/**
* Handles tap event.
* @private
*/
onTap_() {
let timestamp = this.getCurrentTime_();
if (!this.lastTapTime_ ||
timestamp - this.lastTapTime_ <
MultiTapDetector.IN_BETWEEN_TAPS_TIME_MS) {
this.tapsSeen_++;
if (this.tapsSeen_ >= this.tapsCount_) {
this.tapsSeen_ = 0;
this.callback_();
}
} else {
this.tapsSeen_ = 0;
}
this.lastTapTime_ = timestamp;
}
}
/**
* Time in between taps used to recognize multi-tap gesture.
* @const {number}
*/
MultiTapDetector.IN_BETWEEN_TAPS_TIME_MS = 400;
/**
* Fake time used for testing. If set it will be used instead of the current
* time.
* @const {?Date}
*/
MultiTapDetector.FAKE_TIME_FOR_TESTS = null;
......@@ -20,6 +20,7 @@
// <include src="oobe_screen_network.js">
// <include src="oobe_screen_update.js">
// <include src="oobe_screen_welcome.js">
// <include src="multi_tap_detector.js">
cr.define('cr.ui.Oobe', function() {
return {
......
......@@ -10,6 +10,7 @@
#include "ash/public/interfaces/event_rewriter_controller.mojom.h"
#include "ash/shell.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
......@@ -179,6 +180,9 @@ void CoreOobeHandler::Initialize() {
void CoreOobeHandler::GetAdditionalParameters(base::DictionaryValue* dict) {
dict->SetKey("isInTabletMode",
base::Value(TabletModeClient::Get()->tablet_mode_enabled()));
bool is_demo_mode_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableDemoMode);
dict->SetKey("isDemoModeEnabled", base::Value(is_demo_mode_enabled));
}
void CoreOobeHandler::RegisterMessages() {
......
......@@ -274,6 +274,13 @@ cr.define('cr.ui.login', function() {
*/
oobe_configuration_: {},
/**
* Detects multi-tap gesture that invokes demo mode setup in OOBE.
* @type {?MultiTapDetector}
* @private
*/
demoModeStartListener_: null,
/**
* Error message (bubble) was shown. This is checked in tests.
*/
......@@ -495,10 +502,7 @@ cr.define('cr.ui.login', function() {
} else if (name == ACCELERATOR_BOOTSTRAPPING_SLAVE) {
chrome.send('setOobeBootstrappingSlave');
} else if (name == ACCELERATOR_DEMO_MODE) {
if (DEMO_MODE_SETUP_AVAILABLE_SCREEN_GROUP.indexOf(currentStepId) !=
-1) {
this.showEnableDemoModeDialog_();
}
} else if (name == ACCELERATOR_SEND_FEEDBACK) {
chrome.send('sendFeedback');
}
......@@ -896,6 +900,14 @@ cr.define('cr.ui.login', function() {
}
},
/** Initializes demo mode start listener. */
initializeDemoModeMultiTapListener: function() {
if (this.displayType_ == DISPLAY_TYPE.OOBE) {
this.demoModeStartListener_ = new MultiTapDetector(
$('outer-container'), 10, this.showEnableDemoModeDialog_.bind(this));
}
},
/**
* Prepares screens to use in login display.
*/
......@@ -991,7 +1003,17 @@ cr.define('cr.ui.login', function() {
* Shows the enable demo mode dialog.
* @private
*/
showEnableDemoModeDialog_: function(promptText, requisition) {
showEnableDemoModeDialog_: function() {
var isDemoModeEnabled = loadTimeData.getBoolean('isDemoModeEnabled');
if (!isDemoModeEnabled) {
console.warn('Cannot setup demo mode, because it is disabled.');
return;
}
var currentStepId = this.screens_[this.currentStep_];
if (!DEMO_MODE_SETUP_AVAILABLE_SCREEN_GROUP.includes(currentStepId))
return;
if (!this.enableDemoModeDialog_) {
this.enableDemoModeDialog_ =
new cr.ui.dialogs.ConfirmDialog(document.body);
......@@ -1000,12 +1022,13 @@ cr.define('cr.ui.login', function() {
this.enableDemoModeDialog_.setCancelLabel(
loadTimeData.getString('enableDemoModeDialogCancel'));
}
this.enableDemoModeDialog_.showWithTitle(
loadTimeData.getString('enableDemoModeDialogTitle'),
loadTimeData.getString('enableDemoModeDialogText'),
function() { // onOk
chrome.send('setupDemoMode');
}, );
});
},
/**
......@@ -1053,6 +1076,7 @@ cr.define('cr.ui.login', function() {
}
instance.initializeOOBEScreens();
instance.initializeDemoModeMultiTapListener();
window.addEventListener('resize', instance.onWindowResize_.bind(instance));
};
......
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