Commit 02cf6c70 authored by Matthew Mourgos's avatar Matthew Mourgos Committed by Commit Bot

OOBE: Add a final accessibility page to the marketing opt in screen

This change adds an accessibility page that can be shown by clicking a
link on the marketing opt in screen. The link to show the accessibility
screen is only shown if the user was shown the gesture navigation screen
before getting to the marketing opt in screen.

The accessibility page contains a toggle for changing the
kAccessibilityTabletModeShelfNavigationButtonsEnabled pref.

Bug: 976949
Change-Id: Ibbb1568389b86cd336d8c4b65fe275ca2b256ce7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2078740
Commit-Queue: Matthew Mourgos <mmourgos@chromium.org>
Reviewed-by: default avatarToni Baržić <tbarzic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#746692}
parent 43d0c4f4
......@@ -5,9 +5,12 @@
#include "chrome/browser/chromeos/login/screens/gesture_navigation_screen.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/ash_pref_names.h"
#include "ash/public/cpp/tablet_mode.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/browser/chromeos/login/users/chrome_user_manager_util.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "components/prefs/pref_service.h"
namespace chromeos {
......@@ -17,20 +20,6 @@ constexpr const char kUserActionExitPressed[] = "exit";
} // namespace
// static
bool GestureNavigationScreen::ShouldSkipGestureNavigationScreen() {
// TODO(mmourgos): If clamshell mode is enabled and device is detachable, then
// show the gesture navigation flow.
AccessibilityManager* accessibility_manager = AccessibilityManager::Get();
return (chrome_user_manager_util::IsPublicSessionOrEphemeralLogin() ||
!ash::features::IsHideShelfControlsInTabletModeEnabled() ||
!ash::TabletMode::Get()->InTabletMode() ||
accessibility_manager->IsSpokenFeedbackEnabled() ||
accessibility_manager->IsAutoclickEnabled() ||
accessibility_manager->IsSwitchAccessEnabled());
}
GestureNavigationScreen::GestureNavigationScreen(
GestureNavigationScreenView* view,
const base::RepeatingClosure& exit_callback)
......@@ -47,7 +36,16 @@ GestureNavigationScreen::~GestureNavigationScreen() {
}
void GestureNavigationScreen::ShowImpl() {
if (ShouldSkipGestureNavigationScreen()) {
// TODO(mmourgos): If clamshell mode is enabled and device is detachable, then
// show the gesture navigation flow.
AccessibilityManager* accessibility_manager = AccessibilityManager::Get();
if (chrome_user_manager_util::IsPublicSessionOrEphemeralLogin() ||
!ash::features::IsHideShelfControlsInTabletModeEnabled() ||
!ash::TabletMode::Get()->InTabletMode() ||
accessibility_manager->IsSpokenFeedbackEnabled() ||
accessibility_manager->IsAutoclickEnabled() ||
accessibility_manager->IsSwitchAccessEnabled()) {
exit_callback_.Run();
return;
}
......@@ -60,6 +58,10 @@ void GestureNavigationScreen::HideImpl() {
void GestureNavigationScreen::OnUserAction(const std::string& action_id) {
if (action_id == kUserActionExitPressed) {
// Make sure the user does not see a notification about the new gestures
// since they have already gone through this gesture education screen.
ProfileManager::GetActiveUserProfile()->GetPrefs()->SetBoolean(
ash::prefs::kGestureEducationNotificationShown, true);
exit_callback_.Run();
} else {
BaseScreen::OnUserAction(action_id);
......
......@@ -23,9 +23,6 @@ class GestureNavigationScreen : public BaseScreen {
GestureNavigationScreen(const GestureNavigationScreen&) = delete;
GestureNavigationScreen operator=(const GestureNavigationScreen&) = delete;
// Returns whether the gesture navigation screen should be shown.
static bool ShouldSkipGestureNavigationScreen();
void set_exit_callback_for_testing(
const base::RepeatingClosure& exit_callback) {
exit_callback_ = exit_callback;
......
......@@ -4,7 +4,11 @@
#include "chrome/browser/chromeos/login/screens/marketing_opt_in_screen.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/ash_pref_names.h"
#include "ash/public/cpp/login_screen.h"
#include "ash/public/cpp/tablet_mode.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "chrome/browser/chromeos/login/screens/gesture_navigation_screen.h"
......@@ -64,17 +68,28 @@ void MarketingOptInScreen::OnShelfConfigUpdated() {
void MarketingOptInScreen::ShowImpl() {
PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs();
const bool did_skip_gesture_navigation_screen =
!prefs->GetBoolean(ash::prefs::kGestureEducationNotificationShown);
// Always skip the screen if it is a public session or non-regular ephemeral
// user login. Also skip the screen if clamshell mode is active.
// TODO(mmourgos): Enable this screen for clamshell mode.
if (chrome_user_manager_util::IsPublicSessionOrEphemeralLogin() ||
!ash::TabletMode::Get()->InTabletMode()) {
exit_callback_.Run();
return;
}
// Skip the screen if:
// 1) the feature is disabled, or
// 2) the screen has been shown for this user, or
// 3) it is public session or non-regular ephemeral user login.
// 2) the screen has been shown for this user
// AND
// 4) the gesture navigation screen was skipped.
// 3) the hide shelf controls in tablet mode feature is disabled.
if ((!base::CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kEnableMarketingOptInScreen) ||
prefs->GetBoolean(prefs::kOobeMarketingOptInScreenFinished) ||
chrome_user_manager_util::IsPublicSessionOrEphemeralLogin()) &&
GestureNavigationScreen::ShouldSkipGestureNavigationScreen()) {
prefs->GetBoolean(prefs::kOobeMarketingOptInScreenFinished)) &&
!ash::features::IsHideShelfControlsInTabletModeEnabled()) {
exit_callback_.Run();
return;
}
......@@ -89,6 +104,25 @@ void MarketingOptInScreen::ShowImpl() {
// Make sure the screen next button visibility is properly initialized.
view_->UpdateAllSetButtonVisibility(!handling_shelf_gestures_ /*visible*/);
// Only show the link for accessibility settings if the gesture navigation
// screen was shown. This button gets shown when the login shelf gesture
// gets enabled.
view_->UpdateA11ySettingsButtonVisibility(
!did_skip_gesture_navigation_screen || handling_shelf_gestures_);
view_->UpdateA11yShelfNavigationButtonToggle(prefs->GetBoolean(
ash::prefs::kAccessibilityTabletModeShelfNavigationButtonsEnabled));
// Observe the a11y shelf navigation buttons pref so the setting toggle in the
// screen can be updated if the pref value changes.
active_user_pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
active_user_pref_change_registrar_->Init(prefs);
active_user_pref_change_registrar_->Add(
ash::prefs::kAccessibilityTabletModeShelfNavigationButtonsEnabled,
base::BindRepeating(
&MarketingOptInScreen::OnA11yShelfNavigationButtonPrefChanged,
base::Unretained(this)));
}
void MarketingOptInScreen::HideImpl() {
......@@ -102,6 +136,8 @@ void MarketingOptInScreen::HideImpl() {
view_->Hide();
ClearLoginShelfGestureHandler();
active_user_pref_change_registrar_.reset();
}
void MarketingOptInScreen::OnAllSet(bool play_communications_opt_in,
......@@ -143,4 +179,10 @@ void MarketingOptInScreen::ClearLoginShelfGestureHandler() {
ash::LoginScreen::Get()->ClearLoginShelfGestureHandler();
}
void MarketingOptInScreen::OnA11yShelfNavigationButtonPrefChanged() {
view_->UpdateA11yShelfNavigationButtonToggle(
ProfileManager::GetActiveUserProfile()->GetPrefs()->GetBoolean(
ash::prefs::kAccessibilityTabletModeShelfNavigationButtonsEnabled));
}
} // namespace chromeos
......@@ -11,6 +11,7 @@
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "chrome/browser/chromeos/login/screens/base_screen.h"
#include "components/prefs/pref_change_registrar.h"
namespace chromeos {
......@@ -61,6 +62,8 @@ class MarketingOptInScreen : public BaseScreen,
// gestures.
void ClearLoginShelfGestureHandler();
void OnA11yShelfNavigationButtonPrefChanged();
MarketingOptInScreenView* const view_;
// Whether the screen is shown and exit callback has not been run.
......@@ -74,6 +77,8 @@ class MarketingOptInScreen : public BaseScreen,
ScopedObserver<ash::ShelfConfig, ash::ShelfConfig::Observer>
shelf_config_observer_{this};
std::unique_ptr<PrefChangeRegistrar> active_user_pref_change_registrar_;
base::WeakPtrFactory<MarketingOptInScreen> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(MarketingOptInScreen);
......
......@@ -114,19 +114,25 @@ IN_PROC_BROWSER_TEST_F(MarketingOptInScreenTest, MarketingTogglesHidden) {
test::OobeJS().ExpectHiddenPath(
{"marketing-opt-in", "marketing-opt-in-subtitle"});
test::OobeJS().ExpectHiddenPath(
{"marketing-opt-in", "marketing-opt-in-toggles"});
{"marketing-opt-in", "marketing-opt-in-toggle-1"});
test::OobeJS().ExpectHiddenPath(
{"marketing-opt-in", "marketing-opt-in-toggle-2"});
ash::ShellTestApi().SetTabletModeEnabledForTest(false);
test::OobeJS().ExpectHiddenPath(
{"marketing-opt-in", "marketing-opt-in-subtitle"});
test::OobeJS().ExpectHiddenPath(
{"marketing-opt-in", "marketing-opt-in-toggles"});
{"marketing-opt-in", "marketing-opt-in-toggle-1"});
test::OobeJS().ExpectHiddenPath(
{"marketing-opt-in", "marketing-opt-in-toggle-2"});
ash::ShellTestApi().SetTabletModeEnabledForTest(true);
test::OobeJS().ExpectHiddenPath(
{"marketing-opt-in", "marketing-opt-in-subtitle"});
test::OobeJS().ExpectHiddenPath(
{"marketing-opt-in", "marketing-opt-in-toggles"});
{"marketing-opt-in", "marketing-opt-in-toggle-1"});
test::OobeJS().ExpectHiddenPath(
{"marketing-opt-in", "marketing-opt-in-toggle-2"});
}
// Tests that fling from shelf exits the screen in tablet mode.
......
......@@ -4,6 +4,7 @@
:host {
--marketing-opt-in-dialog-list-item-border: 1px solid var(--google-grey-200);
--oobe-a11y-dialog-list-item-border: 1px solid var(--google-grey-200);
}
.marketing-option {
......@@ -23,3 +24,22 @@
--iron-icon-fill-color: var(--google-blue-600);
padding-inline-end: 16px;
}
#finalAccessibilityLink {
align-self: flex-end;
}
#finalAccessibilityLinkContainer {
display: flex;
height: 100%;
justify-content: center;
}
#finalAccessibilityPage oobe-a11y-option {
border-top: var(--oobe-a11y-dialog-list-item-border);
min-height: 64px;
}
#finalAccessibilityPage oobe-a11y-option:last-of-type {
border-bottom: var(--oobe-a11y-dialog-list-item-border);
}
\ No newline at end of file
......@@ -3,6 +3,27 @@
found in the LICENSE file. -->
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html">
<iron-iconset-svg name="marketing-opt-in-32" size="32">
<svg>
<defs>
<g id="accessibility" fill-rule="evenodd">
<path d="M16 2.667c1.467 0 2.667 1.184 2.667 2.633 0 1.448-1.2 2.632-2.667 2.632-1.467 0-2.667-1.184-2.667-2.632 0-1.45 1.2-2.633 2.667-2.633zm4 9.215v16.785h-3v-7.9h-2v7.9h-3V11.882H4V8.92h24v2.962h-8z"></path>
</g>
</defs>
</svg>
</iron-iconset-svg>
<iron-iconset-svg name="marketing-opt-in-64" size="64">
<svg>
<defs>
<g id="accessibility" fill-rule="evenodd">
<path d="M32 5.333c2.933 0 5.333 2.415 5.333 5.367 0 2.95-2.4 5.366-5.333 5.366-2.933 0-5.333-2.415-5.333-5.366 0-2.952 2.4-5.367 5.333-5.367zM40 24v35h-5V43h-6v16.006h-5V24H8v-4.915h48V24H40z"></path>
</g>
</defs>
</svg>
</iron-iconset-svg>
<dom-module id="marketing-opt-in">
<template>
......@@ -10,6 +31,7 @@
<link rel="stylesheet" href="marketing_opt_in.css">
<link rel="stylesheet" href="oobe_flex_layout.css">
<oobe-dialog id="marketingOptInOverviewDialog" role="dialog" has-buttons
hidden="[[isAccessibilitySettingsShown_]]"
title-key="marketingOptInScreenTitle"
aria-label$="[[i18nDynamic(locale, 'marketingOptInScreenTitle')]]">
<hd-iron-icon slot="oobe-icon" icon1x="oobe-32:checkmark"
......@@ -19,9 +41,10 @@
hidden="[[!marketingOptInEnabled_]]">
[[i18nRecursive(locale, 'marketingOptInScreenSubtitle', 'productName')]]
</div>
<div slot="footer" class="layout vertical" id="marketing-opt-in-toggles"
hidden="[[!marketingOptInEnabled_]]">
<div class="marketing-option layout horizontal center">
<div slot="footer" class="layout vertical flex">
<div class="marketing-option layout horizontal center"
hidden="[[!marketingOptInEnabled_]]"
id="marketing-opt-in-toggle-1">
<hd-iron-icon icon1x="oobe-32:checkmark" icon2x="oobe-64:checkmark">
</hd-iron-icon>
<div id="playUpdatesOptionLabel" class="flex">
......@@ -31,7 +54,9 @@
aria-labelledby="usageStatsLabel">
</cr-toggle>
</div>
<div class="marketing-option layout horizontal center">
<div class="marketing-option layout horizontal center"
hidden="[[!marketingOptInEnabled_]]"
id="marketing-opt-in-toggle-2">
<hd-iron-icon icon1x="oobe-32:checkmark" icon2x="oobe-64:checkmark">
</hd-iron-icon>
<div id="chromebookUpdatesOptionLabel" class="flex">
......@@ -42,6 +67,13 @@
aria-labelledby="chromebookUpdatesOption">
</cr-toggle>
</div>
<div hidden="[[!isA11ySettingsButtonVisible_]]"
id="finalAccessibilityLinkContainer">
<a class="oobe-local-link"
id="finalAccessibilityLink" on-tap="onToggleAccessibilityPage_">
[[i18nDynamic(locale, 'marketingOptInA11yLinkLabel')]]
</a>
</div>
</div>
<div slot="bottom-buttons" class="layout horizontal end-justified">
<oobe-text-button on-tap="onAllSet_" class="focus-on-show" inverse
......@@ -51,5 +83,36 @@
</oobe-text-button>
</div>
</oobe-dialog>
<oobe-dialog id="finalAccessibilityPage" role="dialog" has-buttons
hidden="[[!isAccessibilitySettingsShown_]]"
title-key="finalA11yPageTitle"
aria-label$="[[i18nDynamic(locale, 'finalA11yPageTitle')]]">>
<hd-iron-icon slot="oobe-icon"
icon1x="marketing-opt-in-32:accessibility"
icon2x="marketing-opt-in-64:accessibility">
</hd-iron-icon>
<div slot="footer" class="layout vertical">
<oobe-a11y-option id="a11yNavButtonToggle"
on-change="onA11yNavButtonsSettingChanged_">
<span slot="title">
[[i18nDynamic(locale, 'finalA11yPageNavButtonSettingTitle')]]
</span>
<span slot="checked-value">
[[i18nDynamic(locale, 'finalA11yPageNavButtonSettingDescription')]]
</span>
<span slot="unchecked-value">
[[i18nDynamic(locale, 'finalA11yPageNavButtonSettingDescription')]]
</span>
</oobe-a11y-option>
</div>
<div slot="bottom-buttons" class="layout horizontal justified">
<oobe-back-button on-tap="onToggleAccessibilityPage_"
id="final-accessibility-back-button"></oobe-back-button>
<oobe-text-button on-tap="onAllSet_" class="focus-on-show" inverse
text-key="finalA11yPageDoneButtonTitle">
</oobe-text-button>
</div>
</oobe-dialog>
</template>
</dom-module>
......@@ -16,6 +16,16 @@ Polymer({
value: true,
},
isAccessibilitySettingsShown_: {
type: Boolean,
value: false,
},
isA11ySettingsButtonVisible_: {
type: Boolean,
value: false,
},
/**
* Whether the marketing opt in toggles should be shown, which will be the
* case only if marketing opt in feature is enabled.
......@@ -36,6 +46,8 @@ Polymer({
/** Overridden from LoginScreenBehavior. */
EXTERNAL_API: [
'updateAllSetButtonVisibility',
'updateA11ySettingsButtonVisibility',
'updateA11yNavigationButtonToggle',
],
/** @override */
......@@ -57,7 +69,46 @@ Polymer({
* @param {boolean} visible Whether the all set button should be shown.
*/
updateAllSetButtonVisibility(visible) {
// TODO(mmourgos): Update |this.allSetButtonVisible_| once the accessibility
// setting to show shelf buttons is added to screen.
this.allSetButtonVisible_ = visible;
// When showing the all set button, give the user a way to disable shelf
// gestures, and enabled "all set" button.
if(visible)
this.isA11ySettingsButtonVisible_ = true;
},
/**
* @param {boolean} shown Whether the A11y Settings button should be shown.
*/
updateA11ySettingsButtonVisibility(shown) {
this.isA11ySettingsButtonVisible_ = shown;
},
/**
* @param {boolean} enabled Whether the a11y setting for shownig shelf
* navigation buttons is enabled.
*/
updateA11yNavigationButtonToggle(enabled) {
this.$.a11yNavButtonToggle.checked = enabled;
},
/**
* This is the 'on-tap' event handler for the accessibility settings link and
* for the back button on the accessibility page.
* @private
*/
onToggleAccessibilityPage_() {
this.isAccessibilitySettingsShown_ = !this.isAccessibilitySettingsShown_;
},
/**
* The 'on-change' event handler for when the a11y navigation button setting
* is toggled on or off.
* @private
*/
onA11yNavButtonsSettingChanged_() {
chrome.send('login.MarketingOptInScreen.setA11yNavigationButtonsEnabled', [
this.$.a11yNavButtonToggle.checked
]);
}
});
......@@ -4,11 +4,14 @@
#include "chrome/browser/ui/webui/chromeos/login/marketing_opt_in_screen_handler.h"
#include "ash/public/cpp/ash_pref_names.h"
#include "base/command_line.h"
#include "chrome/browser/chromeos/login/screens/marketing_opt_in_screen.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/constants/chromeos_switches.h"
#include "components/login/localized_values_builder.h"
#include "components/prefs/pref_service.h"
namespace chromeos {
......@@ -33,6 +36,16 @@ void MarketingOptInScreenHandler::DeclareLocalizedValues(
IDS_LOGIN_MARKETING_OPT_IN_SCREEN_GET_CHROMEBOOK_UPDATES);
builder->Add("marketingOptInScreenAllSet",
IDS_LOGIN_MARKETING_OPT_IN_SCREEN_ALL_SET);
builder->Add("marketingOptInA11yLinkLabel",
IDS_MARKETING_OPT_IN_ACCESSIBILITY_SETTINGS_LINK);
builder->Add("finalA11yPageTitle", IDS_MARKETING_OPT_IN_ACCESSIBILITY_TITLE);
builder->Add("finalA11yPageNavButtonSettingTitle",
IDS_MARKETING_OPT_IN_ACCESSIBILITY_NAV_BUTTON_SETTING_TITLE);
builder->Add(
"finalA11yPageNavButtonSettingDescription",
IDS_MARKETING_OPT_IN_ACCESSIBILITY_NAV_BUTTON_SETTING_DESCRIPTION);
builder->Add("finalA11yPageDoneButtonTitle",
IDS_MARKETING_OPT_IN_ACCESSIBILITY_DONE_BUTTON);
}
void MarketingOptInScreenHandler::Bind(MarketingOptInScreen* screen) {
......@@ -50,11 +63,26 @@ void MarketingOptInScreenHandler::UpdateAllSetButtonVisibility(bool visible) {
CallJS("login.MarketingOptInScreen.updateAllSetButtonVisibility", visible);
}
void MarketingOptInScreenHandler::UpdateA11ySettingsButtonVisibility(
bool shown) {
CallJS("login.MarketingOptInScreen.updateA11ySettingsButtonVisibility",
shown);
}
void MarketingOptInScreenHandler::UpdateA11yShelfNavigationButtonToggle(
bool enabled) {
CallJS("login.MarketingOptInScreen.updateA11yNavigationButtonToggle",
enabled);
}
void MarketingOptInScreenHandler::Initialize() {}
void MarketingOptInScreenHandler::RegisterMessages() {
AddCallback("login.MarketingOptInScreen.allSet",
&MarketingOptInScreenHandler::HandleAllSet);
AddCallback(
"login.MarketingOptInScreen.setA11yNavigationButtonsEnabled",
&MarketingOptInScreenHandler::HandleSetA11yNavigationButtonsEnabled);
}
void MarketingOptInScreenHandler::GetAdditionalParameters(
......@@ -71,4 +99,11 @@ void MarketingOptInScreenHandler::HandleAllSet(
screen_->OnAllSet(play_communications_opt_in, tips_communications_opt_in);
}
void MarketingOptInScreenHandler::HandleSetA11yNavigationButtonsEnabled(
bool enabled) {
ProfileManager::GetActiveUserProfile()->GetPrefs()->SetBoolean(
ash::prefs::kAccessibilityTabletModeShelfNavigationButtonsEnabled,
enabled);
}
} // namespace chromeos
......@@ -31,6 +31,13 @@ class MarketingOptInScreenView {
// Shows or hides the screen's all set (next) button visibility.
virtual void UpdateAllSetButtonVisibility(bool visible) = 0;
// Sets whether the a11y Settings button is visible.
virtual void UpdateA11ySettingsButtonVisibility(bool shown) = 0;
// Sets whether the a11y setting for showing shelf navigation buttons is
// toggled on or off.
virtual void UpdateA11yShelfNavigationButtonToggle(bool enabled) = 0;
};
// The sole implementation of the MarketingOptInScreenView, using WebUI.
......@@ -51,6 +58,8 @@ class MarketingOptInScreenHandler : public BaseScreenHandler,
void Show() override;
void Hide() override;
void UpdateAllSetButtonVisibility(bool visible) override;
void UpdateA11ySettingsButtonVisibility(bool shown) override;
void UpdateA11yShelfNavigationButtonToggle(bool enabled) override;
private:
// BaseScreenHandler:
......@@ -61,6 +70,7 @@ class MarketingOptInScreenHandler : public BaseScreenHandler,
// WebUI event handler.
void HandleAllSet(bool play_communications_opt_in,
bool tips_communications_opt_in);
void HandleSetA11yNavigationButtonsEnabled(bool enabled);
MarketingOptInScreen* screen_ = nullptr;
......
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