blob: da11825b4bd451fd17ea027dd5ccadb68e7c3630 [file] [log] [blame]
// Copyright 2021 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 "chrome/browser/ui/user_education/feature_promo_specification.h"
#include <string>
#include "base/feature_list.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/base/interaction/element_tracker.h"
#include "ui/base/l10n/l10n_util.h"
FeaturePromoSpecification::AcceleratorInfo::AcceleratorInfo() = default;
FeaturePromoSpecification::AcceleratorInfo::AcceleratorInfo(
const AcceleratorInfo& other) = default;
FeaturePromoSpecification::AcceleratorInfo::~AcceleratorInfo() = default;
FeaturePromoSpecification::AcceleratorInfo::AcceleratorInfo(ValueType value)
: value_(value) {}
FeaturePromoSpecification::AcceleratorInfo&
FeaturePromoSpecification::AcceleratorInfo::operator=(
const AcceleratorInfo& other) = default;
FeaturePromoSpecification::AcceleratorInfo&
FeaturePromoSpecification::AcceleratorInfo::operator=(ValueType value) {
value_ = value;
return *this;
}
FeaturePromoSpecification::AcceleratorInfo::operator bool() const {
return absl::holds_alternative<ui::Accelerator>(value_) ||
absl::get<int>(value_);
}
ui::Accelerator FeaturePromoSpecification::AcceleratorInfo::GetAccelerator(
const ui::AcceleratorProvider* provider) const {
if (absl::holds_alternative<ui::Accelerator>(value_))
return absl::get<ui::Accelerator>(value_);
const int command_id = absl::get<int>(value_);
DCHECK_GT(command_id, 0);
ui::Accelerator result;
DCHECK(provider->GetAcceleratorForCommandId(command_id, &result));
return result;
}
FeaturePromoSpecification::DemoPageInfo::DemoPageInfo(
std::string display_title_,
std::string display_description_,
base::RepeatingClosure setup_for_feature_promo_callback_)
: display_title(display_title_),
display_description(display_description_),
setup_for_feature_promo_callback(setup_for_feature_promo_callback_) {}
FeaturePromoSpecification::DemoPageInfo::DemoPageInfo(
const DemoPageInfo& other) = default;
FeaturePromoSpecification::DemoPageInfo::~DemoPageInfo() = default;
// static
constexpr HelpBubbleArrow FeaturePromoSpecification::kDefaultBubbleArrow;
FeaturePromoSpecification::FeaturePromoSpecification() = default;
FeaturePromoSpecification::FeaturePromoSpecification(
FeaturePromoSpecification&& other)
: feature_(std::exchange(other.feature_, nullptr)),
promo_type_(std::exchange(other.promo_type_, PromoType::kUnspecifiied)),
anchor_element_id_(
std::exchange(other.anchor_element_id_, ui::ElementIdentifier())),
anchor_element_filter_(std::move(other.anchor_element_filter_)),
bubble_body_string_id_(std::exchange(other.bubble_body_string_id_, 0)),
bubble_title_text_(std::move(other.bubble_title_text_)),
bubble_icon_(std::exchange(other.bubble_icon_, nullptr)),
bubble_arrow_(std::exchange(other.bubble_arrow_, kDefaultBubbleArrow)),
screen_reader_string_id_(
std::exchange(other.screen_reader_string_id_, 0)),
screen_reader_accelerator_(
std::exchange(other.screen_reader_accelerator_, AcceleratorInfo())),
demo_page_info_(std::exchange(other.demo_page_info_, DemoPageInfo())),
tutorial_id_(std::move(other.tutorial_id_)) {}
FeaturePromoSpecification::FeaturePromoSpecification(
const base::Feature* feature,
PromoType promo_type,
ui::ElementIdentifier anchor_element_id,
int bubble_body_string_id)
: feature_(feature),
promo_type_(promo_type),
anchor_element_id_(anchor_element_id),
bubble_body_string_id_(bubble_body_string_id),
demo_page_info_(DemoPageInfo(feature ? feature->name : std::string())) {
DCHECK_NE(promo_type, PromoType::kUnspecifiied);
DCHECK(bubble_body_string_id_);
}
FeaturePromoSpecification::~FeaturePromoSpecification() = default;
FeaturePromoSpecification& FeaturePromoSpecification::operator=(
FeaturePromoSpecification&& other) {
if (this != &other) {
feature_ = std::exchange(other.feature_, nullptr);
promo_type_ = std::exchange(other.promo_type_, PromoType::kUnspecifiied);
anchor_element_id_ =
std::exchange(other.anchor_element_id_, ui::ElementIdentifier());
anchor_element_filter_ = std::move(other.anchor_element_filter_);
bubble_body_string_id_ = std::exchange(other.bubble_body_string_id_, 0);
bubble_title_text_ = std::move(other.bubble_title_text_);
bubble_icon_ = std::exchange(other.bubble_icon_, nullptr);
bubble_arrow_ = std::exchange(other.bubble_arrow_, kDefaultBubbleArrow);
screen_reader_string_id_ = std::exchange(other.screen_reader_string_id_, 0);
screen_reader_accelerator_ =
std::exchange(other.screen_reader_accelerator_, AcceleratorInfo());
demo_page_info_ = std::exchange(other.demo_page_info_, DemoPageInfo());
tutorial_id_ = std::move(other.tutorial_id_);
}
return *this;
}
// static
FeaturePromoSpecification FeaturePromoSpecification::CreateForToastPromo(
const base::Feature& feature,
ui::ElementIdentifier anchor_element_id,
int body_text_string_id,
int accessible_text_string_id,
AcceleratorInfo accessible_accelerator) {
FeaturePromoSpecification spec(&feature, PromoType::kToast, anchor_element_id,
body_text_string_id);
spec.screen_reader_string_id_ = accessible_text_string_id;
spec.screen_reader_accelerator_ = std::move(accessible_accelerator);
return spec;
}
// static
FeaturePromoSpecification FeaturePromoSpecification::CreateForSnoozePromo(
const base::Feature& feature,
ui::ElementIdentifier anchor_element_id,
int body_text_string_id) {
return FeaturePromoSpecification(&feature, PromoType::kSnooze,
anchor_element_id, body_text_string_id);
}
// static
FeaturePromoSpecification FeaturePromoSpecification::CreateForTutorialPromo(
const base::Feature& feature,
ui::ElementIdentifier anchor_element_id,
int body_text_string_id,
TutorialIdentifier tutorial_id) {
FeaturePromoSpecification spec(&feature, PromoType::kTutorial,
anchor_element_id, body_text_string_id);
DCHECK(!tutorial_id.empty());
spec.tutorial_id_ = tutorial_id;
return spec;
}
// static
FeaturePromoSpecification FeaturePromoSpecification::CreateForLegacyPromo(
const base::Feature* feature,
ui::ElementIdentifier anchor_element_id,
int body_text_string_id) {
return FeaturePromoSpecification(feature, PromoType::kLegacy,
anchor_element_id, body_text_string_id);
}
FeaturePromoSpecification& FeaturePromoSpecification::SetBubbleTitleText(
int title_text_string_id) {
DCHECK_NE(promo_type_, PromoType::kUnspecifiied);
bubble_title_text_ = l10n_util::GetStringUTF16(title_text_string_id);
return *this;
}
FeaturePromoSpecification& FeaturePromoSpecification::SetBubbleIcon(
const gfx::VectorIcon* bubble_icon) {
DCHECK_NE(promo_type_, PromoType::kUnspecifiied);
bubble_icon_ = bubble_icon;
return *this;
}
FeaturePromoSpecification& FeaturePromoSpecification::SetBubbleArrow(
HelpBubbleArrow bubble_arrow) {
bubble_arrow_ = bubble_arrow;
return *this;
}
FeaturePromoSpecification& FeaturePromoSpecification::SetAnchorElementFilter(
AnchorElementFilter anchor_element_filter) {
anchor_element_filter_ = std::move(anchor_element_filter);
return *this;
}
FeaturePromoSpecification& FeaturePromoSpecification::SetDemoPageInfo(
DemoPageInfo demo_page_info) {
demo_page_info_ = std::move(demo_page_info);
return *this;
}
ui::TrackedElement* FeaturePromoSpecification::GetAnchorElement(
ui::ElementContext context) const {
auto* const element_tracker = ui::ElementTracker::GetElementTracker();
return anchor_element_filter_ ? anchor_element_filter_.Run(
element_tracker->GetAllMatchingElements(
anchor_element_id_, context))
: element_tracker->GetFirstMatchingElement(
anchor_element_id_, context);
}