| // Copyright 2020 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/system/phonehub/onboarding_view.h" |
| |
| #include <algorithm> |
| #include <memory> |
| #include <vector> |
| |
| #include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h" |
| #include "ash/public/cpp/system_tray_client.h" |
| #include "ash/root_window_controller.h" |
| #include "ash/shell.h" |
| #include "ash/strings/grit/ash_strings.h" |
| #include "ash/style/ash_color_provider.h" |
| #include "ash/system/model/system_tray_model.h" |
| #include "ash/system/phonehub/interstitial_view_button.h" |
| #include "ash/system/phonehub/phone_hub_content_view.h" |
| #include "ash/system/phonehub/phone_hub_interstitial_view.h" |
| #include "ash/system/phonehub/phone_hub_metrics.h" |
| #include "ash/system/phonehub/phone_hub_tray.h" |
| #include "ash/system/phonehub/phone_hub_view_ids.h" |
| #include "ash/system/status_area_widget.h" |
| #include "ash/system/tray/tray_bubble_view.h" |
| #include "ash/system/unified/rounded_label_button.h" |
| #include "base/strings/strcat.h" |
| #include "base/strings/string16.h" |
| #include "chromeos/components/phonehub/onboarding_ui_tracker.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/chromeos/devicetype_utils.h" |
| #include "ui/views/layout/fill_layout.h" |
| #include "ui/views/metadata/metadata_impl_macros.h" |
| |
| namespace ash { |
| |
| using phone_hub_metrics::InterstitialScreenEvent; |
| using phone_hub_metrics::Screen; |
| |
| // OnboardingMainView --------------------------------------------------------- |
| // Main onboarding screen with Phone Hub feature description and two buttons |
| // (Get Started and Dismiss), where user can either choose to grant permission |
| // to enable this feature or dismiss the screen. |
| class OnboardingMainView : public PhoneHubInterstitialView { |
| public: |
| OnboardingMainView( |
| chromeos::phonehub::OnboardingUiTracker* onboarding_ui_tracker, |
| OnboardingView* parent_view, |
| OnboardingView::OnboardingFlow onboarding_flow) |
| : PhoneHubInterstitialView(/*show_progress=*/false), |
| onboarding_ui_tracker_(onboarding_ui_tracker), |
| parent_view_(parent_view), |
| onboarding_flow_(onboarding_flow) { |
| SetID(PhoneHubViewID::kOnboardingMainView); |
| InitLayout(); |
| } |
| |
| // PhoneHubInterstitialView: |
| Screen GetScreenForMetrics() const override { |
| switch (onboarding_flow_) { |
| case OnboardingView::kExistingMultideviceUser: |
| return Screen::kOnboardingExistingMultideviceUser; |
| case OnboardingView::kNewMultideviceUser: |
| return Screen::kOnboardingNewMultideviceUser; |
| } |
| } |
| |
| private: |
| void InitLayout() { |
| // TODO(crbug.com/1127996): Replace PNG file with vector icon. |
| gfx::ImageSkia* image = |
| ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| IDR_PHONE_HUB_ONBOARDING_IMAGE); |
| SetImage(*image); |
| SetTitle( |
| l10n_util::GetStringUTF16(IDS_ASH_PHONE_HUB_ONBOARDING_DIALOG_TITLE)); |
| SetDescription(l10n_util::GetStringFUTF16( |
| IDS_ASH_PHONE_HUB_ONBOARDING_DIALOG_DESCRIPTION, |
| ui::GetChromeOSDeviceName())); |
| |
| // Add "Dismiss" and "Get started" buttons. |
| auto dismiss = std::make_unique<InterstitialViewButton>( |
| base::BindRepeating(&OnboardingMainView::DismissButtonPressed, |
| base::Unretained(this)), |
| l10n_util::GetStringUTF16( |
| IDS_ASH_PHONE_HUB_ONBOARDING_DIALOG_DISMISS_BUTTON), |
| /*paint_background=*/false); |
| dismiss->SetEnabledTextColors(AshColorProvider::Get()->GetContentLayerColor( |
| AshColorProvider::ContentLayerType::kTextColorPrimary)); |
| dismiss->SetID(PhoneHubViewID::kOnboardingDismissButton); |
| AddButton(std::move(dismiss)); |
| |
| auto get_started = std::make_unique<InterstitialViewButton>( |
| base::BindRepeating(&OnboardingMainView::GetStartedButtonPressed, |
| base::Unretained(this)), |
| l10n_util::GetStringUTF16( |
| IDS_ASH_PHONE_HUB_ONBOARDING_DIALOG_GET_STARTED_BUTTON), |
| /*paint_background=*/true); |
| get_started->SetID(PhoneHubViewID::kOnboardingGetStartedButton); |
| AddButton(std::move(get_started)); |
| } |
| |
| void GetStartedButtonPressed() { |
| LogInterstitialScreenEvent(InterstitialScreenEvent::kConfirm); |
| onboarding_ui_tracker_->HandleGetStarted(); |
| } |
| |
| void DismissButtonPressed() { |
| LogInterstitialScreenEvent(InterstitialScreenEvent::kDismiss); |
| parent_view_->ShowDismissPrompt(); |
| } |
| |
| chromeos::phonehub::OnboardingUiTracker* onboarding_ui_tracker_ = nullptr; |
| OnboardingView* parent_view_ = nullptr; |
| const OnboardingView::OnboardingFlow onboarding_flow_; |
| }; |
| |
| // OnboardingDismissPromptView ------------------------------------------------ |
| // A follow-up prompt screen that pops up when the user has chosen to dismiss |
| // the main onboarding screen. It should not be shown again after being |
| // dismissed manually by either clicking the ack button or outside the bubble. |
| class OnboardingDismissPromptView : public PhoneHubInterstitialView { |
| public: |
| explicit OnboardingDismissPromptView( |
| chromeos::phonehub::OnboardingUiTracker* onboarding_ui_tracker) |
| : PhoneHubInterstitialView(/*show_progress=*/false, /*show_image=*/false), |
| onboarding_ui_tracker_(onboarding_ui_tracker) { |
| SetID(PhoneHubViewID::kOnboardingDismissPromptView); |
| InitLayout(); |
| } |
| |
| private: |
| void InitLayout() { |
| // Adds title and description. |
| SetTitle(l10n_util::GetStringUTF16( |
| IDS_ASH_PHONE_HUB_ONBOARDING_DISMISS_DIALOG_TITLE)); |
| base::string16 part1 = l10n_util::GetStringFUTF16( |
| IDS_ASH_PHONE_HUB_ONBOARDING_DISMISS_DIALOG_DESCRIPTION_PART_1, |
| ui::GetChromeOSDeviceName()); |
| base::string16 part2 = l10n_util::GetStringUTF16( |
| IDS_ASH_PHONE_HUB_ONBOARDING_DISMISS_DIALOG_DESCRIPTION_PART_2); |
| // Uses "\n" to create a newline separator between two text paragraphs. |
| SetDescription(base::StrCat({part1, base::ASCIIToUTF16("\n\n"), part2})); |
| |
| // Adds "Ok, got it" button. |
| auto ack_button = std::make_unique<InterstitialViewButton>( |
| base::BindRepeating(&OnboardingDismissPromptView::ButtonPressed, |
| base::Unretained(this)), |
| l10n_util::GetStringUTF16( |
| IDS_ASH_PHONE_HUB_ONBOARDING_DISMISS_DIALOG_OK_BUTTON), |
| /*paint_background=*/true); |
| ack_button->SetID(PhoneHubViewID::kOnboardingDismissAckButton); |
| AddButton(std::move(ack_button)); |
| } |
| |
| void ButtonPressed() { |
| LogInterstitialScreenEvent(InterstitialScreenEvent::kConfirm); |
| |
| Shell::GetPrimaryRootWindowController() |
| ->GetStatusAreaWidget() |
| ->phone_hub_tray() |
| ->CloseBubble(); |
| } |
| |
| // PhoneHubInterstitialView: |
| void OnBubbleClose() override { onboarding_ui_tracker_->DismissSetupUi(); } |
| |
| Screen GetScreenForMetrics() const override { |
| return Screen::kOnboardingDismissPrompt; |
| } |
| |
| chromeos::phonehub::OnboardingUiTracker* onboarding_ui_tracker_ = nullptr; |
| }; |
| |
| // OnboardingView ------------------------------------------------------------- |
| OnboardingView::OnboardingView( |
| chromeos::phonehub::OnboardingUiTracker* onboarding_ui_tracker, |
| Delegate* delegate, |
| OnboardingFlow onboarding_flow) |
| : onboarding_ui_tracker_(onboarding_ui_tracker), delegate_(delegate) { |
| SetID(PhoneHubViewID::kOnboardingView); |
| |
| SetLayoutManager(std::make_unique<views::FillLayout>()); |
| main_view_ = AddChildView(std::make_unique<OnboardingMainView>( |
| onboarding_ui_tracker_, this, onboarding_flow)); |
| |
| LogInterstitialScreenEvent(InterstitialScreenEvent::kShown); |
| } |
| |
| OnboardingView::~OnboardingView() = default; |
| |
| void OnboardingView::OnBubbleClose() { |
| main_view_->OnBubbleClose(); |
| } |
| |
| Screen OnboardingView::GetScreenForMetrics() const { |
| return main_view_->GetScreenForMetrics(); |
| } |
| |
| void OnboardingView::ShowDismissPrompt() { |
| DCHECK(main_view_); |
| |
| LogInterstitialScreenEvent(InterstitialScreenEvent::kShown); |
| |
| RemoveChildView(main_view_); |
| main_view_ = AddChildView( |
| std::make_unique<OnboardingDismissPromptView>(onboarding_ui_tracker_)); |
| |
| // We don't show status header view on top for the dismiss prompt. |
| DCHECK(delegate_); |
| delegate_->HideStatusHeaderView(); |
| } |
| |
| BEGIN_METADATA(OnboardingView, views::View) |
| END_METADATA |
| |
| } // namespace ash |