chromium/ash/system/phonehub/sub_feature_opt_in_view.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/phonehub/sub_feature_opt_in_view.h"

#include <string>

#include "ash/style/ash_color_provider.h"
#include "ash/style/pill_button.h"
#include "ash/style/typography.h"
#include "ash/system/phonehub/phone_hub_view_ids.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/chromeos/devicetype_utils.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/border.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout_view.h"
#include "ui/views/layout/flex_layout.h"
#include "ui/views/view_class_properties.h"
#include "url/gurl.h"

namespace ash {

namespace {

// Appearance.
constexpr int kButtonSpacingDip = 8;
constexpr int kBorderThicknessDip = 1;
constexpr int kBorderCornerRadiusDip = 8;
constexpr auto kTextLabelBorderInsets = gfx::Insets::TLBR(12, 16, 12, 16);
constexpr auto kButtonContainerBorderInsets = gfx::Insets::TLBR(0, 0, 12, 16);
constexpr int kTextLabelLineHeightDip = 20;

// Typography.
constexpr int kLabelTextFontSizeDip = 14;

int GetDescriptionStringId(
    PermissionsOnboardingSetUpMode permission_setup_mode) {
  switch (permission_setup_mode) {
    case PermissionsOnboardingSetUpMode::kCameraRoll:
      return IDS_ASH_PHONE_HUB_CAMERA_ROLL_OPT_IN_DESCRIPTION;
    case PermissionsOnboardingSetUpMode::kMessagingApps:
      return IDS_ASH_PHONE_HUB_APPS_OPT_IN_DESCRIPTION;
    case PermissionsOnboardingSetUpMode::kNotificationAndCameraRoll:
      return IDS_ASH_PHONE_HUB_NOTIFICATION_AND_CAMERA_ROLL_OPT_IN_DESCRIPTION;
    case PermissionsOnboardingSetUpMode::kNotification:
      return IDS_ASH_PHONE_HUB_NOTIFICATION_OPT_IN_DESCRIPTION;
    case PermissionsOnboardingSetUpMode::kNotificationAndMessagingApps:
      return IDS_ASH_PHONE_HUB_NOTIFICATION_AND_APPS_OPT_IN_DESCRIPTION;
    case PermissionsOnboardingSetUpMode::kMessagingAppsAndCameraRoll:
      return IDS_ASH_PHONE_HUB_CAMERA_ROLL_AND_APPS_OPT_IN_DESCRIPTION;
    case PermissionsOnboardingSetUpMode::kAllPermissions:
      return IDS_ASH_PHONE_HUB_ALL_FEATURES_OPT_IN_DESCRIPTION;
    case PermissionsOnboardingSetUpMode::kNone:
    default:
      // Just return the default strings since the MultideviceFeatureOptInView
      // will be invisible.
      return IDS_ASH_PHONE_HUB_NOTIFICATION_OPT_IN_DESCRIPTION;
  }
}

int GetSetUpButtonAccessibleNameStringId(
    PermissionsOnboardingSetUpMode permission_setup_mode) {
  switch (permission_setup_mode) {
    case PermissionsOnboardingSetUpMode::kCameraRoll:
      return IDS_ASH_PHONE_HUB_CAMERA_ROLL_OPT_IN_SET_UP_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kMessagingApps:
      return IDS_ASH_PHONE_HUB_APPS_OPT_IN_SET_UP_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kNotificationAndCameraRoll:
      return IDS_ASH_PHONE_HUB_NOTIFICATION_AND_CAMERA_ROLL_OPT_IN_SET_UP_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kNotification:
      return IDS_ASH_PHONE_HUB_NOTIFICATION_OPT_IN_SET_UP_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kNotificationAndMessagingApps:
      return IDS_ASH_PHONE_HUB_NOTIFICATION_AND_APPS_OPT_IN_SET_UP_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kMessagingAppsAndCameraRoll:
      return IDS_ASH_PHONE_HUB_CAMERA_ROLL_AND_APPS_OPT_IN_SET_UP_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kAllPermissions:
      return IDS_ASH_PHONE_HUB_ALL_FEATURES_OPT_IN_SET_UP_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kNone:
    default:
      // Just return the default strings since the MultideviceFeatureOptInView
      // will be invisible.
      return IDS_ASH_PHONE_HUB_NOTIFICATION_OPT_IN_SET_UP_BUTTON_ACCESSIBLE_NAME;
  }
}

int GetDismissButtonAccessibleNameStringId(
    PermissionsOnboardingSetUpMode permission_setup_mode) {
  switch (permission_setup_mode) {
    case PermissionsOnboardingSetUpMode::kCameraRoll:
      return IDS_ASH_PHONE_HUB_CAMERA_ROLL_OPT_IN_DISMISS_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kMessagingApps:
      return IDS_ASH_PHONE_HUB_APPS_OPT_IN_DISMISS_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kNotificationAndCameraRoll:
      return IDS_ASH_PHONE_HUB_NOTIFICATION_AND_CAMERA_ROLL_OPT_IN_DISMISS_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kNotification:
      return IDS_ASH_PHONE_HUB_NOTIFICATION_OPT_IN_DISMISS_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kNotificationAndMessagingApps:
      return IDS_ASH_PHONE_HUB_NOTIFICATION_AND_APPS_OPT_IN_DISMISS_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kMessagingAppsAndCameraRoll:
      return IDS_ASH_PHONE_HUB_CAMERA_ROLL_AND_APPS_OPT_IN_DISMISS_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kAllPermissions:
      return IDS_ASH_PHONE_HUB_ALL_FEATURES_OPT_IN_DISMISS_BUTTON_ACCESSIBLE_NAME;
    case PermissionsOnboardingSetUpMode::kNone:
    default:
      // Just return the default strings since the MultideviceFeatureOptInView
      // will be invisible.
      return IDS_ASH_PHONE_HUB_NOTIFICATION_OPT_IN_DISMISS_BUTTON_ACCESSIBLE_NAME;
  }
}

}  // namespace

SubFeatureOptInView::SubFeatureOptInView(
    PhoneHubViewID view_id,
    PermissionsOnboardingSetUpMode setup_mode)
    : view_id_(view_id), setup_mode_(setup_mode) {
  SetID(view_id_);
  InitLayout();
}

SubFeatureOptInView::~SubFeatureOptInView() = default;

void SubFeatureOptInView::SetSetUpMode(
    PermissionsOnboardingSetUpMode setup_mode) {
  setup_mode_ = setup_mode;
  SetStringIds();
  UpdateLabels();
}

void SubFeatureOptInView::SetStringIds() {
  description_string_id_ = GetDescriptionStringId(setup_mode_);
  set_up_button_accessible_name_string_id_ =
      GetSetUpButtonAccessibleNameStringId(setup_mode_);
  dismiss_button_accessible_name_string_id_ =
      GetDismissButtonAccessibleNameStringId(setup_mode_);
}

void SubFeatureOptInView::UpdateLabels() {
  text_label_->SetText(l10n_util::GetStringUTF16(description_string_id_));
  set_up_button_->GetViewAccessibility().SetName(
      l10n_util::GetStringUTF16(set_up_button_accessible_name_string_id_));
  dismiss_button_->GetViewAccessibility().SetName(
      l10n_util::GetStringUTF16(dismiss_button_accessible_name_string_id_));
}

void SubFeatureOptInView::InitLayout() {
  // TODO(b/322067753): Replace usage of |AshColorProvider| with |cros_tokens|.
  const SkColor border_color = AshColorProvider::Get()->GetContentLayerColor(
      AshColorProvider::ContentLayerType::kSeparatorColor);
  SetBorder(views::CreateRoundedRectBorder(
      kBorderThicknessDip, kBorderCornerRadiusDip, border_color));

  auto* layout = SetLayoutManager(std::make_unique<views::FlexLayout>());
  layout->SetOrientation(views::LayoutOrientation::kVertical);
  layout->SetMainAxisAlignment(views::LayoutAlignment::kCenter);

  SetStringIds();

  // Set up layout row for the text label.
  text_label_ = AddChildView(std::make_unique<views::Label>());
  text_label_->SetProperty(views::kCrossAxisAlignmentKey,
                           views::LayoutAlignment::kCenter);
  text_label_->SetProperty(views::kMarginsKey, kTextLabelBorderInsets);
  text_label_->SetProperty(
      views::kFlexBehaviorKey,
      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum,
                               views::MaximumFlexSizeRule::kUnbounded, true));
  auto text_color = AshColorProvider::Get()->GetContentLayerColor(
      AshColorProvider::ContentLayerType::kTextColorPrimary);
  text_label_->SetEnabledColor(text_color);
  text_label_->SetAutoColorReadabilityEnabled(false);
  auto default_font = text_label_->font_list();
  text_label_->SetFontList(default_font
                               .DeriveWithSizeDelta(kLabelTextFontSizeDip -
                                                    default_font.GetFontSize())
                               .DeriveWithWeight(gfx::Font::Weight::MEDIUM));
  text_label_->SetMultiLine(/*multi_line=*/true);
  text_label_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
  text_label_->SetText(l10n_util::GetStringUTF16(description_string_id_));

