[go: nahoru, domu]

blob: d43d6b08777cfb9a51044025c637571ff2ea5ed0 [file] [log] [blame]
Meilin Wang418ae712020-09-17 05:50:031// Copyright 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ash/system/phonehub/onboarding_view.h"
6
7#include <algorithm>
8#include <memory>
Jan Wilken Dörriead587c32021-03-11 14:09:279#include <string>
Meilin Wang418ae712020-09-17 05:50:0310#include <vector>
11
12#include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h"
Meilin Wang98efd1be2020-10-01 22:25:3513#include "ash/public/cpp/system_tray_client.h"
Meilin Wangd626fde2020-10-23 17:53:3614#include "ash/root_window_controller.h"
Meilin Wang98efd1be2020-10-01 22:25:3515#include "ash/shell.h"
Meilin Wang418ae712020-09-17 05:50:0316#include "ash/strings/grit/ash_strings.h"
17#include "ash/style/ash_color_provider.h"
Meilin Wang98efd1be2020-10-01 22:25:3518#include "ash/system/model/system_tray_model.h"
Meilin Wang3062ff2e2020-10-07 22:26:4319#include "ash/system/phonehub/interstitial_view_button.h"
Meilin Wangd626fde2020-10-23 17:53:3620#include "ash/system/phonehub/phone_hub_content_view.h"
Meilin Wang418ae712020-09-17 05:50:0321#include "ash/system/phonehub/phone_hub_interstitial_view.h"
Tim Song85303702020-10-16 04:57:0022#include "ash/system/phonehub/phone_hub_metrics.h"
Meilin Wangd626fde2020-10-23 17:53:3623#include "ash/system/phonehub/phone_hub_tray.h"
Meilin Wang98efd1be2020-10-01 22:25:3524#include "ash/system/phonehub/phone_hub_view_ids.h"
Meilin Wangd626fde2020-10-23 17:53:3625#include "ash/system/status_area_widget.h"
26#include "ash/system/tray/tray_bubble_view.h"
Meilin Wang418ae712020-09-17 05:50:0327#include "ash/system/unified/rounded_label_button.h"
Meilin Wangd626fde2020-10-23 17:53:3628#include "base/strings/strcat.h"
Meilin Wang418ae712020-09-17 05:50:0329#include "base/strings/string16.h"
Meilin Wang98efd1be2020-10-01 22:25:3530#include "chromeos/components/phonehub/onboarding_ui_tracker.h"
Meilin Wang418ae712020-09-17 05:50:0331#include "ui/base/l10n/l10n_util.h"
32#include "ui/base/resource/resource_bundle.h"
Andre Le09e38cd2020-11-05 19:49:1633#include "ui/chromeos/devicetype_utils.h"
Meilin Wang418ae712020-09-17 05:50:0334#include "ui/views/layout/fill_layout.h"
Wei Li5add5412020-10-15 15:57:2135#include "ui/views/metadata/metadata_impl_macros.h"
Meilin Wang418ae712020-09-17 05:50:0336
37namespace ash {
38
Tim Song85303702020-10-16 04:57:0039using phone_hub_metrics::InterstitialScreenEvent;
Tim Song947932a2020-10-31 00:38:4540using phone_hub_metrics::Screen;
Tim Song85303702020-10-16 04:57:0041
Meilin Wangd626fde2020-10-23 17:53:3642// OnboardingMainView ---------------------------------------------------------
43// Main onboarding screen with Phone Hub feature description and two buttons
44// (Get Started and Dismiss), where user can either choose to grant permission
45// to enable this feature or dismiss the screen.
Peter Kasting5aacfd492020-10-31 03:33:1446class OnboardingMainView : public PhoneHubInterstitialView {
Meilin Wangd626fde2020-10-23 17:53:3647 public:
48 OnboardingMainView(
49 chromeos::phonehub::OnboardingUiTracker* onboarding_ui_tracker,
Tim Song5a9883f52020-11-04 19:40:0350 OnboardingView* parent_view,
51 OnboardingView::OnboardingFlow onboarding_flow)
Meilin Wangd626fde2020-10-23 17:53:3652 : PhoneHubInterstitialView(/*show_progress=*/false),
53 onboarding_ui_tracker_(onboarding_ui_tracker),
Tim Song5a9883f52020-11-04 19:40:0354 parent_view_(parent_view),
55 onboarding_flow_(onboarding_flow) {
Meilin Wangd626fde2020-10-23 17:53:3656 SetID(PhoneHubViewID::kOnboardingMainView);
57 InitLayout();
58 }
59
Tim Song947932a2020-10-31 00:38:4560 // PhoneHubInterstitialView:
61 Screen GetScreenForMetrics() const override {
Tim Song5a9883f52020-11-04 19:40:0362 switch (onboarding_flow_) {
63 case OnboardingView::kExistingMultideviceUser:
64 return Screen::kOnboardingExistingMultideviceUser;
65 case OnboardingView::kNewMultideviceUser:
66 return Screen::kOnboardingNewMultideviceUser;
67 }
Tim Song947932a2020-10-31 00:38:4568 }
69
Meilin Wangd626fde2020-10-23 17:53:3670 private:
71 void InitLayout() {
72 // TODO(crbug.com/1127996): Replace PNG file with vector icon.
73 gfx::ImageSkia* image =
74 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
75 IDR_PHONE_HUB_ONBOARDING_IMAGE);
76 SetImage(*image);
77 SetTitle(
78 l10n_util::GetStringUTF16(IDS_ASH_PHONE_HUB_ONBOARDING_DIALOG_TITLE));
Kyle Horimotofe7173b2021-01-14 22:32:4879 SetDescription(l10n_util::GetStringUTF16(
80 IDS_ASH_PHONE_HUB_ONBOARDING_DIALOG_DESCRIPTION));
Meilin Wangd626fde2020-10-23 17:53:3681
82 // Add "Dismiss" and "Get started" buttons.
83 auto dismiss = std::make_unique<InterstitialViewButton>(
Peter Kasting5aacfd492020-10-31 03:33:1484 base::BindRepeating(&OnboardingMainView::DismissButtonPressed,
85 base::Unretained(this)),
Meilin Wangd626fde2020-10-23 17:53:3686 l10n_util::GetStringUTF16(
87 IDS_ASH_PHONE_HUB_ONBOARDING_DIALOG_DISMISS_BUTTON),
88 /*paint_background=*/false);
89 dismiss->SetEnabledTextColors(AshColorProvider::Get()->GetContentLayerColor(
90 AshColorProvider::ContentLayerType::kTextColorPrimary));
91 dismiss->SetID(PhoneHubViewID::kOnboardingDismissButton);
92 AddButton(std::move(dismiss));
93
94 auto get_started = std::make_unique<InterstitialViewButton>(
Peter Kasting5aacfd492020-10-31 03:33:1495 base::BindRepeating(&OnboardingMainView::GetStartedButtonPressed,
96 base::Unretained(this)),
Meilin Wangd626fde2020-10-23 17:53:3697 l10n_util::GetStringUTF16(
98 IDS_ASH_PHONE_HUB_ONBOARDING_DIALOG_GET_STARTED_BUTTON),
99 /*paint_background=*/true);
100 get_started->SetID(PhoneHubViewID::kOnboardingGetStartedButton);
101 AddButton(std::move(get_started));
102 }
103
Peter Kasting5aacfd492020-10-31 03:33:14104 void GetStartedButtonPressed() {
Tim Songa6682b152020-11-03 21:24:24105 LogInterstitialScreenEvent(InterstitialScreenEvent::kConfirm);
Peter Kasting5aacfd492020-10-31 03:33:14106 onboarding_ui_tracker_->HandleGetStarted();
107 }
108
109 void DismissButtonPressed() {
Tim Songa6682b152020-11-03 21:24:24110 LogInterstitialScreenEvent(InterstitialScreenEvent::kDismiss);
Peter Kasting5aacfd492020-10-31 03:33:14111 parent_view_->ShowDismissPrompt();
112 }
113
Meilin Wangd626fde2020-10-23 17:53:36114 chromeos::phonehub::OnboardingUiTracker* onboarding_ui_tracker_ = nullptr;
115 OnboardingView* parent_view_ = nullptr;
Tim Song5a9883f52020-11-04 19:40:03116 const OnboardingView::OnboardingFlow onboarding_flow_;
Meilin Wangd626fde2020-10-23 17:53:36117};
118
119// OnboardingDismissPromptView ------------------------------------------------
120// A follow-up prompt screen that pops up when the user has chosen to dismiss
121// the main onboarding screen. It should not be shown again after being
122// dismissed manually by either clicking the ack button or outside the bubble.
Peter Kasting5aacfd492020-10-31 03:33:14123class OnboardingDismissPromptView : public PhoneHubInterstitialView {
Meilin Wangd626fde2020-10-23 17:53:36124 public:
125 explicit OnboardingDismissPromptView(
126 chromeos::phonehub::OnboardingUiTracker* onboarding_ui_tracker)
Meilin Wangffecec382020-11-13 03:12:23127 : PhoneHubInterstitialView(/*show_progress=*/false, /*show_image=*/false),
Meilin Wangd626fde2020-10-23 17:53:36128 onboarding_ui_tracker_(onboarding_ui_tracker) {
129 SetID(PhoneHubViewID::kOnboardingDismissPromptView);
130 InitLayout();
131 }
132
133 private:
134 void InitLayout() {
135 // Adds title and description.
136 SetTitle(l10n_util::GetStringUTF16(
137 IDS_ASH_PHONE_HUB_ONBOARDING_DISMISS_DIALOG_TITLE));
Jan Wilken Dörrie85285b02021-03-11 23:38:47138 std::u16string part1 = l10n_util::GetStringUTF16(
Kyle Horimotofe7173b2021-01-14 22:32:48139 IDS_ASH_PHONE_HUB_ONBOARDING_DISMISS_DIALOG_DESCRIPTION_PART_1);
Jan Wilken Dörrie85285b02021-03-11 23:38:47140 std::u16string part2 = l10n_util::GetStringUTF16(
Meilin Wangd626fde2020-10-23 17:53:36141 IDS_ASH_PHONE_HUB_ONBOARDING_DISMISS_DIALOG_DESCRIPTION_PART_2);
142 // Uses "\n" to create a newline separator between two text paragraphs.
143 SetDescription(base::StrCat({part1, base::ASCIIToUTF16("\n\n"), part2}));
144
145 // Adds "Ok, got it" button.
146 auto ack_button = std::make_unique<InterstitialViewButton>(
Peter Kasting5aacfd492020-10-31 03:33:14147 base::BindRepeating(&OnboardingDismissPromptView::ButtonPressed,
148 base::Unretained(this)),
Meilin Wangd626fde2020-10-23 17:53:36149 l10n_util::GetStringUTF16(
150 IDS_ASH_PHONE_HUB_ONBOARDING_DISMISS_DIALOG_OK_BUTTON),
151 /*paint_background=*/true);
152 ack_button->SetID(PhoneHubViewID::kOnboardingDismissAckButton);
153 AddButton(std::move(ack_button));
154 }
155
Peter Kasting5aacfd492020-10-31 03:33:14156 void ButtonPressed() {
Tim Songa6682b152020-11-03 21:24:24157 LogInterstitialScreenEvent(InterstitialScreenEvent::kConfirm);
Tim Song947932a2020-10-31 00:38:45158
Andre Le4a5d5cd2020-12-08 20:04:15159 // Close Phone Hub bubble in current display.
160 views::Widget* const widget = GetWidget();
161 // |widget| is null when this function is called before the view is added to
162 // a widget (in unit tests).
163 if (!widget)
164 return;
165 int64_t current_display_id =
166 display::Screen::GetScreen()
167 ->GetDisplayNearestWindow(widget->GetNativeWindow())
168 .id();
169 Shell::GetRootWindowControllerWithDisplayId(current_display_id)
Meilin Wangd626fde2020-10-23 17:53:36170 ->GetStatusAreaWidget()
171 ->phone_hub_tray()
172 ->CloseBubble();
173 }
174
Peter Kasting5aacfd492020-10-31 03:33:14175 // PhoneHubInterstitialView:
176 void OnBubbleClose() override { onboarding_ui_tracker_->DismissSetupUi(); }
177
178 Screen GetScreenForMetrics() const override {
179 return Screen::kOnboardingDismissPrompt;
180 }
181
Meilin Wangd626fde2020-10-23 17:53:36182 chromeos::phonehub::OnboardingUiTracker* onboarding_ui_tracker_ = nullptr;
183};
184
185// OnboardingView -------------------------------------------------------------
Meilin Wang98efd1be2020-10-01 22:25:35186OnboardingView::OnboardingView(
Meilin Wangd626fde2020-10-23 17:53:36187 chromeos::phonehub::OnboardingUiTracker* onboarding_ui_tracker,
Meilin Wang65319732020-11-06 20:03:18188 Delegate* delegate,
Tim Song5a9883f52020-11-04 19:40:03189 OnboardingFlow onboarding_flow)
Meilin Wang65319732020-11-06 20:03:18190 : onboarding_ui_tracker_(onboarding_ui_tracker), delegate_(delegate) {
Meilin Wang98efd1be2020-10-01 22:25:35191 SetID(PhoneHubViewID::kOnboardingView);
Meilin Wang418ae712020-09-17 05:50:03192
Meilin Wang418ae712020-09-17 05:50:03193 SetLayoutManager(std::make_unique<views::FillLayout>());
Tim Song5a9883f52020-11-04 19:40:03194 main_view_ = AddChildView(std::make_unique<OnboardingMainView>(
195 onboarding_ui_tracker_, this, onboarding_flow));
Tim Song85303702020-10-16 04:57:00196
Tim Songa6682b152020-11-03 21:24:24197 LogInterstitialScreenEvent(InterstitialScreenEvent::kShown);
Meilin Wang418ae712020-09-17 05:50:03198}
199
200OnboardingView::~OnboardingView() = default;
201
Meilin Wangd626fde2020-10-23 17:53:36202void OnboardingView::OnBubbleClose() {
203 main_view_->OnBubbleClose();
204}
205
Tim Song947932a2020-10-31 00:38:45206Screen OnboardingView::GetScreenForMetrics() const {
207 return main_view_->GetScreenForMetrics();
208}
209
Meilin Wangd626fde2020-10-23 17:53:36210void OnboardingView::ShowDismissPrompt() {
211 DCHECK(main_view_);
212
Tim Songa6682b152020-11-03 21:24:24213 LogInterstitialScreenEvent(InterstitialScreenEvent::kShown);
Tim Song947932a2020-10-31 00:38:45214
Meilin Wangd626fde2020-10-23 17:53:36215 RemoveChildView(main_view_);
216 main_view_ = AddChildView(
217 std::make_unique<OnboardingDismissPromptView>(onboarding_ui_tracker_));
218
Meilin Wang65319732020-11-06 20:03:18219 // We don't show status header view on top for the dismiss prompt.
220 DCHECK(delegate_);
221 delegate_->HideStatusHeaderView();
Meilin Wang418ae712020-09-17 05:50:03222}
223
224BEGIN_METADATA(OnboardingView, views::View)
225END_METADATA
226
227} // namespace ash