[PhoneHub][Eche] Create connection error dialog
Created the error dialog that will open when user clicks on the warning icon if there is a network connection error. Screenshot: https://screenshot.googleplex.com/8Bukw64nbPYAVCs.png Tested: manually verified the dialog behavior. Bug: b/273664743 Change-Id: Ic3047c94e9807dc5606ef9609ffefa94bc526ac6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4336750 Reviewed-by: Crisrael Lucero <crisrael@google.com> Reviewed-by: Jon Mann <jonmann@chromium.org> Commit-Queue: Pu Shi <pushi@google.com> Cr-Commit-Position: refs/heads/main@{#1118416}
This commit is contained in:
@ -1638,6 +1638,8 @@ component("ash") {
|
||||
"system/palette/tools/magnifier_mode.h",
|
||||
"system/pcie_peripheral/pcie_peripheral_notification_controller.cc",
|
||||
"system/pcie_peripheral/pcie_peripheral_notification_controller.h",
|
||||
"system/phonehub/app_stream_connection_error_dialog.cc",
|
||||
"system/phonehub/app_stream_connection_error_dialog.h",
|
||||
"system/phonehub/app_stream_launcher_item.cc",
|
||||
"system/phonehub/app_stream_launcher_item.h",
|
||||
"system/phonehub/app_stream_launcher_list_item.cc",
|
||||
|
@ -6278,6 +6278,15 @@ New install
|
||||
<message name="ID_ASH_ECHE_APP_STREAMING_BUBBLE_TITLE" desc="The title appear on the top of app streaming bubble">
|
||||
From <ph name="PHONE_NAME">$1<ex>Pixel 7</ex></ph>
|
||||
</message>
|
||||
<message name="IDS_ASH_ECHE_APP_STREMING_ERROR_DIALOG_TITLE" desc="The title of dialog that appears when there is a connection error trying to stream app">
|
||||
Can't stream apps
|
||||
</message>
|
||||
<message name="IDS_ASH_ECHE_APP_STREMING_ERROR_DIALOG_MAIN_TEXT" desc="The main description in the dialog that appears when there is a connection error trying to stream app">
|
||||
This network doesn't support streaming apps from your phone. Try turning on your phone's hotspot. Learn more.
|
||||
</message>
|
||||
<message name="IDS_ASH_ECHE_APP_STREMING_ERROR_DIALOG_TURN_ON_HOTSPOT" desc="The button in the dialog that appears when there is a connection error trying to stream app to turn on hotspot">
|
||||
Turn on hotspot
|
||||
</message>
|
||||
|
||||
<!-- Deferred update dialog -->
|
||||
<message name="IDS_DEFERRED_UPDATE_DIALOG_TITLE" desc="Title of the dialog for notifying deferred update available to be applied.">
|
||||
|
@ -0,0 +1 @@
|
||||
d51a7b6fe868ca874bcde99c4ddc0404fdfac611
|
@ -0,0 +1 @@
|
||||
d51a7b6fe868ca874bcde99c4ddc0404fdfac611
|
@ -0,0 +1 @@
|
||||
d51a7b6fe868ca874bcde99c4ddc0404fdfac611
|
281
ash/system/phonehub/app_stream_connection_error_dialog.cc
Normal file
281
ash/system/phonehub/app_stream_connection_error_dialog.cc
Normal file
@ -0,0 +1,281 @@
|
||||
// Copyright 2023 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/app_stream_connection_error_dialog.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "ash/constants/ash_features.h"
|
||||
#include "ash/public/cpp/view_shadow.h"
|
||||
#include "ash/resources/vector_icons/vector_icons.h"
|
||||
#include "ash/strings/grit/ash_strings.h"
|
||||
#include "ash/style/ash_color_provider.h"
|
||||
#include "ash/style/pill_button.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/models/image_model.h"
|
||||
#include "ui/compositor/layer.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/gfx/geometry/size.h"
|
||||
#include "ui/gfx/geometry/transform.h"
|
||||
#include "ui/strings/grit/ui_strings.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/controls/image_view.h"
|
||||
#include "ui/views/controls/label.h"
|
||||
#include "ui/views/highlight_border.h"
|
||||
#include "ui/views/layout/box_layout.h"
|
||||
#include "ui/views/layout/flex_layout.h"
|
||||
#include "ui/views/view.h"
|
||||
#include "ui/views/view_class_properties.h"
|
||||
#include "ui/views/window/dialog_delegate.h"
|
||||
#include "ui/views/window/non_client_view.h"
|
||||
#include "ui/wm/core/coordinate_conversion.h"
|
||||
|
||||
namespace ash {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int kDialogVerticalMargin = 50;
|
||||
|
||||
constexpr int kDialogWidth = 330;
|
||||
|
||||
constexpr gfx::Insets kDialogContentInsets = gfx::Insets::VH(20, 24);
|
||||
constexpr float kDialogRoundedCornerRadius = 16.0f;
|
||||
constexpr int kDialogShadowElevation = 3;
|
||||
|
||||
constexpr int kIconSize = 25;
|
||||
|
||||
constexpr int kMarginBetweenIconAndTitle = 15;
|
||||
constexpr int kMarginBetweenTitleAndBody = 15;
|
||||
constexpr int kMarginBetweenBodyAndButtons = 20;
|
||||
constexpr int kMarginBetweenButtons = 8;
|
||||
|
||||
// The real error dialog with content.
|
||||
class ConnectionErrorDialogDelegateView : public views::WidgetDelegateView {
|
||||
public:
|
||||
explicit ConnectionErrorDialogDelegateView(
|
||||
StartTetheringCallback start_tethering_callback)
|
||||
: start_tethering_callback_(std::move(start_tethering_callback)) {
|
||||
SetModalType(ui::MODAL_TYPE_WINDOW);
|
||||
|
||||
SetPaintToLayer();
|
||||
layer()->SetBackgroundBlur(ColorProvider::kBackgroundBlurSigma);
|
||||
layer()->SetBackdropFilterQuality(ColorProvider::kBackgroundBlurQuality);
|
||||
|
||||
view_shadow_ = std::make_unique<ViewShadow>(this, kDialogShadowElevation);
|
||||
view_shadow_->SetRoundedCornerRadius(kDialogRoundedCornerRadius);
|
||||
|
||||
SetLayoutManager(std::make_unique<views::BoxLayout>(
|
||||
views::BoxLayout::Orientation::kVertical, kDialogContentInsets));
|
||||
|
||||
// Add info icon.
|
||||
auto* icon_row = AddChildView(std::make_unique<views::View>());
|
||||
icon_row
|
||||
->SetLayoutManager(std::make_unique<views::BoxLayout>(
|
||||
views::BoxLayout::Orientation::kHorizontal, gfx::Insets()))
|
||||
->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart);
|
||||
icon_ = icon_row->AddChildView(
|
||||
std::make_unique<views::ImageView>(ui::ImageModel::FromVectorIcon(
|
||||
kPhoneHubEcheErrorStatusIcon,
|
||||
AshColorProvider::Get()->GetContentLayerColor(
|
||||
AshColorProvider::ContentLayerType::kIconColorWarning),
|
||||
kIconSize)));
|
||||
|
||||
// Add dialog title.
|
||||
title_ =
|
||||
AddChildView(std::make_unique<views::Label>(l10n_util::GetStringUTF16(
|
||||
IDS_ASH_ECHE_APP_STREMING_ERROR_DIALOG_TITLE)));
|
||||
title_->SetProperty(views::kMarginsKey,
|
||||
gfx::Insets::TLBR(kMarginBetweenIconAndTitle, 0, 0, 0));
|
||||
title_->SetTextContext(views::style::CONTEXT_DIALOG_TITLE);
|
||||
title_->SetTextStyle(views::style::STYLE_EMPHASIZED);
|
||||
title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
||||
title_->SetAutoColorReadabilityEnabled(false);
|
||||
|
||||
title_->SetPaintToLayer();
|
||||
title_->layer()->SetFillsBoundsOpaquely(false);
|
||||
|
||||
// Add dialog body.
|
||||
// TODO(b/273822975): change Learn More to link.
|
||||
body_ =
|
||||
AddChildView(std::make_unique<views::Label>(l10n_util::GetStringUTF16(
|
||||
IDS_ASH_ECHE_APP_STREMING_ERROR_DIALOG_MAIN_TEXT)));
|
||||
body_->SetProperty(views::kMarginsKey,
|
||||
gfx::Insets::TLBR(kMarginBetweenTitleAndBody, 0,
|
||||
kMarginBetweenBodyAndButtons, 0));
|
||||
body_->SetTextContext(views::style::CONTEXT_DIALOG_BODY_TEXT);
|
||||
body_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
||||
body_->SetMultiLine(true);
|
||||
body_->SetAllowCharacterBreak(true);
|
||||
body_->SetAutoColorReadabilityEnabled(false);
|
||||
|
||||
body_->SetPaintToLayer();
|
||||
body_->layer()->SetFillsBoundsOpaquely(false);
|
||||
|
||||
// Add button row.
|
||||
auto* button_row = AddChildView(std::make_unique<views::View>());
|
||||
button_row
|
||||
->SetLayoutManager(std::make_unique<views::BoxLayout>(
|
||||
views::BoxLayout::Orientation::kHorizontal, gfx::Insets(),
|
||||
kMarginBetweenButtons))
|
||||
->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kEnd);
|
||||
|
||||
cancel_button_ = button_row->AddChildView(std::make_unique<ash::PillButton>(
|
||||
views::Button::PressedCallback(base::BindRepeating(
|
||||
&ConnectionErrorDialogDelegateView::OnCancelClicked,
|
||||
base::Unretained(this))),
|
||||
l10n_util::GetStringUTF16(IDS_APP_CANCEL),
|
||||
PillButton::Type::kDefaultWithoutIcon, nullptr));
|
||||
accept_button_ = button_row->AddChildView(std::make_unique<ash::PillButton>(
|
||||
views::Button::PressedCallback(base::BindRepeating(
|
||||
&ConnectionErrorDialogDelegateView::OnStartTetheringClicked,
|
||||
base::Unretained(this))),
|
||||
l10n_util::GetStringUTF16(
|
||||
IDS_ASH_ECHE_APP_STREMING_ERROR_DIALOG_TURN_ON_HOTSPOT),
|
||||
PillButton::Type::kPrimaryWithoutIcon, nullptr));
|
||||
}
|
||||
|
||||
ConnectionErrorDialogDelegateView(const ConnectionErrorDialogDelegateView&) =
|
||||
delete;
|
||||
ConnectionErrorDialogDelegateView& operator=(
|
||||
const ConnectionErrorDialogDelegateView&) = delete;
|
||||
|
||||
~ConnectionErrorDialogDelegateView() override = default;
|
||||
|
||||
// views::View:
|
||||
const char* GetClassName() const override {
|
||||
return "ConnectionErrorDialogDelegateView";
|
||||
}
|
||||
|
||||
gfx::Size CalculatePreferredSize() const override {
|
||||
return gfx::Size(kDialogWidth, GetHeightForWidth(kDialogWidth));
|
||||
}
|
||||
|
||||
void OnThemeChanged() override {
|
||||
views::WidgetDelegateView::OnThemeChanged();
|
||||
|
||||
SetBackground(views::CreateRoundedRectBackground(
|
||||
AshColorProvider::Get()->GetBaseLayerColor(
|
||||
AshColorProvider::BaseLayerType::kTransparent80),
|
||||
kDialogRoundedCornerRadius));
|
||||
SetBorder(std::make_unique<views::HighlightBorder>(
|
||||
kDialogRoundedCornerRadius,
|
||||
views::HighlightBorder::Type::kHighlightBorder1,
|
||||
/*use_light_colors=*/false));
|
||||
title_->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor(
|
||||
AshColorProvider::ContentLayerType::kTextColorPrimary));
|
||||
body_->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor(
|
||||
AshColorProvider::ContentLayerType::kTextColorPrimary));
|
||||
}
|
||||
|
||||
void OnStartTetheringClicked() {
|
||||
if (start_tethering_callback_) {
|
||||
std::move(start_tethering_callback_).Run();
|
||||
}
|
||||
|
||||
GetWidget()->CloseWithReason(
|
||||
views::Widget::ClosedReason::kAcceptButtonClicked);
|
||||
}
|
||||
|
||||
void OnCancelClicked() {
|
||||
GetWidget()->CloseWithReason(
|
||||
views::Widget::ClosedReason::kCancelButtonClicked);
|
||||
}
|
||||
|
||||
private:
|
||||
StartTetheringCallback start_tethering_callback_;
|
||||
std::unique_ptr<ViewShadow> view_shadow_;
|
||||
|
||||
views::ImageView* icon_ = nullptr;
|
||||
views::Label* title_ = nullptr;
|
||||
views::Label* body_ = nullptr;
|
||||
views::Button* cancel_button_ = nullptr;
|
||||
views::Button* accept_button_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
AppStreamConnectionErrorDialog::AppStreamConnectionErrorDialog(
|
||||
views::View* host_view,
|
||||
base::OnceClosure on_close_callback,
|
||||
StartTetheringCallback button_callback)
|
||||
: host_view_(host_view), on_close_callback_(std::move(on_close_callback)) {
|
||||
auto dialog = std::make_unique<ConnectionErrorDialogDelegateView>(
|
||||
std::move(button_callback));
|
||||
views::Widget* const parent = host_view_->GetWidget();
|
||||
|
||||
widget_ = new views::Widget();
|
||||
views::Widget::InitParams params;
|
||||
|
||||
params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
|
||||
params.layer_type = ui::LAYER_NOT_DRAWN;
|
||||
params.parent = parent->GetNativeWindow();
|
||||
params.delegate = dialog.release();
|
||||
|
||||
widget_->Init(std::move(params));
|
||||
|
||||
// The |dialog| ownership is passed to the window hierarchy.
|
||||
widget_observations_.AddObservation(widget_);
|
||||
widget_observations_.AddObservation(parent);
|
||||
|
||||
view_observations_.AddObservation(host_view_);
|
||||
view_observations_.AddObservation(widget_->GetContentsView());
|
||||
}
|
||||
|
||||
AppStreamConnectionErrorDialog::~AppStreamConnectionErrorDialog() {
|
||||
view_observations_.RemoveAllObservations();
|
||||
widget_observations_.RemoveAllObservations();
|
||||
if (widget_) {
|
||||
widget_->Close();
|
||||
widget_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AppStreamConnectionErrorDialog::UpdateBounds() {
|
||||
if (!widget_) {
|
||||
return;
|
||||
}
|
||||
|
||||
gfx::Point anchor_point_in_screen(host_view_->width() / 2, 0);
|
||||
views::View::ConvertPointToScreen(host_view_, &anchor_point_in_screen);
|
||||
|
||||
const int offset_for_frame_insets =
|
||||
widget_->non_client_view() && widget_->non_client_view()->frame_view()
|
||||
? widget_->non_client_view()->frame_view()->GetInsets().top()
|
||||
: 0;
|
||||
const int vertical_offset = kDialogVerticalMargin - offset_for_frame_insets;
|
||||
|
||||
gfx::Size dialog_size = widget_->GetContentsView()->GetPreferredSize();
|
||||
widget_->SetBounds(
|
||||
gfx::Rect(gfx::Point(anchor_point_in_screen.x() - dialog_size.width() / 2,
|
||||
anchor_point_in_screen.y() + vertical_offset),
|
||||
dialog_size));
|
||||
}
|
||||
|
||||
void AppStreamConnectionErrorDialog::OnWidgetDestroying(views::Widget* widget) {
|
||||
if (on_close_callback_) {
|
||||
std::move(on_close_callback_).Run();
|
||||
}
|
||||
}
|
||||
|
||||
void AppStreamConnectionErrorDialog::OnWidgetBoundsChanged(
|
||||
views::Widget* widget,
|
||||
const gfx::Rect& new_bounds) {
|
||||
if (widget == host_view_->GetWidget()) {
|
||||
UpdateBounds();
|
||||
}
|
||||
}
|
||||
|
||||
void AppStreamConnectionErrorDialog::OnViewBoundsChanged(
|
||||
views::View* observed_view) {
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void AppStreamConnectionErrorDialog::OnViewPreferredSizeChanged(
|
||||
views::View* observed_view) {
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
} // namespace ash
|
69
ash/system/phonehub/app_stream_connection_error_dialog.h
Normal file
69
ash/system/phonehub/app_stream_connection_error_dialog.h
Normal file
@ -0,0 +1,69 @@
|
||||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ASH_SYSTEM_PHONEHUB_APP_STREAM_CONNECTION_ERROR_DIALOG_H_
|
||||
#define ASH_SYSTEM_PHONEHUB_APP_STREAM_CONNECTION_ERROR_DIALOG_H_
|
||||
|
||||
#include "ash/ash_export.h"
|
||||
#include "base/functional/callback.h"
|
||||
#include "base/scoped_multi_source_observation.h"
|
||||
#include "ui/views/view_observer.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/widget/widget_observer.h"
|
||||
|
||||
namespace gfx {
|
||||
class Rect;
|
||||
}
|
||||
|
||||
using StartTetheringCallback = base::OnceCallback<void()>;
|
||||
|
||||
namespace ash {
|
||||
|
||||
// A view to anchor error dialog to Phone Hub bubble.
|
||||
class ASH_EXPORT AppStreamConnectionErrorDialog : public views::WidgetObserver,
|
||||
public views::ViewObserver {
|
||||
public:
|
||||
// TODO(b/273823160): Make the callback name more generic and take in strings
|
||||
// as parameters to make the dialog available in other locations.
|
||||
AppStreamConnectionErrorDialog(
|
||||
views::View* host_view,
|
||||
base::OnceClosure on_close_callback,
|
||||
StartTetheringCallback start_tethering_callback);
|
||||
AppStreamConnectionErrorDialog(const AppStreamConnectionErrorDialog& other) =
|
||||
delete;
|
||||
AppStreamConnectionErrorDialog& operator=(
|
||||
const AppStreamConnectionErrorDialog& other) = delete;
|
||||
~AppStreamConnectionErrorDialog() override;
|
||||
|
||||
// Repositions the dialog widget bounds relative to the current host view
|
||||
// bounds.
|
||||
void UpdateBounds();
|
||||
|
||||
// views::WidgetObserver:
|
||||
void OnWidgetDestroying(views::Widget* widget) override;
|
||||
void OnWidgetBoundsChanged(views::Widget* widget,
|
||||
const gfx::Rect& new_bounds) override;
|
||||
|
||||
// views::ViewObserver:
|
||||
void OnViewBoundsChanged(views::View* observed_view) override;
|
||||
void OnViewPreferredSizeChanged(views::View* observed_view) override;
|
||||
|
||||
views::Widget* widget() { return widget_; }
|
||||
|
||||
private:
|
||||
views::Widget* widget_ = nullptr;
|
||||
|
||||
views::View* const host_view_;
|
||||
|
||||
base::OnceClosure on_close_callback_;
|
||||
|
||||
base::ScopedMultiSourceObservation<views::Widget, views::WidgetObserver>
|
||||
widget_observations_{this};
|
||||
base::ScopedMultiSourceObservation<views::View, views::ViewObserver>
|
||||
view_observations_{this};
|
||||
};
|
||||
|
||||
} // namespace ash
|
||||
|
||||
#endif // ASH_SYSTEM_PHONEHUB_APP_STREAM_CONNECTION_ERROR_DIALOG_H_
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "ash/constants/ash_features.h"
|
||||
#include "ash/style/ash_color_provider.h"
|
||||
#include "ash/system/phonehub/app_stream_connection_error_dialog.h"
|
||||
#include "ash/system/phonehub/camera_roll_view.h"
|
||||
#include "ash/system/phonehub/multidevice_feature_opt_in_view.h"
|
||||
#include "ash/system/phonehub/phone_hub_recent_apps_view.h"
|
||||
@ -17,6 +18,7 @@
|
||||
#include "ash/system/phonehub/task_continuation_view.h"
|
||||
#include "ash/system/phonehub/ui_constants.h"
|
||||
#include "ash/system/tray/tray_constants.h"
|
||||
#include "chromeos/ash/components/multidevice/logging/logging.h"
|
||||
#include "chromeos/ash/components/phonehub/multidevice_feature_access_manager.h"
|
||||
#include "chromeos/ash/components/phonehub/phone_hub_manager.h"
|
||||
#include "chromeos/ash/components/phonehub/ping_manager.h"
|
||||
@ -89,7 +91,7 @@ PhoneConnectedView::PhoneConnectedView(
|
||||
phone_hub_manager->GetRecentAppsInteractionHandler();
|
||||
if (features::IsEcheSWAEnabled() && recent_apps_handler) {
|
||||
setup_layered_view(AddChildView(std::make_unique<PhoneHubRecentAppsView>(
|
||||
recent_apps_handler, phone_hub_manager)));
|
||||
recent_apps_handler, phone_hub_manager, this)));
|
||||
}
|
||||
|
||||
auto* ping_manager = phone_hub_manager->GetPingManager();
|
||||
@ -135,4 +137,26 @@ phone_hub_metrics::Screen PhoneConnectedView::GetScreenForMetrics() const {
|
||||
return phone_hub_metrics::Screen::kPhoneConnected;
|
||||
}
|
||||
|
||||
void PhoneConnectedView::ShowAppStreamErrorDialog() {
|
||||
if (!features::IsEcheNetworkConnectionStateEnabled()) {
|
||||
return;
|
||||
}
|
||||
app_stream_error_dialog_ = std::make_unique<AppStreamConnectionErrorDialog>(
|
||||
this,
|
||||
base::BindOnce(&PhoneConnectedView::OnAppStreamErrorDialogClosed,
|
||||
base::Unretained(this)),
|
||||
base::BindOnce(&PhoneConnectedView::OnAppStreamErrorDialogButtonClicked,
|
||||
base::Unretained(this)));
|
||||
app_stream_error_dialog_->UpdateBounds();
|
||||
app_stream_error_dialog_->widget()->Show();
|
||||
}
|
||||
|
||||
void PhoneConnectedView::OnAppStreamErrorDialogClosed() {
|
||||
app_stream_error_dialog_.reset();
|
||||
}
|
||||
|
||||
void PhoneConnectedView::OnAppStreamErrorDialogButtonClicked() {
|
||||
// TODO(b/273823627): Add method to enable hotspot.
|
||||
}
|
||||
|
||||
} // namespace ash
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define ASH_SYSTEM_PHONEHUB_PHONE_CONNECTED_VIEW_H_
|
||||
|
||||
#include "ash/ash_export.h"
|
||||
#include "ash/system/phonehub/app_stream_connection_error_dialog.h"
|
||||
#include "ash/system/phonehub/phone_hub_content_view.h"
|
||||
#include "chromeos/ash/components/phonehub/phone_hub_manager.h"
|
||||
#include "ui/views/view.h"
|
||||
@ -31,8 +32,15 @@ class PhoneConnectedView : public PhoneHubContentView {
|
||||
// PhoneHubContentView:
|
||||
phone_hub_metrics::Screen GetScreenForMetrics() const override;
|
||||
|
||||
void ShowAppStreamErrorDialog();
|
||||
|
||||
private:
|
||||
void OnAppStreamErrorDialogClosed();
|
||||
|
||||
void OnAppStreamErrorDialogButtonClicked();
|
||||
|
||||
phonehub::PhoneHubManager* phone_hub_manager_;
|
||||
std::unique_ptr<AppStreamConnectionErrorDialog> app_stream_error_dialog_;
|
||||
};
|
||||
|
||||
} // namespace ash
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "ash/strings/grit/ash_strings.h"
|
||||
#include "ash/style/ash_color_id.h"
|
||||
#include "ash/style/ash_color_provider.h"
|
||||
#include "ash/system/phonehub/phone_connected_view.h"
|
||||
#include "ash/system/phonehub/phone_hub_more_apps_button.h"
|
||||
#include "ash/system/phonehub/phone_hub_recent_app_button.h"
|
||||
#include "ash/system/phonehub/phone_hub_view_ids.h"
|
||||
@ -28,6 +29,7 @@
|
||||
#include "ui/gfx/image/image_skia_operations.h"
|
||||
#include "ui/gfx/paint_vector_icon.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
|
||||
#include "ui/views/controls/button/image_button.h"
|
||||
#include "ui/views/controls/label.h"
|
||||
#include "ui/views/layout/box_layout.h"
|
||||
@ -67,7 +69,7 @@ constexpr int kRecentAppsHeaderSpacing = 220;
|
||||
|
||||
class HeaderView : public views::View {
|
||||
public:
|
||||
HeaderView() {
|
||||
explicit HeaderView(views::ImageButton::PressedCallback callback) {
|
||||
auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>());
|
||||
layout->set_main_axis_alignment(
|
||||
views::BoxLayout::MainAxisAlignment::kCenter);
|
||||
@ -92,7 +94,8 @@ class HeaderView : public views::View {
|
||||
AshColorProvider::ContentLayerType::kTextColorPrimary));
|
||||
|
||||
if (features::IsEcheNetworkConnectionStateEnabled()) {
|
||||
error_button_ = AddChildView(std::make_unique<views::ImageButton>());
|
||||
error_button_ =
|
||||
AddChildView(std::make_unique<views::ImageButton>(callback));
|
||||
gfx::ImageSkia image = gfx::CreateVectorIcon(
|
||||
kPhoneHubEcheErrorStatusIcon,
|
||||
AshColorProvider::Get()->GetContentLayerColor(
|
||||
@ -138,15 +141,19 @@ class PhoneHubRecentAppsView::PlaceholderView : public views::Label {
|
||||
|
||||
PhoneHubRecentAppsView::PhoneHubRecentAppsView(
|
||||
phonehub::RecentAppsInteractionHandler* recent_apps_interaction_handler,
|
||||
phonehub::PhoneHubManager* phone_hub_manager)
|
||||
phonehub::PhoneHubManager* phone_hub_manager,
|
||||
PhoneConnectedView* connected_view)
|
||||
: recent_apps_interaction_handler_(recent_apps_interaction_handler),
|
||||
phone_hub_manager_(phone_hub_manager) {
|
||||
phone_hub_manager_(phone_hub_manager),
|
||||
connected_view_(connected_view) {
|
||||
SetID(PhoneHubViewID::kPhoneHubRecentAppsView);
|
||||
auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
|
||||
views::BoxLayout::Orientation::kVertical));
|
||||
layout->set_cross_axis_alignment(
|
||||
views::BoxLayout::CrossAxisAlignment::kStart);
|
||||
AddChildView(std::make_unique<HeaderView>());
|
||||
AddChildView(std::make_unique<HeaderView>(
|
||||
base::BindRepeating(&PhoneHubRecentAppsView::ShowConnectionErrorDialog,
|
||||
base::Unretained(this))));
|
||||
recent_app_buttons_view_ =
|
||||
AddChildView(std::make_unique<RecentAppButtonsView>());
|
||||
placeholder_view_ = AddChildView(std::make_unique<PlaceholderView>());
|
||||
@ -316,6 +323,12 @@ void PhoneHubRecentAppsView::SwitchToFullAppsList() {
|
||||
->SetShouldShowMiniLauncher(true);
|
||||
}
|
||||
|
||||
void PhoneHubRecentAppsView::ShowConnectionErrorDialog() {
|
||||
if (features::IsEcheNetworkConnectionStateEnabled()) {
|
||||
connected_view_->ShowAppStreamErrorDialog();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<views::View> PhoneHubRecentAppsView::GenerateMoreAppsButton() {
|
||||
if (features::IsEcheLauncherIconsInMoreAppsButtonEnabled()) {
|
||||
return std::make_unique<PhoneHubMoreAppsButton>(
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "ash/ash_export.h"
|
||||
#include "ash/system/phonehub/phone_connected_view.h"
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "chromeos/ash/components/phonehub/recent_apps_interaction_handler.h"
|
||||
#include "ui/views/controls/button/image_button.h"
|
||||
@ -28,7 +29,8 @@ class ASH_EXPORT PhoneHubRecentAppsView
|
||||
public:
|
||||
explicit PhoneHubRecentAppsView(
|
||||
phonehub::RecentAppsInteractionHandler* recent_apps_interaction_handler,
|
||||
phonehub::PhoneHubManager* phone_hub_manager);
|
||||
phonehub::PhoneHubManager* phone_hub_manager,
|
||||
PhoneConnectedView* connected_view);
|
||||
~PhoneHubRecentAppsView() override;
|
||||
PhoneHubRecentAppsView(PhoneHubRecentAppsView&) = delete;
|
||||
PhoneHubRecentAppsView operator=(PhoneHubRecentAppsView&) = delete;
|
||||
@ -73,6 +75,8 @@ class ASH_EXPORT PhoneHubRecentAppsView
|
||||
// Switch to full apps list view.
|
||||
void SwitchToFullAppsList();
|
||||
|
||||
void ShowConnectionErrorDialog();
|
||||
|
||||
// Generate more apps button.
|
||||
std::unique_ptr<views::View> GenerateMoreAppsButton();
|
||||
|
||||
@ -82,6 +86,7 @@ class ASH_EXPORT PhoneHubRecentAppsView
|
||||
nullptr;
|
||||
phonehub::PhoneHubManager* phone_hub_manager_ = nullptr;
|
||||
PlaceholderView* placeholder_view_ = nullptr;
|
||||
PhoneConnectedView* connected_view_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace ash
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "ash/system/phonehub/phone_hub_recent_apps_view.h"
|
||||
|
||||
#include "ash/constants/ash_features.h"
|
||||
#include "ash/system/phonehub/phone_connected_view.h"
|
||||
#include "ash/system/phonehub/phone_hub_recent_app_button.h"
|
||||
#include "ash/test/ash_test_base.h"
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
@ -45,7 +46,8 @@ class RecentAppButtonsViewTest : public AshTestBase {
|
||||
/*disabled_features=*/{});
|
||||
|
||||
phone_hub_recent_apps_view_ = std::make_unique<PhoneHubRecentAppsView>(
|
||||
&fake_recent_apps_interaction_handler_, &fake_phone_hub_manager_);
|
||||
&fake_recent_apps_interaction_handler_, &fake_phone_hub_manager_,
|
||||
connected_view_);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
@ -90,6 +92,7 @@ class RecentAppButtonsViewTest : public AshTestBase {
|
||||
phonehub::FakeRecentAppsInteractionHandler
|
||||
fake_recent_apps_interaction_handler_;
|
||||
phonehub::FakePhoneHubManager fake_phone_hub_manager_;
|
||||
PhoneConnectedView* connected_view_;
|
||||
base::test::ScopedFeatureList feature_list_;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user