  TypographyProvider::Get()->StyleLabel(ash::TypographyToken::kCrosHeadline1,
                                        *text_label_);
  text_label_->SetLineHeight(kTextLabelLineHeightDip);

  // Set up layout row for the buttons.
  auto* button_container =
      AddChildView(std::make_unique<views::BoxLayoutView>());
  button_container->SetProperty(views::kCrossAxisAlignmentKey,
                                views::LayoutAlignment::kEnd);
  button_container->SetBetweenChildSpacing(kButtonSpacingDip);
  button_container->SetBorder(
      views::CreateEmptyBorder(kButtonContainerBorderInsets));
  dismiss_button_ = button_container->AddChildView(std::make_unique<PillButton>(
      base::BindRepeating(&SubFeatureOptInView::DismissButtonPressed,
                          base::Unretained(this)),
      l10n_util::GetStringUTF16(
          IDS_ASH_PHONE_HUB_SUB_FEATURE_OPT_IN_DISMISS_BUTTON),
      PillButton::Type::kFloatingWithoutIcon, /*icon=*/nullptr));
  dismiss_button_->SetID(kSubFeatureOptInDismissButton);
  dismiss_button_->GetViewAccessibility().SetName(
      l10n_util::GetStringUTF16(dismiss_button_accessible_name_string_id_));
  set_up_button_ = button_container->AddChildView(std::make_unique<PillButton>(
      base::BindRepeating(&SubFeatureOptInView::SetUpButtonPressed,
                          base::Unretained(this)),
      l10n_util::GetStringUTF16(
          IDS_ASH_PHONE_HUB_NOTIFICATION_OPT_IN_SET_UP_BUTTON),
      PillButton::Type::kPrimaryWithoutIcon, /*icon=*/nullptr));
  set_up_button_->SetID(kSubFeatureOptInConfirmButton);
  set_up_button_->GetViewAccessibility().SetName(
      l10n_util::GetStringUTF16(set_up_button_accessible_name_string_id_));

  // By default, the description will be set to the tooltip text, but the title
  // is already announced in the accessible name.
  set_up_button_->GetViewAccessibility().SetDescription(
      u"", ax::mojom::DescriptionFrom::kAttributeExplicitlyEmpty);
  dismiss_button_->GetViewAccessibility().SetDescription(
      u"", ax::mojom::DescriptionFrom::kAttributeExplicitlyEmpty);
}

BEGIN_METADATA(SubFeatureOptInView)
END_METADATA

}  // namespace ash