Commit 8f861fa4 authored by Eyor Alemayehu's avatar Eyor Alemayehu Committed by Commit Bot

Add an appropriate optin message for G-Suite users

Currently, G-Suite users whose policy is enforced by the administrator
are prompted to enable the Web and App activity when they launch
Assistant. However, they are not authorized to enable the Web and App
activity.

Made changes to present an appropriate prompt as outlined in:

go/gsuite-optin

Bug: b:123638794
Change-Id: I883efed56948f0d22e577902eb489b37b894af94
Reviewed-on: https://chromium-review.googlesource.com/c/1480539
Commit-Queue: Eyor Alemayehu <eyor@google.com>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#635698}
parent 7a397889
...@@ -1762,12 +1762,15 @@ This file contains the strings for ash. ...@@ -1762,12 +1762,15 @@ This file contains the strings for ash.
<message name="IDS_ASH_ASSISTANT_NOTIFICATION_DISPLAY_SOURCE" desc="The name for the source of the assistant notification."> <message name="IDS_ASH_ASSISTANT_NOTIFICATION_DISPLAY_SOURCE" desc="The name for the source of the assistant notification.">
Assistant Assistant
</message> </message>
<message name="IDS_ASH_ASSISTANT_OPT_IN_UNLOCK_MORE_FEATURES" desc="Message shown in Assistant UI when the user is opted out to promote an opted in experience."> <message name="IDS_ASH_ASSISTANT_OPT_IN_ASK_ADMINISTRATOR" desc="Message shown in Assistant UI to direct a G Suite user to a page that specifies how the administrator can remove policy restrictions such that the user has access to more Assistant features.">
Unlock more Assistant features. Ask Administrator
</message> </message>
<message name="IDS_ASH_ASSISTANT_OPT_IN_GET_STARTED" desc="Message shown in Assistant UI when the user is opted out to promote an opted in experience."> <message name="IDS_ASH_ASSISTANT_OPT_IN_GET_STARTED" desc="Message shown in Assistant UI when the user is opted out to promote an opted in experience.">
Get Started Get Started
</message> </message>
<message name="IDS_ASH_ASSISTANT_OPT_IN_UNLOCK_MORE_FEATURES" desc="Message shown in Assistant UI when the user is opted out to promote an opted in experience.">
Unlock more Assistant features.
</message>
<message name="IDS_ASH_ASSISTANT_OPT_IN_PROMPT" desc="Message shown in Assistant UI when the user is opted out to promote an opted in experience. $1 = IDS_ASH_ASSISTANT_OPT_IN_UNLOCK_MORE_FEATURES, $2 = IDS_ASH_ASSISTANT_OPT_IN_GET_STARTED"> <message name="IDS_ASH_ASSISTANT_OPT_IN_PROMPT" desc="Message shown in Assistant UI when the user is opted out to promote an opted in experience. $1 = IDS_ASH_ASSISTANT_OPT_IN_UNLOCK_MORE_FEATURES, $2 = IDS_ASH_ASSISTANT_OPT_IN_GET_STARTED">
<ph name="UNLOCK_MORE_FEATURES">$1<ex>Unlock more Assistant features.</ex></ph> <ph name="GET_STARTED">$2<ex>Get Started</ex></ph> <ph name="UNLOCK_MORE_FEATURES">$1<ex>Unlock more Assistant features.</ex></ph> <ph name="GET_STARTED">$2<ex>Get Started</ex></ph>
</message> </message>
......
...@@ -7,8 +7,20 @@ ...@@ -7,8 +7,20 @@
#include "ash/assistant/assistant_controller.h" #include "ash/assistant/assistant_controller.h"
#include "ash/assistant/assistant_ui_controller.h" #include "ash/assistant/assistant_ui_controller.h"
#include "ash/assistant/util/deep_link_util.h" #include "ash/assistant/util/deep_link_util.h"
#include "ash/assistant/util/i18n_util.h"
#include "ash/public/interfaces/voice_interaction_controller.mojom.h"
#include "ash/shell.h"
#include "ash/voice_interaction/voice_interaction_controller.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "chromeos/services/assistant/public/features.h"
namespace {
constexpr char kGSuiteAdministratorInstructionsUrl[] =
"https://support.google.com/a/answer/6304876";
} // namespace
namespace ash { namespace ash {
...@@ -47,7 +59,16 @@ void AssistantSetupController::OnDeepLinkReceived( ...@@ -47,7 +59,16 @@ void AssistantSetupController::OnDeepLinkReceived(
} }
void AssistantSetupController::OnOptInButtonPressed() { void AssistantSetupController::OnOptInButtonPressed() {
mojom::ConsentStatus consent_status =
Shell::Get()->voice_interaction_controller()->consent_status().value_or(
mojom::ConsentStatus::kUnknown);
if (consent_status == mojom::ConsentStatus::kUnauthorized) {
assistant_controller_->OpenUrl(assistant::util::CreateLocalizedGURL(
kGSuiteAdministratorInstructionsUrl));
} else {
StartOnboarding(/*relaunch=*/true); StartOnboarding(/*relaunch=*/true);
}
} }
void AssistantSetupController::StartOnboarding(bool relaunch, void AssistantSetupController::StartOnboarding(bool relaunch,
......
...@@ -84,9 +84,8 @@ void AssistantFooterView::InitLayout() { ...@@ -84,9 +84,8 @@ void AssistantFooterView::InitLayout() {
AddChildView(suggestion_container_); AddChildView(suggestion_container_);
// Opt in view. // Opt in view.
opt_in_view_ = new AssistantOptInView(); opt_in_view_ = new AssistantOptInView(delegate_);
opt_in_view_->set_can_process_events_within_subtree(!consent_given); opt_in_view_->set_can_process_events_within_subtree(!consent_given);
opt_in_view_->set_delegate(delegate_->GetOptInDelegate());
// Opt in view will be animated on its own layer. // Opt in view will be animated on its own layer.
opt_in_view_->SetPaintToLayer(); opt_in_view_->SetPaintToLayer();
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <vector> #include <vector>
#include "ash/assistant/ui/assistant_ui_constants.h" #include "ash/assistant/ui/assistant_ui_constants.h"
#include "ash/assistant/ui/assistant_view_delegate.h"
#include "ash/strings/grit/ash_strings.h" #include "ash/strings/grit/ash_strings.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
...@@ -34,6 +35,15 @@ views::StyledLabel::RangeStyleInfo CreateStyleInfo( ...@@ -34,6 +35,15 @@ views::StyledLabel::RangeStyleInfo CreateStyleInfo(
return style; return style;
} }
base::string16 GetAction(mojom::ConsentStatus consent_status) {
if (consent_status == mojom::ConsentStatus::kUnauthorized) {
return l10n_util::GetStringUTF16(
IDS_ASH_ASSISTANT_OPT_IN_ASK_ADMINISTRATOR);
} else {
return l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_OPT_IN_GET_STARTED);
}
}
// AssistantOptInContainer ----------------------------------------------------- // AssistantOptInContainer -----------------------------------------------------
class AssistantOptInContainer : public views::Button { class AssistantOptInContainer : public views::Button {
...@@ -77,11 +87,15 @@ class AssistantOptInContainer : public views::Button { ...@@ -77,11 +87,15 @@ class AssistantOptInContainer : public views::Button {
// AssistantOptInView ---------------------------------------------------------- // AssistantOptInView ----------------------------------------------------------
AssistantOptInView::AssistantOptInView() { AssistantOptInView::AssistantOptInView(AssistantViewDelegate* delegate)
: delegate_(delegate) {
InitLayout(); InitLayout();
delegate_->AddVoiceInteractionControllerObserver(this);
} }
AssistantOptInView::~AssistantOptInView() = default; AssistantOptInView::~AssistantOptInView() {
delegate_->RemoveVoiceInteractionControllerObserver(this);
}
const char* AssistantOptInView::GetClassName() const { const char* AssistantOptInView::GetClassName() const {
return "AssistantOptInView"; return "AssistantOptInView";
...@@ -107,37 +121,42 @@ void AssistantOptInView::InitLayout() { ...@@ -107,37 +121,42 @@ void AssistantOptInView::InitLayout() {
views::BoxLayout::MainAxisAlignment::MAIN_AXIS_ALIGNMENT_CENTER); views::BoxLayout::MainAxisAlignment::MAIN_AXIS_ALIGNMENT_CENTER);
// Container. // Container.
AssistantOptInContainer* container = container_ = new AssistantOptInContainer(/*listener=*/this);
new AssistantOptInContainer(/*listener=*/this);
layout_manager = layout_manager =
container->SetLayoutManager(std::make_unique<views::BoxLayout>( container_->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal, views::BoxLayout::Orientation::kHorizontal,
gfx::Insets(0, kPaddingDip))); gfx::Insets(0, kPaddingDip)));
layout_manager->set_cross_axis_alignment( layout_manager->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_CENTER); views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_CENTER);
AddChildView(container); AddChildView(container_);
// Label. // Label.
label_ = new views::StyledLabel(base::string16(), /*listener=*/nullptr); label_ = new views::StyledLabel(base::string16(), /*listener=*/nullptr);
label_->set_auto_color_readability_enabled(false); label_->set_auto_color_readability_enabled(false);
label_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_CENTER); label_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_CENTER);
container_->AddChildView(label_);
container_->SetFocusForPlatform();
UpdateLabel(delegate_->GetConsentStatus());
}
void AssistantOptInView::UpdateLabel(mojom::ConsentStatus consent_status) {
// First substitution string: "Unlock more Assistant features." // First substitution string: "Unlock more Assistant features."
const base::string16 unlock_features = const base::string16 unlock_features =
l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_OPT_IN_UNLOCK_MORE_FEATURES); l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_OPT_IN_UNLOCK_MORE_FEATURES);
// Second substitution string: "Get Started". // Second substitution string specifies the action to be taken.
const base::string16 get_started = const base::string16 action = GetAction(consent_status);
l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_OPT_IN_GET_STARTED);
// Set the text, having replaced placeholders in the opt in prompt with // Set the text, having replaced placeholders in the opt in prompt with
// substitution strings and caching their offset positions for styling. // substitution strings and caching their offset positions for styling.
std::vector<size_t> offsets; std::vector<size_t> offsets;
auto label_text = l10n_util::GetStringFUTF16( auto label_text = l10n_util::GetStringFUTF16(
IDS_ASH_ASSISTANT_OPT_IN_PROMPT, unlock_features, get_started, &offsets); IDS_ASH_ASSISTANT_OPT_IN_PROMPT, unlock_features, action, &offsets);
label_->SetText(label_text); label_->SetText(label_text);
// Style the first substitution string. // Style the first substitution string.
...@@ -147,19 +166,20 @@ void AssistantOptInView::InitLayout() { ...@@ -147,19 +166,20 @@ void AssistantOptInView::InitLayout() {
// Style the second substitution string. // Style the second substitution string.
label_->AddStyleRange( label_->AddStyleRange(
gfx::Range(offsets.at(1), offsets.at(1) + get_started.length()), gfx::Range(offsets.at(1), offsets.at(1) + action.length()),
CreateStyleInfo(gfx::Font::Weight::BOLD)); CreateStyleInfo(gfx::Font::Weight::BOLD));
container->AddChildView(label_); container_->SetAccessibleName(label_text);
container->SetFocusForPlatform();
container->SetAccessibleName(label_text);
} }
void AssistantOptInView::ButtonPressed(views::Button* sender, void AssistantOptInView::ButtonPressed(views::Button* sender,
const ui::Event& event) { const ui::Event& event) {
if (delegate_) delegate_->GetOptInDelegate()->OnOptInButtonPressed();
delegate_->OnOptInButtonPressed(); }
void AssistantOptInView::OnVoiceInteractionConsentStatusUpdated(
mojom::ConsentStatus consent_status) {
UpdateLabel(consent_status);
} }
} // namespace ash } // namespace ash
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef ASH_ASSISTANT_UI_MAIN_STAGE_ASSISTANT_OPT_IN_VIEW_H_ #ifndef ASH_ASSISTANT_UI_MAIN_STAGE_ASSISTANT_OPT_IN_VIEW_H_
#define ASH_ASSISTANT_UI_MAIN_STAGE_ASSISTANT_OPT_IN_VIEW_H_ #define ASH_ASSISTANT_UI_MAIN_STAGE_ASSISTANT_OPT_IN_VIEW_H_
#include "ash/public/cpp/assistant/default_voice_interaction_observer.h"
#include "ash/public/interfaces/voice_interaction_controller.mojom.h"
#include "base/component_export.h" #include "base/component_export.h"
#include "base/macros.h" #include "base/macros.h"
#include "ui/views/controls/button/button.h" #include "ui/views/controls/button/button.h"
...@@ -15,6 +17,8 @@ class StyledLabel; ...@@ -15,6 +17,8 @@ class StyledLabel;
namespace ash { namespace ash {
class AssistantViewDelegate;
// AssistantOptInDelegate ------------------------------------------------------ // AssistantOptInDelegate ------------------------------------------------------
class COMPONENT_EXPORT(ASSISTANT_UI) AssistantOptInDelegate { class COMPONENT_EXPORT(ASSISTANT_UI) AssistantOptInDelegate {
...@@ -30,9 +34,10 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantOptInDelegate { ...@@ -30,9 +34,10 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantOptInDelegate {
class COMPONENT_EXPORT(ASSISTANT_UI) AssistantOptInView class COMPONENT_EXPORT(ASSISTANT_UI) AssistantOptInView
: public views::View, : public views::View,
public views::ButtonListener { public views::ButtonListener,
public DefaultVoiceInteractionObserver {
public: public:
AssistantOptInView(); explicit AssistantOptInView(AssistantViewDelegate* delegate_);
~AssistantOptInView() override; ~AssistantOptInView() override;
// views::View: // views::View:
...@@ -43,14 +48,19 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantOptInView ...@@ -43,14 +48,19 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantOptInView
// views::ButtonListener: // views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override; void ButtonPressed(views::Button* sender, const ui::Event& event) override;
void set_delegate(AssistantOptInDelegate* delegate) { delegate_ = delegate; } // DefaultVoiceInteractionObserver:
void OnVoiceInteractionConsentStatusUpdated(
mojom::ConsentStatus consent_status) override;
private: private:
void InitLayout(); void InitLayout();
void UpdateLabel(mojom::ConsentStatus consent_status);
views::StyledLabel* label_; // Owned by view hierarchy. views::StyledLabel* label_; // Owned by view hierarchy.
AssistantOptInDelegate* delegate_ = nullptr; views::Button* container_;
AssistantViewDelegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(AssistantOptInView); DISALLOW_COPY_AND_ASSIGN(AssistantOptInView);
}; };
......
...@@ -18,6 +18,8 @@ component("util") { ...@@ -18,6 +18,8 @@ component("util") {
"deep_link_util.h", "deep_link_util.h",
"histogram_util.cc", "histogram_util.cc",
"histogram_util.h", "histogram_util.h",
"i18n_util.cc",
"i18n_util.h",
] ]
deps = [ deps = [
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <array> #include <array>
#include <set> #include <set>
#include "base/i18n/rtl.h" #include "ash/assistant/util/i18n_util.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
...@@ -42,15 +42,6 @@ constexpr char kAssistantTaskManagerPrefix[] = "googleassistant://task-manager"; ...@@ -42,15 +42,6 @@ constexpr char kAssistantTaskManagerPrefix[] = "googleassistant://task-manager";
constexpr char kAssistantWhatsOnMyScreenPrefix[] = constexpr char kAssistantWhatsOnMyScreenPrefix[] =
"googleassistant://whats-on-my-screen"; "googleassistant://whats-on-my-screen";
// Helpers ---------------------------------------------------------------------
// Returns a GURL for the specified |url| having set the locale query parameter.
GURL CreateLocalizedGURL(const std::string& url) {
static constexpr char kLocaleParamKey[] = "hl";
return net::AppendOrReplaceQueryParameter(GURL(url), kLocaleParamKey,
base::i18n::GetConfiguredLocale());
}
} // namespace } // namespace
// Utilities ------------------------------------------------------------------- // Utilities -------------------------------------------------------------------
......
// 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.
#include "ash/assistant/util/i18n_util.h"
#include "base/i18n/rtl.h"
#include "net/base/url_util.h"
#include "url/gurl.h"
namespace ash {
namespace assistant {
namespace util {
GURL CreateLocalizedGURL(const std::string& url) {
static constexpr char kLocaleParamKey[] = "hl";
return net::AppendOrReplaceQueryParameter(GURL(url), kLocaleParamKey,
base::i18n::GetConfiguredLocale());
}
} // namespace util
} // namespace assistant
} // namespace ash
\ No newline at end of file
// 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.
#ifndef ASH_ASSISTANT_UTIL_I18N_UTIL_H_
#define ASH_ASSISTANT_UTIL_I18N_UTIL_H_
#include <string>
#include "base/component_export.h"
class GURL;
namespace ash {
namespace assistant {
namespace util {
// Returns a GURL for the specified |url| having set the locale query parameter.
COMPONENT_EXPORT(ASSISTANT_UTIL)
GURL CreateLocalizedGURL(const std::string& url);
} // namespace util
} // namespace assistant
} // namespace ash
#endif // ASH_ASSISTANT_UTIL_I18N_UTIL_H_
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