diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:20:33 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:28:57 +0000 |
commit | d17ea114e5ef69ad5d5d7413280a13e6428098aa (patch) | |
tree | 2c01a75df69f30d27b1432467cfe7c1467a498da /chromium/ui/arc/notification | |
parent | 8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (diff) | |
download | qtwebengine-chromium-d17ea114e5ef69ad5d5d7413280a13e6428098aa.tar.gz |
BASELINE: Update Chromium to 67.0.3396.47
Change-Id: Idcb1341782e417561a2473eeecc82642dafda5b7
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/ui/arc/notification')
18 files changed, 523 insertions, 512 deletions
diff --git a/chromium/ui/arc/notification/arc_notification_content_view.cc b/chromium/ui/arc/notification/arc_notification_content_view.cc index baecc8484c1..9a3ad45d84e 100644 --- a/chromium/ui/arc/notification/arc_notification_content_view.cc +++ b/chromium/ui/arc/notification/arc_notification_content_view.cc @@ -6,7 +6,6 @@ #include "ash/wm/window_util.h" #include "base/auto_reset.h" -#include "base/memory/ptr_util.h" #include "components/exo/notification_surface.h" #include "components/exo/surface.h" #include "ui/accessibility/ax_node_data.h" @@ -18,8 +17,9 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/transform.h" +#include "ui/message_center/message_center.h" #include "ui/message_center/public/cpp/message_center_constants.h" -#include "ui/message_center/views/notification_control_buttons_view.h" +#include "ui/message_center/public/cpp/notification.h" #include "ui/strings/grit/ui_strings.h" #include "ui/views/focus/focus_manager.h" #include "ui/views/widget/root_view.h" @@ -231,50 +231,19 @@ class ArcNotificationContentView::SlideHelper DISALLOW_COPY_AND_ASSIGN(SlideHelper); }; -class ArcNotificationContentView::ContentViewDelegate - : public ArcNotificationContentViewDelegate { - public: - explicit ContentViewDelegate(ArcNotificationContentView* owner) - : owner_(owner) {} - - void UpdateControlButtonsVisibility() override { - owner_->UpdateControlButtonsVisibility(); - } - - void OnSlideChanged() override { - if (owner_->slide_helper_) - owner_->slide_helper_->Update(); - } - - message_center::NotificationControlButtonsView* GetControlButtonsView() - const override { - return owner_->control_buttons_view_; - } - - void OnContainerAnimationStarted() override { - owner_->OnContainerAnimationStarted(); - } - - void OnContainerAnimationEnded() override { - owner_->OnContainerAnimationEnded(); - } - - private: - ArcNotificationContentView* const owner_; - - DISALLOW_COPY_AND_ASSIGN(ContentViewDelegate); -}; - // static, for ArcNotificationContentView::GetClassName(). const char ArcNotificationContentView::kViewClassName[] = "ArcNotificationContentView"; ArcNotificationContentView::ArcNotificationContentView( - ArcNotificationItem* item) + ArcNotificationItem* item, + const message_center::Notification& notification, + message_center::MessageView* message_view) : item_(item), notification_key_(item->GetNotificationKey()), event_forwarder_(new EventForwarder(this)), - mouse_enter_exit_handler_(new MouseEnterExitHandler(this)) { + mouse_enter_exit_handler_(new MouseEnterExitHandler(this)), + control_buttons_view_(message_view) { // kNotificationWidth must be 360, since this value is separately defiend in // ArcNotificationWrapperView class in Android side. DCHECK_EQ(360, message_center::kNotificationWidth); @@ -294,10 +263,17 @@ ArcNotificationContentView::ArcNotificationContentView( OnNotificationSurfaceAdded(surface); } + // Creates the control_buttons_view_, which collects all control buttons into + // a horizontal box. + control_buttons_view_.set_owned_by_client(); + control_buttons_view_.SetBackgroundColor( + GetControlButtonBackgroundColor(item_->GetShownContents())); + + Update(message_view, notification); + // Create a layer as an anchor to insert surface copy during a slide. SetPaintToLayer(); UpdatePreferredSize(); - UpdateAccessibleName(); } ArcNotificationContentView::~ArcNotificationContentView() { @@ -316,10 +292,66 @@ const char* ArcNotificationContentView::GetClassName() const { return kViewClassName; } -std::unique_ptr<ArcNotificationContentViewDelegate> -ArcNotificationContentView::CreateContentViewDelegate() { - return std::make_unique<ArcNotificationContentView::ContentViewDelegate>( - this); +void ArcNotificationContentView::Update( + message_center::MessageView* message_view, + const message_center::Notification& notification) { + control_buttons_view_.ShowSettingsButton( + notification.should_show_settings_button()); + control_buttons_view_.ShowCloseButton(!message_view->GetPinned()); + control_buttons_view_.SetBackgroundColor( + GetControlButtonBackgroundColor(item_->GetShownContents())); + UpdateControlButtonsVisibility(); + + accessible_name_ = notification.accessible_name(); + UpdateSnapshot(); +} + +message_center::NotificationControlButtonsView* +ArcNotificationContentView::GetControlButtonsView() { + // |control_buttons_view_| is hosted in |floating_control_buttons_widget_| and + // should not be used when there is no |floating_control_buttons_widget_|. + return floating_control_buttons_widget_ ? &control_buttons_view_ : nullptr; +} + +void ArcNotificationContentView::UpdateControlButtonsVisibility() { + if (!control_buttons_view_.parent()) + return; + + // If the visibility change is ongoing, skip this method to prevent an + // infinite loop. + if (updating_control_buttons_visibility_) + return; + + DCHECK(floating_control_buttons_widget_); + + const bool target_visiblity = + IsMouseHovered() || (control_buttons_view_.IsCloseButtonFocused()) || + (control_buttons_view_.IsSettingsButtonFocused()); + + if (target_visiblity == floating_control_buttons_widget_->IsVisible()) + return; + + // Add the guard to prevent an infinite loop. Changing visibility may generate + // an event and it may call thie method again. + base::AutoReset<bool> reset(&updating_control_buttons_visibility_, true); + + if (target_visiblity) + floating_control_buttons_widget_->Show(); + else + floating_control_buttons_widget_->Hide(); +} + +void ArcNotificationContentView::OnSlideChanged() { + if (slide_helper_) + slide_helper_->Update(); +} + +void ArcNotificationContentView::OnContainerAnimationStarted() { + ShowCopiedSurface(); +} + +void ArcNotificationContentView::OnContainerAnimationEnded() { + HideCopiedSurface(); } void ArcNotificationContentView::MaybeCreateFloatingControlButtons() { @@ -330,22 +362,9 @@ void ArcNotificationContentView::MaybeCreateFloatingControlButtons() { if (!surface_ || !GetWidget() || !item_) return; - DCHECK(!control_buttons_view_); + DCHECK(!control_buttons_view_.parent()); DCHECK(!floating_control_buttons_widget_); - CHECK_EQ(ArcNotificationView::kViewClassName, parent()->GetClassName()); - auto* notification_view = static_cast<ArcNotificationView*>(parent()); - - // Creates the control_buttons_view_, which collects all control buttons into - // a horizontal box. - control_buttons_view_ = - new message_center::NotificationControlButtonsView(notification_view); - control_buttons_view_->SetBackgroundColor( - GetControlButtonBackgroundColor(item_->GetShownContents())); - control_buttons_view_->ShowSettingsButton( - item_->IsOpeningSettingsSupported()); - control_buttons_view_->ShowCloseButton(!notification_view->GetPinned()); - views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL); params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; @@ -353,7 +372,7 @@ void ArcNotificationContentView::MaybeCreateFloatingControlButtons() { floating_control_buttons_widget_.reset(new views::Widget); floating_control_buttons_widget_->Init(params); - floating_control_buttons_widget_->SetContentsView(control_buttons_view_); + floating_control_buttons_widget_->SetContentsView(&control_buttons_view_); floating_control_buttons_widget_->GetNativeWindow()->AddPreTargetHandler( mouse_enter_exit_handler_.get()); @@ -369,9 +388,6 @@ void ArcNotificationContentView::SetSurface(ArcNotificationSurface* surface) { if (surface_ == surface) return; - // Put null to |control_buttos|view_| before deleting the widget, since it may - // be referred while deletion. - control_buttons_view_ = nullptr; // Reset |floating_control_buttons_widget_| when |surface_| is changed. floating_control_buttons_widget_.reset(); @@ -428,34 +444,6 @@ void ArcNotificationContentView::UpdatePreferredSize() { SetPreferredSize(preferred_size); } -void ArcNotificationContentView::UpdateControlButtonsVisibility() { - if (!control_buttons_view_) - return; - - // If the visibility change is ongoing, skip this method to prevent an - // infinite loop. - if (updating_control_buttons_visibility_) - return; - - DCHECK(floating_control_buttons_widget_); - - const bool target_visiblity = - IsMouseHovered() || (control_buttons_view_->IsCloseButtonFocused()) || - (control_buttons_view_->IsSettingsButtonFocused()); - - if (target_visiblity == floating_control_buttons_widget_->IsVisible()) - return; - - // Add the guard to prevent an infinite loop. Changing visibility may generate - // an event and it may call thie method again. - base::AutoReset<bool> reset(&updating_control_buttons_visibility_, true); - - if (target_visiblity) - floating_control_buttons_widget_->Show(); - else - floating_control_buttons_widget_->Hide(); -} - void ArcNotificationContentView::UpdateSnapshot() { // Bail if we have a |surface_| because it controls the sizes and paints UI. if (surface_) @@ -489,22 +477,6 @@ void ArcNotificationContentView::AttachSurface() { MaybeCreateFloatingControlButtons(); } -void ArcNotificationContentView::UpdateAccessibleName() { - // Don't update the accessible name when we are about to be destroyed. - if (!item_) - return; - - accessible_name_ = item_->GetAccessibleName(); -} - -void ArcNotificationContentView::OnContainerAnimationStarted() { - ShowCopiedSurface(); -} - -void ArcNotificationContentView::OnContainerAnimationEnded() { - HideCopiedSurface(); -} - void ArcNotificationContentView::ShowCopiedSurface() { if (!surface_) return; @@ -576,19 +548,17 @@ void ArcNotificationContentView::Layout() { // be positioned without the need to consider the transform. surface_->GetContentWindow()->SetTransform(transform); - if (control_buttons_view_) { - DCHECK(floating_control_buttons_widget_); + if (floating_control_buttons_widget_) { gfx::Rect control_buttons_bounds(contents_bounds); - int buttons_width = control_buttons_view_->GetPreferredSize().width(); - int buttons_height = control_buttons_view_->GetPreferredSize().height(); + const gfx::Size button_size = control_buttons_view_.GetPreferredSize(); control_buttons_bounds.set_x(control_buttons_bounds.right() - - buttons_width - + button_size.width() - message_center::kControlButtonPadding); control_buttons_bounds.set_y(control_buttons_bounds.y() + message_center::kControlButtonPadding); - control_buttons_bounds.set_width(buttons_width); - control_buttons_bounds.set_height(buttons_height); + control_buttons_bounds.set_width(button_size.width()); + control_buttons_bounds.set_height(button_size.height()); floating_control_buttons_widget_->SetBounds(control_buttons_bounds); } @@ -625,10 +595,14 @@ void ArcNotificationContentView::OnMouseExited(const ui::MouseEvent&) { } void ArcNotificationContentView::OnFocus() { - CHECK_EQ(ArcNotificationView::kViewClassName, parent()->GetClassName()); + CHECK_EQ(message_center::MessageView::kViewClassName, + parent()->GetClassName()); + auto* notification_view = static_cast<ArcNotificationView*>(parent()); + CHECK_EQ(ArcNotificationView::kMessageViewSubClassName, + notification_view->GetMessageViewSubClassName()); NativeViewHost::OnFocus(); - static_cast<ArcNotificationView*>(parent())->OnContentFocused(); + notification_view->OnContentFocused(); if (surface_ && surface_->GetAXTreeId() != -1) Activate(); @@ -640,10 +614,14 @@ void ArcNotificationContentView::OnBlur() { return; } - CHECK_EQ(ArcNotificationView::kViewClassName, parent()->GetClassName()); + CHECK_EQ(message_center::MessageView::kViewClassName, + parent()->GetClassName()); + auto* notification_view = static_cast<ArcNotificationView*>(parent()); + CHECK_EQ(ArcNotificationView::kMessageViewSubClassName, + notification_view->GetMessageViewSubClassName()); NativeViewHost::OnBlur(); - static_cast<ArcNotificationView*>(parent())->OnContentBlured(); + notification_view->OnContentBlured(); } void ArcNotificationContentView::Activate() { @@ -683,6 +661,19 @@ void ArcNotificationContentView::GetAccessibleNodeData( node_data->SetName(accessible_name_); } +void ArcNotificationContentView::OnAccessibilityEvent(ax::mojom::Event event) { + if (event == ax::mojom::Event::kTextSelectionChanged) { + // Activate and request focus on notification content view. If text + // selection changed event is dispatched, it indicates that user is going to + // type something inside Android notification. Widget of message center is + // not activated by default. We need to activate the widget. If other view + // in message center has focus, it can consume key event. We need to request + // focus to move it to this content view. + Activate(); + RequestFocus(); + } +} + void ArcNotificationContentView::OnWindowBoundsChanged( aura::Window* window, const gfx::Rect& old_bounds, @@ -708,16 +699,6 @@ void ArcNotificationContentView::OnItemDestroying() { SetSurface(nullptr); } -void ArcNotificationContentView::OnItemUpdated() { - UpdateAccessibleName(); - UpdateSnapshot(); - if (control_buttons_view_) { - DCHECK(floating_control_buttons_widget_); - control_buttons_view_->SetBackgroundColor( - GetControlButtonBackgroundColor(item_->GetShownContents())); - } -} - void ArcNotificationContentView::OnNotificationSurfaceAdded( ArcNotificationSurface* surface) { if (surface->GetNotificationKey() != notification_key_) diff --git a/chromium/ui/arc/notification/arc_notification_content_view.h b/chromium/ui/arc/notification/arc_notification_content_view.h index fe405a0c4dd..2d4fdf39aba 100644 --- a/chromium/ui/arc/notification/arc_notification_content_view.h +++ b/chromium/ui/arc/notification/arc_notification_content_view.h @@ -9,13 +9,14 @@ #include <string> #include "base/macros.h" -#include "ui/arc/notification/arc_notification_content_view_delegate.h" #include "ui/arc/notification/arc_notification_item.h" #include "ui/arc/notification/arc_notification_surface_manager.h" #include "ui/aura/window_observer.h" +#include "ui/message_center/views/notification_control_buttons_view.h" #include "ui/views/controls/native/native_view_host.h" namespace message_center { +class Notification; class NotificationControlButtonsView; } @@ -42,19 +43,25 @@ class ArcNotificationContentView public: static const char kViewClassName[]; - explicit ArcNotificationContentView(ArcNotificationItem* item); + ArcNotificationContentView(ArcNotificationItem* item, + const message_center::Notification& notification, + message_center::MessageView* message_view); ~ArcNotificationContentView() override; // views::View overrides: const char* GetClassName() const override; - std::unique_ptr<ArcNotificationContentViewDelegate> - CreateContentViewDelegate(); + void Update(message_center::MessageView* message_view, + const message_center::Notification& notification); + message_center::NotificationControlButtonsView* GetControlButtonsView(); + void UpdateControlButtonsVisibility(); + void OnSlideChanged(); + void OnContainerAnimationStarted(); + void OnContainerAnimationEnded(); private: friend class ArcNotificationContentViewTest; - class ContentViewDelegate; class EventForwarder; class MouseEnterExitHandler; class SettingsButton; @@ -65,17 +72,13 @@ class ArcNotificationContentView void MaybeCreateFloatingControlButtons(); void SetSurface(ArcNotificationSurface* surface); void UpdatePreferredSize(); - void UpdateControlButtonsVisibility(); void UpdateSnapshot(); void AttachSurface(); void Activate(); - void UpdateAccessibleName(); void SetExpanded(bool expanded); bool IsExpanded() const; void SetManuallyExpandedOrCollapsed(bool value); bool IsManuallyExpandedOrCollapsed() const; - void OnContainerAnimationStarted(); - void OnContainerAnimationEnded(); void ShowCopiedSurface(); void HideCopiedSurface(); @@ -91,6 +94,7 @@ class ArcNotificationContentView void OnBlur() override; views::FocusTraversable* GetFocusTraversable() override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; + void OnAccessibilityEvent(ax::mojom::Event event) override; // aura::WindowObserver void OnWindowBoundsChanged(aura::Window* window, @@ -101,7 +105,6 @@ class ArcNotificationContentView // ArcNotificationItem::Observer void OnItemDestroying() override; - void OnItemUpdated() override; // ArcNotificationSurfaceManager::Observer: void OnNotificationSurfaceAdded(ArcNotificationSurface* surface) override; @@ -138,8 +141,8 @@ class ArcNotificationContentView // it. std::unique_ptr<views::Widget> floating_control_buttons_widget_; - message_center::NotificationControlButtonsView* control_buttons_view_ = - nullptr; + // This view is owned by client (this). + message_center::NotificationControlButtonsView control_buttons_view_; // Protects from call loops between Layout and OnWindowBoundsChanged. bool in_layout_ = false; diff --git a/chromium/ui/arc/notification/arc_notification_content_view_delegate.h b/chromium/ui/arc/notification/arc_notification_content_view_delegate.h deleted file mode 100644 index 2d8e4d04ffc..00000000000 --- a/chromium/ui/arc/notification/arc_notification_content_view_delegate.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017 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. - -#ifndef UI_ARC_NOTIFICATION_ARC_NOTIFICATION_CONTENT_VIEW_DELEGATE_H_ -#define UI_ARC_NOTIFICATION_ARC_NOTIFICATION_CONTENT_VIEW_DELEGATE_H_ - -namespace message_center { -class NotificationControlButtonsView; -} - -namespace arc { - -// Delegate for a view that is hosted by CustomNotificationView. -// TODO(yoshiki): Remove this delegate and call code in the content view -// directly without delegate. -class ArcNotificationContentViewDelegate { - public: - virtual ~ArcNotificationContentViewDelegate() = default; - virtual void UpdateControlButtonsVisibility() = 0; - virtual void OnSlideChanged() = 0; - virtual message_center::NotificationControlButtonsView* - GetControlButtonsView() const = 0; - virtual void OnContainerAnimationStarted() = 0; - virtual void OnContainerAnimationEnded() = 0; -}; - -} // namespace arc - -#endif // UI_ARC_NOTIFICATION_ARC_NOTIFICATION_CONTENT_VIEW_DELEGATE_H_ diff --git a/chromium/ui/arc/notification/arc_notification_content_view_unittest.cc b/chromium/ui/arc/notification/arc_notification_content_view_unittest.cc index d69a751faf4..2a2fb6f029c 100644 --- a/chromium/ui/arc/notification/arc_notification_content_view_unittest.cc +++ b/chromium/ui/arc/notification/arc_notification_content_view_unittest.cc @@ -8,10 +8,15 @@ #include <string> #include <utility> +#include "ash/message_center/message_center_view.h" #include "ash/shell.h" +#include "ash/system/status_area_widget.h" +#include "ash/system/status_area_widget_test_helper.h" +#include "ash/system/web_notification/web_notification_tray.h" #include "ash/test/ash_test_base.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind_test_util.h" #include "components/exo/buffer.h" #include "components/exo/keyboard.h" #include "components/exo/keyboard_delegate.h" @@ -28,6 +33,7 @@ #include "ui/arc/notification/arc_notification_surface.h" #include "ui/arc/notification/arc_notification_surface_manager_impl.h" #include "ui/arc/notification/arc_notification_view.h" +#include "ui/arc/notification/mock_arc_notification_item.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/window.h" #include "ui/events/keycodes/dom/dom_code.h" @@ -45,7 +51,6 @@ namespace arc { namespace { -constexpr char kNotificationIdPrefix[] = "ARC_NOTIFICATION_"; constexpr gfx::Rect kNotificationSurfaceBounds(100, 100, 300, 300); class MockKeyboardDelegate : public exo::KeyboardDelegate { @@ -69,63 +74,6 @@ aura::Window* GetFocusedWindow() { } // anonymous namespace -class MockArcNotificationItem : public ArcNotificationItem { - public: - MockArcNotificationItem(const std::string& notification_key) - : notification_key_(notification_key), - notification_id_(kNotificationIdPrefix + notification_key), - weak_factory_(this) {} - - // Methods for testing. - size_t count_close() { return count_close_; } - base::WeakPtr<MockArcNotificationItem> GetWeakPtr() { - return weak_factory_.GetWeakPtr(); - } - - // Overriding methods for testing. - void Close(bool by_user) override { count_close_++; } - const gfx::ImageSkia& GetSnapshot() const override { return snapshot_; } - const std::string& GetNotificationKey() const override { - return notification_key_; - } - const std::string& GetNotificationId() const override { - return notification_id_; - } - - // Overriding methods for returning dummy data or doing nothing. - void OnClosedFromAndroid() override {} - void Click() override {} - void ToggleExpansion() override {} - void OpenSettings() override {} - void AddObserver(Observer* observer) override {} - void RemoveObserver(Observer* observer) override {} - void IncrementWindowRefCount() override {} - void DecrementWindowRefCount() override {} - bool IsOpeningSettingsSupported() const override { return true; } - mojom::ArcNotificationExpandState GetExpandState() const override { - return mojom::ArcNotificationExpandState::FIXED_SIZE; - } - mojom::ArcNotificationShownContents GetShownContents() const override { - return mojom::ArcNotificationShownContents::CONTENTS_SHOWN; - } - gfx::Rect GetSwipeInputRect() const override { return gfx::Rect(); } - const base::string16& GetAccessibleName() const override { - return base::EmptyString16(); - }; - void OnUpdatedFromAndroid(mojom::ArcNotificationDataPtr data) override {} - bool IsManuallyExpandedOrCollapsed() const override { return false; } - - private: - std::string notification_key_; - std::string notification_id_; - gfx::ImageSkia snapshot_; - size_t count_close_ = 0; - - base::WeakPtrFactory<MockArcNotificationItem> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(MockArcNotificationItem); -}; - class DummyEvent : public ui::Event { public: DummyEvent() : Event(ui::ET_UNKNOWN, base::TimeTicks(), 0) {} @@ -140,6 +88,8 @@ class ArcNotificationContentViewTest : public ash::AshTestBase { void SetUp() override { ash::AshTestBase::SetUp(); + ash::MessageCenterView::disable_animation_for_testing = true; + wm_helper_ = std::make_unique<exo::WMHelper>(); exo::WMHelper::SetInstance(wm_helper_.get()); DCHECK(exo::WMHelper::HasInstance()); @@ -167,13 +117,14 @@ class ArcNotificationContentViewTest : public ash::AshTestBase { ash::AshTestBase::TearDown(); } - void PressCloseButton() { + void PressCloseButton(ArcNotificationView* notification_view) { DummyEvent dummy_event; auto* control_buttons_view = - GetArcNotificationContentView()->control_buttons_view_; + ¬ification_view->content_view_->control_buttons_view_; ASSERT_TRUE(control_buttons_view); views::Button* close_button = control_buttons_view->close_button(); ASSERT_NE(nullptr, close_button); + close_button->RequestFocus(); control_buttons_view->ButtonPressed(close_button, dummy_event); } @@ -193,8 +144,8 @@ class ArcNotificationContentViewTest : public ash::AshTestBase { static_cast<ArcNotificationView*>( message_center::MessageViewFactory::Create(notification, true))); notification_view->set_owned_by_client(); - views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); + views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; params.context = ash::Shell::GetPrimaryRootWindow(); auto wrapper_widget = std::make_unique<views::Widget>(); @@ -228,6 +179,9 @@ class ArcNotificationContentViewTest : public ash::AshTestBase { } Notification CreateNotification(MockArcNotificationItem* notification_item) { + message_center::RichNotificationData optional_fields; + optional_fields.settings_button_handler = + message_center::SettingsButtonHandler::DELEGATE; return Notification( message_center::NOTIFICATION_TYPE_CUSTOM, notification_item->GetNotificationId(), base::UTF8ToUTF16("title"), @@ -235,7 +189,7 @@ class ArcNotificationContentViewTest : public ash::AshTestBase { GURL(), message_center::NotifierId(message_center::NotifierId::ARC_APPLICATION, "ARC_NOTIFICATION"), - message_center::RichNotificationData(), + optional_fields, new ArcNotificationDelegate(notification_item->GetWeakPtr())); } @@ -249,8 +203,7 @@ class ArcNotificationContentViewTest : public ash::AshTestBase { message_center::NotificationControlButtonsView* GetControlButtonsView() const { DCHECK(GetArcNotificationContentView()); - DCHECK(GetArcNotificationContentView()->control_buttons_view_); - return GetArcNotificationContentView()->control_buttons_view_; + return &GetArcNotificationContentView()->control_buttons_view_; } views::Widget* GetControlButtonsWidget() const { DCHECK(GetControlButtonsView()->GetWidget()); @@ -258,9 +211,7 @@ class ArcNotificationContentViewTest : public ash::AshTestBase { } ArcNotificationContentView* GetArcNotificationContentView() const { - views::View* view = notification_view_->contents_view_; - EXPECT_EQ(ArcNotificationContentView::kViewClassName, view->GetClassName()); - return static_cast<ArcNotificationContentView*>(view); + return notification_view_->content_view_; } void ActivateArcNotification() { GetArcNotificationContentView()->Activate(); @@ -339,13 +290,68 @@ TEST_F(ArcNotificationContentViewTest, CloseButton) { EXPECT_TRUE(MessageCenter::Get()->FindVisibleNotificationById( notification_item->GetNotificationId())); - PressCloseButton(); + PressCloseButton(notification_view()); EXPECT_FALSE(MessageCenter::Get()->FindVisibleNotificationById( notification_item->GetNotificationId())); CloseNotificationView(); } +// Tests pressing close button when hosted in MessageCenterView. +TEST_F(ArcNotificationContentViewTest, CloseButtonInMessageCenterView) { + std::string notification_key("notification id"); + + // Override MessageView factory to capture the created notification view in + // |notification_view|. + ArcNotificationView* notification_view = nullptr; + message_center::MessageViewFactory::SetCustomNotificationViewFactory( + base::BindLambdaForTesting( + [¬ification_view](const message_center::Notification& notification) + -> std::unique_ptr<message_center::MessageView> { + auto* arc_delegate = + static_cast<ArcNotificationDelegate*>(notification.delegate()); + std::unique_ptr<message_center::MessageView> created_view = + arc_delegate->CreateCustomMessageView(notification); + notification_view = + static_cast<ArcNotificationView*>(created_view.get()); + return created_view; + })); + + // Show MessageCenterView and activate its widget. + auto* notification_tray = + ash::StatusAreaWidgetTestHelper::GetStatusAreaWidget() + ->web_notification_tray(); + notification_tray->ShowBubble(false /* show_by_click */); + notification_tray->GetBubbleView() + ->GetWidget() + ->widget_delegate() + ->set_can_activate(true); + notification_tray->GetBubbleView()->GetWidget()->Activate(); + + auto notification_item = + std::make_unique<MockArcNotificationItem>(notification_key); + PrepareSurface(notification_key); + Notification notification = CreateNotification(notification_item.get()); + + // Sets a close callback so that the underlying item is destroyed when close + // button is pressed. This simulates ArcNotificationItemImpl behavior. + notification_item->SetCloseCallback(base::BindLambdaForTesting( + [¬ification_item]() { notification_item.reset(); })); + + MessageCenter::Get()->AddNotification( + std::make_unique<Notification>(notification)); + ASSERT_TRUE(notification_view); + + // Cache notification id because |notification_item| will be gone when the + // close button is pressed. + const std::string notification_id = notification_item->GetNotificationId(); + EXPECT_TRUE( + MessageCenter::Get()->FindVisibleNotificationById(notification_id)); + PressCloseButton(notification_view); + EXPECT_FALSE( + MessageCenter::Get()->FindVisibleNotificationById(notification_id)); +} + TEST_F(ArcNotificationContentViewTest, ReuseSurfaceAfterClosing) { std::string notification_key("notification id"); diff --git a/chromium/ui/arc/notification/arc_notification_delegate.cc b/chromium/ui/arc/notification/arc_notification_delegate.cc index 4a3ddb0ac03..a689675b463 100644 --- a/chromium/ui/arc/notification/arc_notification_delegate.cc +++ b/chromium/ui/arc/notification/arc_notification_delegate.cc @@ -25,12 +25,7 @@ ArcNotificationDelegate::CreateCustomMessageView( const message_center::Notification& notification) { DCHECK(item_); DCHECK_EQ(item_->GetNotificationId(), notification.id()); - - auto view = std::make_unique<ArcNotificationContentView>(item_.get()); - auto content_view_delegate = view->CreateContentViewDelegate(); - return std::make_unique<ArcNotificationView>(item_.get(), std::move(view), - std::move(content_view_delegate), - notification); + return std::make_unique<ArcNotificationView>(item_.get(), notification); } void ArcNotificationDelegate::Close(bool by_user) { @@ -38,7 +33,9 @@ void ArcNotificationDelegate::Close(bool by_user) { item_->Close(by_user); } -void ArcNotificationDelegate::Click() { +void ArcNotificationDelegate::Click( + const base::Optional<int>& button_index, + const base::Optional<base::string16>& reply) { DCHECK(item_); item_->Click(); } diff --git a/chromium/ui/arc/notification/arc_notification_delegate.h b/chromium/ui/arc/notification/arc_notification_delegate.h index c90da5dc3c5..34481382069 100644 --- a/chromium/ui/arc/notification/arc_notification_delegate.h +++ b/chromium/ui/arc/notification/arc_notification_delegate.h @@ -32,7 +32,8 @@ class ArcNotificationDelegate : public message_center::NotificationDelegate { // message_center::NotificationDelegate overrides: void Close(bool by_user) override; - void Click() override; + void Click(const base::Optional<int>& button_index, + const base::Optional<base::string16>& reply) override; void SettingsClick() override; private: diff --git a/chromium/ui/arc/notification/arc_notification_item.h b/chromium/ui/arc/notification/arc_notification_item.h index cbe94104602..e31015c3832 100644 --- a/chromium/ui/arc/notification/arc_notification_item.h +++ b/chromium/ui/arc/notification/arc_notification_item.h @@ -18,9 +18,6 @@ class ArcNotificationItem { // Invoked when the notification data for this item has changed. virtual void OnItemDestroying() = 0; - // Invoked when the notification data for the item is updated. - virtual void OnItemUpdated() = 0; - protected: virtual ~Observer() = default; }; @@ -32,7 +29,8 @@ class ArcNotificationItem { virtual void OnClosedFromAndroid() = 0; // Called when the notification is updated on Android-side. This is called // from ArcNotificationManager. - virtual void OnUpdatedFromAndroid(mojom::ArcNotificationDataPtr data) = 0; + virtual void OnUpdatedFromAndroid(mojom::ArcNotificationDataPtr data, + const std::string& app_id) = 0; // Called when the notification is closed on Chrome-side. This is called from // ArcNotificationDelegate. @@ -47,10 +45,6 @@ class ArcNotificationItem { // Called when the user wants to toggle expansio of notification. This is // called from ArcNotificationContentView. virtual void ToggleExpansion() = 0; - // Returns true if this notification has an intrinsic setting which shown - // inside the notification content area. This is called from - // ArcNotificationContentView. - virtual bool IsOpeningSettingsSupported() const = 0; // Adds an observer. virtual void AddObserver(Observer* observer) = 0; @@ -68,6 +62,8 @@ class ArcNotificationItem { // Returns the current snapshot. virtual const gfx::ImageSkia& GetSnapshot() const = 0; // Returns the current expand state. + virtual mojom::ArcNotificationType GetNotificationType() const = 0; + // Returns the current expand state. virtual mojom::ArcNotificationExpandState GetExpandState() const = 0; virtual bool IsManuallyExpandedOrCollapsed() const = 0; @@ -81,8 +77,6 @@ class ArcNotificationItem { virtual const std::string& GetNotificationKey() const = 0; // Returns the notification ID used in the Chrome message center. virtual const std::string& GetNotificationId() const = 0; - // Returnes the accessible name of the notification. - virtual const base::string16& GetAccessibleName() const = 0; }; } // namespace arc diff --git a/chromium/ui/arc/notification/arc_notification_item_impl.cc b/chromium/ui/arc/notification/arc_notification_item_impl.cc index a889206a543..40b317f87d3 100644 --- a/chromium/ui/arc/notification/arc_notification_item_impl.cc +++ b/chromium/ui/arc/notification/arc_notification_item_impl.cc @@ -7,7 +7,7 @@ #include <utility> #include <vector> -#include "base/memory/ptr_util.h" +#include "ash/shelf/shelf_constants.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "ui/arc/notification/arc_notification_delegate.h" @@ -22,7 +22,6 @@ namespace arc { namespace { -constexpr char kNotifierId[] = "ARC_NOTIFICATION"; constexpr char kNotificationIdPrefix[] = "ARC_NOTIFICATION_"; // Converts from Android notification priority to Chrome notification priority. @@ -68,7 +67,8 @@ ArcNotificationItemImpl::~ArcNotificationItemImpl() { } void ArcNotificationItemImpl::OnUpdatedFromAndroid( - mojom::ArcNotificationDataPtr data) { + mojom::ArcNotificationDataPtr data, + const std::string& app_id) { DCHECK(CalledOnValidThread()); DCHECK_EQ(notification_key_, data->key); @@ -77,21 +77,17 @@ void ArcNotificationItemImpl::OnUpdatedFromAndroid( rich_data.priority = ConvertAndroidPriority(data->priority); if (data->small_icon) rich_data.small_image = gfx::Image::CreateFrom1xBitmap(*data->small_icon); - if (data->accessible_name.has_value()) { - accessible_name_ = base::UTF8ToUTF16(*data->accessible_name); - } else { - accessible_name_ = base::JoinString( - {base::UTF8ToUTF16(data->title), base::UTF8ToUTF16(data->message)}, - base::ASCIIToUTF16("\n")); - } - rich_data.accessible_name = accessible_name_; - if (IsOpeningSettingsSupported()) { + + rich_data.accessible_name = base::UTF8ToUTF16( + data->accessible_name.value_or(data->title + "\n" + data->message)); + if (manager_->IsOpeningSettingsSupported()) { rich_data.settings_button_handler = message_center::SettingsButtonHandler::DELEGATE; } message_center::NotifierId notifier_id( - message_center::NotifierId::ARC_APPLICATION, kNotifierId); + message_center::NotifierId::ARC_APPLICATION, + app_id.empty() ? ash::kDefaultArcNotifierId : app_id); notifier_id.profile_id = profile_id_.GetUserEmail(); auto notification = std::make_unique<message_center::Notification>( @@ -112,6 +108,7 @@ void ArcNotificationItemImpl::OnUpdatedFromAndroid( manually_expanded_or_collapsed_ = true; } + type_ = data->type; expand_state_ = data->expand_state; shown_contents_ = data->shown_contents; swipe_input_rect_ = @@ -128,9 +125,6 @@ void ArcNotificationItemImpl::OnUpdatedFromAndroid( gfx::ImageSkiaRep(*data->snapshot_image, data->snapshot_image_scale)); } - for (auto& observer : observers_) - observer.OnItemUpdated(); - message_center_->AddNotification(std::move(notification)); } @@ -159,10 +153,6 @@ void ArcNotificationItemImpl::OpenSettings() { manager_->OpenNotificationSettings(notification_key_); } -bool ArcNotificationItemImpl::IsOpeningSettingsSupported() const { - return manager_->IsOpeningSettingsSupported(); -} - void ArcNotificationItemImpl::ToggleExpansion() { switch (expand_state_) { case mojom::ArcNotificationExpandState::EXPANDED: @@ -208,6 +198,11 @@ const gfx::ImageSkia& ArcNotificationItemImpl::GetSnapshot() const { return snapshot_; } +mojom::ArcNotificationType ArcNotificationItemImpl::GetNotificationType() + const { + return type_; +} + mojom::ArcNotificationExpandState ArcNotificationItemImpl::GetExpandState() const { return expand_state_; @@ -234,8 +229,4 @@ const std::string& ArcNotificationItemImpl::GetNotificationId() const { return notification_id_; } -const base::string16& ArcNotificationItemImpl::GetAccessibleName() const { - return accessible_name_; -} - } // namespace arc diff --git a/chromium/ui/arc/notification/arc_notification_item_impl.h b/chromium/ui/arc/notification/arc_notification_item_impl.h index 33bea528b40..b1557fdcfc8 100644 --- a/chromium/ui/arc/notification/arc_notification_item_impl.h +++ b/chromium/ui/arc/notification/arc_notification_item_impl.h @@ -32,24 +32,24 @@ class ArcNotificationItemImpl : public ArcNotificationItem { // ArcNotificationItem overrides: void OnClosedFromAndroid() override; - void OnUpdatedFromAndroid(mojom::ArcNotificationDataPtr data) override; + void OnUpdatedFromAndroid(mojom::ArcNotificationDataPtr data, + const std::string& app_id) override; void Close(bool by_user) override; void Click() override; void OpenSettings() override; - bool IsOpeningSettingsSupported() const override; void ToggleExpansion() override; void AddObserver(Observer* observer) override; void RemoveObserver(Observer* observer) override; void IncrementWindowRefCount() override; void DecrementWindowRefCount() override; const gfx::ImageSkia& GetSnapshot() const override; + mojom::ArcNotificationType GetNotificationType() const override; mojom::ArcNotificationExpandState GetExpandState() const override; bool IsManuallyExpandedOrCollapsed() const override; mojom::ArcNotificationShownContents GetShownContents() const override; gfx::Rect GetSwipeInputRect() const override; const std::string& GetNotificationKey() const override; const std::string& GetNotificationId() const override; - const base::string16& GetAccessibleName() const override; private: // Return true if it's on the thread this instance is created on. @@ -60,6 +60,8 @@ class ArcNotificationItemImpl : public ArcNotificationItem { // The snapshot of the latest notification. gfx::ImageSkia snapshot_; + // The type of the latest notification. + mojom::ArcNotificationType type_ = mojom::ArcNotificationType::SIMPLE; // The expand state of the latest notification. mojom::ArcNotificationExpandState expand_state_ = mojom::ArcNotificationExpandState::FIXED_SIZE; @@ -70,8 +72,6 @@ class ArcNotificationItemImpl : public ArcNotificationItem { gfx::Rect swipe_input_rect_ = gfx::Rect(); // The reference counter of the window. int window_ref_count_ = 0; - // The accessible name of the latest notification. - base::string16 accessible_name_; base::ObserverList<Observer> observers_; diff --git a/chromium/ui/arc/notification/arc_notification_manager.cc b/chromium/ui/arc/notification/arc_notification_manager.cc index 98553c4b090..c015fc7162d 100644 --- a/chromium/ui/arc/notification/arc_notification_manager.cc +++ b/chromium/ui/arc/notification/arc_notification_manager.cc @@ -7,8 +7,6 @@ #include <memory> #include <utility> -#include "ash/shell.h" -#include "ash/system/toast/toast_manager.h" #include "base/memory/ptr_util.h" #include "base/memory/singleton.h" #include "base/stl_util.h" @@ -130,7 +128,8 @@ void ArcNotificationManager::OnNotificationPosted( const std::string& key = data->key; auto it = items_.find(key); if (it == items_.end()) { - // Show a notification on the primary logged-in user's desktop. + // Show a notification on the primary logged-in user's desktop and badge the + // app icon in the shelf if the icon exists. // TODO(yoshiki): Reconsider when ARC supports multi-user. auto item = std::make_unique<ArcNotificationItemImpl>( this, message_center_, key, main_profile_id_); @@ -139,7 +138,9 @@ void ArcNotificationManager::OnNotificationPosted( DCHECK(result.second); it = result.first; } - it->second->OnUpdatedFromAndroid(std::move(data)); + const std::string app_id = + data->package_name ? GetAppId(data->package_name.value()) : std::string(); + it->second->OnUpdatedFromAndroid(std::move(data), app_id); } void ArcNotificationManager::OnNotificationUpdated( @@ -154,7 +155,8 @@ void ArcNotificationManager::OnNotificationUpdated( if (it == items_.end()) return; - it->second->OnUpdatedFromAndroid(std::move(data)); + const std::string app_id = GetAppId(data->package_name.value()); + it->second->OnUpdatedFromAndroid(std::move(data), app_id); } void ArcNotificationManager::OnNotificationRemoved(const std::string& key) { @@ -340,17 +342,8 @@ void ArcNotificationManager::SendNotificationToggleExpansionOnChrome( key, mojom::ArcNotificationEvent::TOGGLE_EXPANSION); } -void ArcNotificationManager::OnToastPosted(mojom::ArcToastDataPtr data) { - const base::string16 text16( - base::UTF8ToUTF16(data->text.has_value() ? *data->text : std::string())); - const base::string16 dismiss_text16(base::UTF8ToUTF16( - data->dismiss_text.has_value() ? *data->dismiss_text : std::string())); - ash::Shell::Get()->toast_manager()->Show( - ash::ToastData(data->id, text16, data->duration, dismiss_text16)); -} - -void ArcNotificationManager::OnToastCancelled(mojom::ArcToastDataPtr data) { - ash::Shell::Get()->toast_manager()->Cancel(data->id); +void ArcNotificationManager::Shutdown() { + get_app_id_callback_.Reset(); } bool ArcNotificationManager::ShouldIgnoreNotification( @@ -361,4 +354,12 @@ bool ArcNotificationManager::ShouldIgnoreNotification( *data->package_name == kPlayStorePackageName && IsRobotAccountMode(); } +std::string ArcNotificationManager::GetAppId( + const std::string& package_name) const { + if (get_app_id_callback_.is_null()) + return std::string(); + + return get_app_id_callback_.Run(package_name); +} + } // namespace arc diff --git a/chromium/ui/arc/notification/arc_notification_manager.h b/chromium/ui/arc/notification/arc_notification_manager.h index 07058352b78..42279600213 100644 --- a/chromium/ui/arc/notification/arc_notification_manager.h +++ b/chromium/ui/arc/notification/arc_notification_manager.h @@ -51,6 +51,12 @@ class ArcNotificationManager ~ArcNotificationManager() override; + void set_get_app_id_callback( + base::RepeatingCallback<std::string(const std::string&)> + get_app_id_callback) { + get_app_id_callback_ = std::move(get_app_id_callback); + } + // ConnectionObserver<mojom::NotificationsInstance> implementation: void OnConnectionReady() override; void OnConnectionClosed() override; @@ -59,8 +65,6 @@ class ArcNotificationManager void OnNotificationPosted(mojom::ArcNotificationDataPtr data) override; void OnNotificationUpdated(mojom::ArcNotificationDataPtr data) override; void OnNotificationRemoved(const std::string& key) override; - void OnToastPosted(mojom::ArcToastDataPtr data) override; - void OnToastCancelled(mojom::ArcToastDataPtr data) override; // Methods called from ArcNotificationItem: void SendNotificationRemovedFromChrome(const std::string& key); @@ -73,6 +77,9 @@ class ArcNotificationManager bool IsOpeningSettingsSupported() const; void SendNotificationToggleExpansionOnChrome(const std::string& key); + // Overridden from KeyedService: + void Shutdown() override; + private: ArcNotificationManager(ArcBridgeService* bridge_service, const AccountId& main_profile_id, @@ -80,6 +87,9 @@ class ArcNotificationManager bool ShouldIgnoreNotification(mojom::ArcNotificationData* data); + // Calls |get_app_id_callback_| to retrieve the app id from ArcAppListPrefs. + std::string GetAppId(const std::string& package_name) const; + ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager. const AccountId main_profile_id_; message_center::MessageCenter* const message_center_; @@ -88,6 +98,8 @@ class ArcNotificationManager std::unordered_map<std::string, std::unique_ptr<ArcNotificationItem>>; ItemMap items_; + base::RepeatingCallback<std::string(const std::string&)> get_app_id_callback_; + bool ready_ = false; DISALLOW_COPY_AND_ASSIGN(ArcNotificationManager); diff --git a/chromium/ui/arc/notification/arc_notification_manager_unittest.cc b/chromium/ui/arc/notification/arc_notification_manager_unittest.cc index 98f586105d2..1ef695c1b7a 100644 --- a/chromium/ui/arc/notification/arc_notification_manager_unittest.cc +++ b/chromium/ui/arc/notification/arc_notification_manager_unittest.cc @@ -8,7 +8,6 @@ #include <utility> #include <vector> -#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "components/arc/arc_bridge_service.h" @@ -85,6 +84,7 @@ class ArcNotificationManagerTest : public testing::Test { data->key = key; data->title = "TITLE"; data->message = "MESSAGE"; + data->package_name = "PACKAGE_NAME"; arc_notification_manager()->OnNotificationPosted(std::move(data)); diff --git a/chromium/ui/arc/notification/arc_notification_surface_manager_impl.cc b/chromium/ui/arc/notification/arc_notification_surface_manager_impl.cc index 29778a785b7..72c834d5bb3 100644 --- a/chromium/ui/arc/notification/arc_notification_surface_manager_impl.cc +++ b/chromium/ui/arc/notification/arc_notification_surface_manager_impl.cc @@ -7,7 +7,6 @@ #include <string> #include <utility> -#include "base/memory/ptr_util.h" #include "components/exo/notification_surface.h" #include "ui/arc/notification/arc_notification_surface_impl.h" diff --git a/chromium/ui/arc/notification/arc_notification_view.cc b/chromium/ui/arc/notification/arc_notification_view.cc index 6977d6d385f..1cee5514afb 100644 --- a/chromium/ui/arc/notification/arc_notification_view.cc +++ b/chromium/ui/arc/notification/arc_notification_view.cc @@ -7,7 +7,7 @@ #include <algorithm> #include "ui/accessibility/ax_action_data.h" -#include "ui/arc/notification/arc_notification_content_view_delegate.h" +#include "ui/arc/notification/arc_notification_content_view.h" #include "ui/arc/notification/arc_notification_item.h" #include "ui/base/ime/input_method.h" #include "ui/base/ime/text_input_client.h" @@ -23,33 +23,26 @@ namespace arc { // static -const char ArcNotificationView::kViewClassName[] = "ArcNotificationView"; +const char ArcNotificationView::kMessageViewSubClassName[] = + "ArcNotificationView"; ArcNotificationView::ArcNotificationView( ArcNotificationItem* item, - std::unique_ptr<views::View> contents_view, - std::unique_ptr<ArcNotificationContentViewDelegate> contents_view_delegate, const message_center::Notification& notification) : message_center::MessageView(notification), item_(item), - contents_view_(contents_view.get()), - contents_view_delegate_(std::move(contents_view_delegate)) { + content_view_(new ArcNotificationContentView(item_, notification, this)) { DCHECK_EQ(message_center::NOTIFICATION_TYPE_CUSTOM, notification.type()); item_->AddObserver(this); - DCHECK(contents_view); - AddChildView(contents_view.release()); + AddChildView(content_view_); - DCHECK(contents_view_delegate_); - - if (contents_view_->background()) { + if (content_view_->background()) { background_view()->background()->SetNativeControlColor( - contents_view_->background()->get_color()); + content_view_->background()->get_color()); } - UpdateControlButtonsVisibilityWithNotification(notification); - focus_painter_ = views::Painter::CreateSolidFocusPainter( message_center::kFocusBorderColor, gfx::Insets(0, 1, 3, 2)); } @@ -70,39 +63,23 @@ void ArcNotificationView::OnContentBlured() { void ArcNotificationView::UpdateWithNotification( const message_center::Notification& notification) { message_center::MessageView::UpdateWithNotification(notification); - - UpdateControlButtonsVisibilityWithNotification(notification); + content_view_->Update(this, notification); } void ArcNotificationView::SetDrawBackgroundAsActive(bool active) { - // Do nothing if |contents_view_| has a background. - if (contents_view_->background()) + // Do nothing if |content_view_| has a background. + if (content_view_->background()) return; message_center::MessageView::SetDrawBackgroundAsActive(active); } -bool ArcNotificationView::IsCloseButtonFocused() const { - if (!GetControlButtonsView()) - return false; - return GetControlButtonsView()->IsCloseButtonFocused(); -} - -void ArcNotificationView::RequestFocusOnCloseButton() { - if (GetControlButtonsView()) { - GetControlButtonsView()->RequestFocusOnCloseButton(); - if (contents_view_delegate_) - contents_view_delegate_->UpdateControlButtonsVisibility(); - } -} - -const char* ArcNotificationView::GetClassName() const { - return kViewClassName; +void ArcNotificationView::UpdateControlButtonsVisibility() { + content_view_->UpdateControlButtonsVisibility(); } -void ArcNotificationView::UpdateControlButtonsVisibility() { - if (contents_view_delegate_) - contents_view_delegate_->UpdateControlButtonsVisibility(); +const char* ArcNotificationView::GetMessageViewSubClassName() const { + return kMessageViewSubClassName; } void ArcNotificationView::GetAccessibleNodeData(ui::AXNodeData* node_data) { @@ -112,7 +89,7 @@ void ArcNotificationView::GetAccessibleNodeData(ui::AXNodeData* node_data) { message_center::NotificationControlButtonsView* ArcNotificationView::GetControlButtonsView() const { - return contents_view_delegate_->GetControlButtonsView(); + return content_view_->GetControlButtonsView(); } bool ArcNotificationView::IsExpanded() const { @@ -120,6 +97,16 @@ bool ArcNotificationView::IsExpanded() const { item_->GetExpandState() == mojom::ArcNotificationExpandState::EXPANDED; } +bool ArcNotificationView::IsAutoExpandingAllowed() const { + if (!item_) + return false; + + // Disallow auto-expanding if the notificaiton is bundled. This is consistent + // behavior with Android since expanded height of bundle notification might be + // too long vertically. + return item_->GetNotificationType() != mojom::ArcNotificationType::BUNDLED; +} + void ArcNotificationView::SetExpanded(bool expanded) { if (!item_) return; @@ -141,75 +128,68 @@ bool ArcNotificationView::IsManuallyExpandedOrCollapsed() const { } void ArcNotificationView::OnContainerAnimationStarted() { - if (contents_view_delegate_) - contents_view_delegate_->OnContainerAnimationStarted(); + content_view_->OnContainerAnimationStarted(); } void ArcNotificationView::OnContainerAnimationEnded() { - if (contents_view_delegate_) - contents_view_delegate_->OnContainerAnimationEnded(); + content_view_->OnContainerAnimationEnded(); } void ArcNotificationView::OnSlideChanged() { - if (contents_view_delegate_) - contents_view_delegate_->OnSlideChanged(); + content_view_->OnSlideChanged(); } gfx::Size ArcNotificationView::CalculatePreferredSize() const { const gfx::Insets insets = GetInsets(); const int contents_width = message_center::kNotificationWidth; - const int contents_height = contents_view_->GetHeightForWidth(contents_width); + const int contents_height = content_view_->GetHeightForWidth(contents_width); return gfx::Size(contents_width + insets.width(), contents_height + insets.height()); } void ArcNotificationView::Layout() { // Setting the bounds before calling the parent to prevent double Layout. - contents_view_->SetBoundsRect(GetContentsBounds()); + content_view_->SetBoundsRect(GetContentsBounds()); message_center::MessageView::Layout(); // If the content view claims focus, defer focus handling to the content view. - if (contents_view_->IsFocusable()) + if (content_view_->IsFocusable()) SetFocusBehavior(FocusBehavior::NEVER); } bool ArcNotificationView::HasFocus() const { // In case that focus handling is defered to the content view, asking the // content view about focus. - if (contents_view_ && contents_view_->IsFocusable()) - return contents_view_->HasFocus(); - else - return message_center::MessageView::HasFocus(); + return content_view_->IsFocusable() ? content_view_->HasFocus() + : message_center::MessageView::HasFocus(); } void ArcNotificationView::RequestFocus() { - if (contents_view_ && contents_view_->IsFocusable()) - contents_view_->RequestFocus(); + if (content_view_->IsFocusable()) + content_view_->RequestFocus(); else message_center::MessageView::RequestFocus(); } void ArcNotificationView::OnPaint(gfx::Canvas* canvas) { MessageView::OnPaint(canvas); - if (contents_view_ && contents_view_->IsFocusable()) - views::Painter::PaintFocusPainter(contents_view_, canvas, + if (content_view_->IsFocusable()) { + views::Painter::PaintFocusPainter(content_view_, canvas, focus_painter_.get()); + } } bool ArcNotificationView::OnKeyPressed(const ui::KeyEvent& event) { - if (contents_view_) { - ui::InputMethod* input_method = contents_view_->GetInputMethod(); - if (input_method) { - ui::TextInputClient* text_input_client = - input_method->GetTextInputClient(); - if (text_input_client && - text_input_client->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE) { - // If the focus is in an edit box, we skip the special key handling for - // back space and return keys. So that these key events are sent to the - // arc container correctly without being handled by the message center. - return false; - } + ui::InputMethod* input_method = content_view_->GetInputMethod(); + if (input_method) { + ui::TextInputClient* text_input_client = input_method->GetTextInputClient(); + if (text_input_client && + text_input_client->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE) { + // If the focus is in an edit box, we skip the special key handling for + // back space and return keys. So that these key events are sent to the + // arc container correctly without being handled by the message center. + return false; } } @@ -235,19 +215,4 @@ void ArcNotificationView::OnItemDestroying() { item_ = nullptr; } -void ArcNotificationView::OnItemUpdated() {} - -// TODO(yoshiki): move this to MessageView and share the code among -// NotificationView and NotificationViewMD. -void ArcNotificationView::UpdateControlButtonsVisibilityWithNotification( - const message_center::Notification& notification) { - if (!GetControlButtonsView()) - return; - - GetControlButtonsView()->ShowSettingsButton( - notification.should_show_settings_button()); - GetControlButtonsView()->ShowCloseButton(!GetPinned()); - UpdateControlButtonsVisibility(); -} - } // namespace message_center diff --git a/chromium/ui/arc/notification/arc_notification_view.h b/chromium/ui/arc/notification/arc_notification_view.h index e54838bb0b5..2e9e64a4dc6 100644 --- a/chromium/ui/arc/notification/arc_notification_view.h +++ b/chromium/ui/arc/notification/arc_notification_view.h @@ -15,20 +15,17 @@ class Painter; namespace arc { -class ArcNotificationContentViewDelegate; +class ArcNotificationContentView; // View for custom notification with NOTIFICATION_TYPE_CUSTOM which hosts the // ArcNotificationContentView which shows content of the notification. class ArcNotificationView : public message_center::MessageView, public ArcNotificationItem::Observer { public: - static const char kViewClassName[]; + static const char kMessageViewSubClassName[]; // |content_view| is a view to be hosted in this view. ArcNotificationView(ArcNotificationItem* item, - std::unique_ptr<views::View> content_view, - std::unique_ptr<ArcNotificationContentViewDelegate> - contents_view_delegate, const message_center::Notification& notification); ~ArcNotificationView() override; @@ -41,23 +38,22 @@ class ArcNotificationView : public message_center::MessageView, void UpdateWithNotification( const message_center::Notification& notification) override; void SetDrawBackgroundAsActive(bool active) override; - bool IsCloseButtonFocused() const override; - void RequestFocusOnCloseButton() override; void UpdateControlButtonsVisibility() override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; message_center::NotificationControlButtonsView* GetControlButtonsView() const override; bool IsExpanded() const override; void SetExpanded(bool expanded) override; + bool IsAutoExpandingAllowed() const override; bool IsManuallyExpandedOrCollapsed() const override; void OnContainerAnimationStarted() override; void OnContainerAnimationEnded() override; + const char* GetMessageViewSubClassName() const final; // views::SlideOutController::Delegate: void OnSlideChanged() override; // Overridden from views::View: - const char* GetClassName() const override; gfx::Size CalculatePreferredSize() const override; void Layout() override; bool HasFocus() const override; @@ -69,11 +65,11 @@ class ArcNotificationView : public message_center::MessageView, // ArcNotificationItem::Observer void OnItemDestroying() override; - void OnItemUpdated() override; private: friend class ArcNotificationContentViewTest; friend class ArcNotificationViewTest; + friend class ArcAccessibilityHelperBridgeTest; // TODO(yoshiki): Mmove this to message_center::MessageView. void UpdateControlButtonsVisibilityWithNotification( @@ -82,8 +78,7 @@ class ArcNotificationView : public message_center::MessageView, ArcNotificationItem* item_; // The view for the custom content. Owned by view hierarchy. - views::View* contents_view_ = nullptr; - std::unique_ptr<ArcNotificationContentViewDelegate> contents_view_delegate_; + ArcNotificationContentView* const content_view_; std::unique_ptr<views::Painter> focus_painter_; diff --git a/chromium/ui/arc/notification/arc_notification_view_unittest.cc b/chromium/ui/arc/notification/arc_notification_view_unittest.cc index e988fdd763b..bac3ab667ca 100644 --- a/chromium/ui/arc/notification/arc_notification_view_unittest.cc +++ b/chromium/ui/arc/notification/arc_notification_view_unittest.cc @@ -4,12 +4,13 @@ #include <memory> +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/strings/utf_string_conversions.h" #include "third_party/skia/include/core/SkColor.h" -#include "ui/arc/notification/arc_notification_content_view_delegate.h" +#include "ui/arc/notification/arc_notification_content_view.h" #include "ui/arc/notification/arc_notification_item.h" #include "ui/arc/notification/arc_notification_view.h" #include "ui/base/ime/dummy_text_input_client.h" @@ -22,6 +23,7 @@ #include "ui/message_center/message_center.h" #include "ui/message_center/public/cpp/notification.h" #include "ui/message_center/views/message_view_factory.h" +#include "ui/message_center/views/notification_control_buttons_view.h" #include "ui/views/background.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/test/views_test_base.h" @@ -34,59 +36,6 @@ namespace arc { namespace { constexpr char kNotificationIdPrefix[] = "ARC_NOTIFICATION_"; -const SkColor kBackgroundColor = SK_ColorGREEN; - -class TestNotificationContentsView : public views::View { - public: - TestNotificationContentsView() { - SetFocusBehavior(FocusBehavior::ALWAYS); - SetBackground(views::CreateSolidBackground(kBackgroundColor)); - SetPreferredSize(gfx::Size(100, 100)); - } - ~TestNotificationContentsView() override = default; - - void Reset() { - mouse_event_count_ = 0; - keyboard_event_count_ = 0; - } - - // views::View - bool OnMousePressed(const ui::MouseEvent& event) override { - ++mouse_event_count_; - return true; - } - void OnMouseMoved(const ui::MouseEvent& event) override { - ++mouse_event_count_; - } - void OnMouseReleased(const ui::MouseEvent& event) override { - ++mouse_event_count_; - } - bool OnKeyPressed(const ui::KeyEvent& event) override { - ++keyboard_event_count_; - return false; - } - - int mouse_event_count() const { return mouse_event_count_; } - int keyboard_event_count() const { return keyboard_event_count_; } - - private: - int mouse_event_count_ = 0; - int keyboard_event_count_ = 0; - - DISALLOW_COPY_AND_ASSIGN(TestNotificationContentsView); -}; - -class TestContentViewDelegate : public ArcNotificationContentViewDelegate { - public: - void UpdateControlButtonsVisibility() override {} - void OnSlideChanged() override {} - message_center::NotificationControlButtonsView* GetControlButtonsView() - const override { - return nullptr; - } - void OnContainerAnimationStarted() override {} - void OnContainerAnimationEnded() override {} -}; class MockArcNotificationItem : public ArcNotificationItem { public: @@ -113,7 +62,9 @@ class MockArcNotificationItem : public ArcNotificationItem { void RemoveObserver(Observer* observer) override {} void IncrementWindowRefCount() override {} void DecrementWindowRefCount() override {} - bool IsOpeningSettingsSupported() const override { return true; } + mojom::ArcNotificationType GetNotificationType() const override { + return mojom::ArcNotificationType::SIMPLE; + } mojom::ArcNotificationExpandState GetExpandState() const override { return mojom::ArcNotificationExpandState::FIXED_SIZE; } @@ -121,10 +72,8 @@ class MockArcNotificationItem : public ArcNotificationItem { return mojom::ArcNotificationShownContents::CONTENTS_SHOWN; } gfx::Rect GetSwipeInputRect() const override { return gfx::Rect(); } - const base::string16& GetAccessibleName() const override { - return base::EmptyString16(); - }; - void OnUpdatedFromAndroid(mojom::ArcNotificationDataPtr data) override {} + void OnUpdatedFromAndroid(mojom::ArcNotificationDataPtr data, + const std::string& app_id) override {} bool IsManuallyExpandedOrCollapsed() const override { return false; } private: @@ -135,14 +84,6 @@ class MockArcNotificationItem : public ArcNotificationItem { DISALLOW_COPY_AND_ASSIGN(MockArcNotificationItem); }; -std::unique_ptr<message_center::MessageView> CreateCustomMessageViewForTest( - ArcNotificationItem* item, - const Notification& notification) { - return std::make_unique<ArcNotificationView>( - item, std::make_unique<TestNotificationContentsView>(), - std::make_unique<TestContentViewDelegate>(), notification); -} - class TestTextInputClient : public ui::DummyTextInputClient { public: TestTextInputClient() : ui::DummyTextInputClient(ui::TEXT_INPUT_TYPE_TEXT) {} @@ -159,21 +100,21 @@ class TestTextInputClient : public ui::DummyTextInputClient { } // namespace -class ArcNotificationViewTest : public views::ViewsTestBase { +class ArcNotificationViewTest : public ash::AshTestBase { public: ArcNotificationViewTest() = default; ~ArcNotificationViewTest() override = default; // views::ViewsTestBase void SetUp() override { - views::ViewsTestBase::SetUp(); - - MessageCenter::Initialize(); + ash::AshTestBase::SetUp(); const std::string notification_id("notification id"); item_ = std::make_unique<MockArcNotificationItem>(notification_id); message_center::MessageViewFactory::SetCustomNotificationViewFactory( - base::BindRepeating(&CreateCustomMessageViewForTest, item_.get())); + base::BindRepeating( + &ArcNotificationViewTest::CreateCustomMessageViewForTest, + base::Unretained(this), item_.get())); notification_ = std::make_unique<Notification>( message_center::NOTIFICATION_TYPE_CUSTOM, notification_id, @@ -189,23 +130,24 @@ class ArcNotificationViewTest : public views::ViewsTestBase { UpdateNotificationViews(); views::Widget::InitParams init_params( - CreateParams(views::Widget::InitParams::TYPE_POPUP)); + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + init_params.context = CurrentContext(); + init_params.parent = ash::Shell::GetPrimaryRootWindow()->GetChildById( + ash::kShellWindowId_DefaultContainer); + init_params.ownership = + views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; views::Widget* widget = new views::Widget(); widget->Init(init_params); widget->SetContentsView(notification_view_.get()); widget->SetSize(notification_view_->GetPreferredSize()); widget->Show(); + EXPECT_EQ(widget, notification_view_->GetWidget()); } void TearDown() override { widget()->Close(); notification_view_.reset(); - views::ViewsTestBase::TearDown(); - MessageCenter::Shutdown(); - } - - SkColor GetBackgroundColor() const { - return notification_view_->background_view()->background()->get_color(); + ash::AshTestBase::TearDown(); } void PerformClick(const gfx::Point& point) { @@ -226,11 +168,6 @@ class ArcNotificationViewTest : public views::ViewsTestBase { widget()->OnKeyEvent(&event2); } - void KeyPress(ui::KeyboardCode key_code) { - ui::KeyEvent event(ui::ET_KEY_PRESSED, key_code, ui::EF_NONE); - widget()->OnKeyEvent(&event); - } - void UpdateNotificationViews() { MessageCenter::Get()->AddNotification( std::make_unique<Notification>(*notification())); @@ -249,10 +186,8 @@ class ArcNotificationViewTest : public views::ViewsTestBase { } void DispatchGesture(const ui::GestureEventDetails& details) { - ui::test::EventGenerator generator( - notification_view()->GetWidget()->GetNativeWindow()); - ui::GestureEvent event(0, 0, 0, ui::EventTimeForNow(), details); - generator.Dispatch(&event); + ui::GestureEvent event2(0, 0, 0, ui::EventTimeForNow(), details); + widget()->OnGestureEvent(&event2); } void BeginScroll() { @@ -269,14 +204,22 @@ class ArcNotificationViewTest : public views::ViewsTestBase { } Notification* notification() { return notification_.get(); } - TestNotificationContentsView* contents_view() { - return static_cast<TestNotificationContentsView*>( - notification_view_->contents_view_); + ArcNotificationContentView* content_view() { + return notification_view_->content_view_; } views::Widget* widget() { return notification_view_->GetWidget(); } ArcNotificationView* notification_view() { return notification_view_.get(); } private: + std::unique_ptr<message_center::MessageView> CreateCustomMessageViewForTest( + ArcNotificationItem* item, + const Notification& notification) { + auto message_view = + std::make_unique<ArcNotificationView>(item, notification); + message_view->content_view_->SetPreferredSize(gfx::Size(100, 100)); + return message_view; + } + std::unique_ptr<Notification> notification_; std::unique_ptr<ArcNotificationView> notification_view_; @@ -285,28 +228,20 @@ class ArcNotificationViewTest : public views::ViewsTestBase { DISALLOW_COPY_AND_ASSIGN(ArcNotificationViewTest); }; -TEST_F(ArcNotificationViewTest, Background) { - EXPECT_EQ(kBackgroundColor, GetBackgroundColor()); -} - TEST_F(ArcNotificationViewTest, Events) { widget()->Show(); - contents_view()->RequestFocus(); - EXPECT_EQ(0, contents_view()->mouse_event_count()); gfx::Point cursor_location(1, 1); - views::View::ConvertPointToWidget(contents_view(), &cursor_location); - PerformClick(cursor_location); - EXPECT_EQ(2, contents_view()->mouse_event_count()); - - ui::MouseEvent move(ui::ET_MOUSE_MOVED, cursor_location, cursor_location, - ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE); - widget()->OnMouseEvent(&move); - EXPECT_EQ(3, contents_view()->mouse_event_count()); - - EXPECT_EQ(0, contents_view()->keyboard_event_count()); - KeyPress(ui::VKEY_A); - EXPECT_EQ(1, contents_view()->keyboard_event_count()); + views::View::ConvertPointToWidget(content_view(), &cursor_location); + EXPECT_EQ(content_view(), + widget()->GetRootView()->GetEventHandlerForPoint(cursor_location)); + + content_view()->RequestFocus(); + ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); + EXPECT_EQ(content_view(), + static_cast<ui::EventTargeter*>( + widget()->GetRootView()->GetEffectiveViewTargeter()) + ->FindTargetForEvent(widget()->GetRootView(), &key_event)); } TEST_F(ArcNotificationViewTest, SlideOut) { @@ -316,6 +251,7 @@ TEST_F(ArcNotificationViewTest, SlideOut) { std::string notification_id = notification()->id(); BeginScroll(); + EXPECT_EQ(0.f, GetNotificationSlideAmount()); ScrollBy(-10); EXPECT_FALSE(IsRemoved(notification_id)); EXPECT_EQ(-10.f, GetNotificationSlideAmount()); @@ -324,6 +260,7 @@ TEST_F(ArcNotificationViewTest, SlideOut) { EXPECT_EQ(0.f, GetNotificationSlideAmount()); BeginScroll(); + EXPECT_EQ(0.f, GetNotificationSlideAmount()); ScrollBy(-200); EXPECT_FALSE(IsRemoved(notification_id)); EXPECT_EQ(-200.f, GetNotificationSlideAmount()); @@ -339,6 +276,7 @@ TEST_F(ArcNotificationViewTest, SlideOutNested) { std::string notification_id = notification()->id(); BeginScroll(); + EXPECT_EQ(0.f, GetNotificationSlideAmount()); ScrollBy(-10); EXPECT_FALSE(IsRemoved(notification_id)); EXPECT_EQ(-10.f, GetNotificationSlideAmount()); @@ -347,6 +285,7 @@ TEST_F(ArcNotificationViewTest, SlideOutNested) { EXPECT_EQ(0.f, GetNotificationSlideAmount()); BeginScroll(); + EXPECT_EQ(0.f, GetNotificationSlideAmount()); ScrollBy(-200); EXPECT_FALSE(IsRemoved(notification_id)); EXPECT_EQ(-200.f, GetNotificationSlideAmount()); @@ -367,10 +306,12 @@ TEST_F(ArcNotificationViewTest, SlideOutPinned) { std::string notification_id = notification()->id(); BeginScroll(); + EXPECT_EQ(0.f, GetNotificationSlideAmount()); ScrollBy(-200); EXPECT_FALSE(IsRemoved(notification_id)); EXPECT_LT(-200.f, GetNotificationSlideAmount()); EndScroll(); + EXPECT_EQ(0.f, GetNotificationSlideAmount()); EXPECT_FALSE(IsRemoved(notification_id)); } @@ -378,9 +319,9 @@ TEST_F(ArcNotificationViewTest, SlideOutPinned) { TEST_F(ArcNotificationViewTest, PressBackspaceKey) { std::string notification_id = notification()->id(); - contents_view()->RequestFocus(); + content_view()->RequestFocus(); - ui::InputMethod* input_method = contents_view()->GetInputMethod(); + ui::InputMethod* input_method = content_view()->GetInputMethod(); ASSERT_TRUE(input_method); TestTextInputClient text_input_client; input_method->SetFocusedTextInputClient(&text_input_client); @@ -395,9 +336,9 @@ TEST_F(ArcNotificationViewTest, PressBackspaceKey) { TEST_F(ArcNotificationViewTest, PressBackspaceKeyOnEditBox) { std::string notification_id = notification()->id(); - contents_view()->RequestFocus(); + content_view()->RequestFocus(); - ui::InputMethod* input_method = contents_view()->GetInputMethod(); + ui::InputMethod* input_method = content_view()->GetInputMethod(); ASSERT_TRUE(input_method); TestTextInputClient text_input_client; input_method->SetFocusedTextInputClient(&text_input_client); @@ -419,13 +360,13 @@ TEST_F(ArcNotificationViewTest, ChangeContentHeight) { EXPECT_EQ("360x100", size.ToString()); // Allow small notifications. - contents_view()->SetPreferredSize(gfx::Size(10, 10)); + content_view()->SetPreferredSize(gfx::Size(10, 10)); size = notification_view()->GetPreferredSize(); size.Enlarge(0, -notification_view()->GetInsets().height()); EXPECT_EQ("360x10", size.ToString()); // The long notification. - contents_view()->SetPreferredSize(gfx::Size(1000, 1000)); + content_view()->SetPreferredSize(gfx::Size(1000, 1000)); size = notification_view()->GetPreferredSize(); size.Enlarge(0, -notification_view()->GetInsets().height()); EXPECT_EQ("360x1000", size.ToString()); diff --git a/chromium/ui/arc/notification/mock_arc_notification_item.cc b/chromium/ui/arc/notification/mock_arc_notification_item.cc new file mode 100644 index 00000000000..388d6c71bad --- /dev/null +++ b/chromium/ui/arc/notification/mock_arc_notification_item.cc @@ -0,0 +1,85 @@ +// Copyright 2018 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 "ui/arc/notification/mock_arc_notification_item.h" + +#include <utility> + +#include "base/bind_helpers.h" + +namespace arc { + +namespace { + +constexpr char kNotificationIdPrefix[] = "ARC_NOTIFICATION_"; + +} // namespace + +MockArcNotificationItem::MockArcNotificationItem( + const std::string& notification_key) + : notification_key_(notification_key), + notification_id_(kNotificationIdPrefix + notification_key), + weak_factory_(this) {} + +MockArcNotificationItem::~MockArcNotificationItem() { + for (auto& observer : observers_) + observer.OnItemDestroying(); +} + +void MockArcNotificationItem::SetCloseCallback( + base::OnceClosure close_callback) { + close_callback_ = std::move(close_callback); +} + +void MockArcNotificationItem::Close(bool by_user) { + count_close_++; + + if (close_callback_) + base::ResetAndReturn(&close_callback_).Run(); +} + +const gfx::ImageSkia& MockArcNotificationItem::GetSnapshot() const { + return snapshot_; +} + +const std::string& MockArcNotificationItem::GetNotificationKey() const { + return notification_key_; +} + +const std::string& MockArcNotificationItem::GetNotificationId() const { + return notification_id_; +} + +void MockArcNotificationItem::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void MockArcNotificationItem::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +mojom::ArcNotificationType MockArcNotificationItem::GetNotificationType() + const { + return mojom::ArcNotificationType::SIMPLE; +} + +mojom::ArcNotificationExpandState MockArcNotificationItem::GetExpandState() + const { + return mojom::ArcNotificationExpandState::FIXED_SIZE; +} + +mojom::ArcNotificationShownContents MockArcNotificationItem::GetShownContents() + const { + return mojom::ArcNotificationShownContents::CONTENTS_SHOWN; +} + +gfx::Rect MockArcNotificationItem::GetSwipeInputRect() const { + return gfx::Rect(); +} + +bool MockArcNotificationItem::IsManuallyExpandedOrCollapsed() const { + return false; +} + +} // namespace arc diff --git a/chromium/ui/arc/notification/mock_arc_notification_item.h b/chromium/ui/arc/notification/mock_arc_notification_item.h new file mode 100644 index 00000000000..db2d22d055c --- /dev/null +++ b/chromium/ui/arc/notification/mock_arc_notification_item.h @@ -0,0 +1,70 @@ +// Copyright 2018 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. + +#ifndef UI_ARC_NOTIFICATION_MOCK_ARC_NOTIFICATION_ITEM_H_ +#define UI_ARC_NOTIFICATION_MOCK_ARC_NOTIFICATION_ITEM_H_ + +#include <string> + +#include "base/callback.h" +#include "base/observer_list.h" +#include "ui/arc/notification/arc_notification_item.h" + +namespace arc { + +class MockArcNotificationItem : public ArcNotificationItem { + public: + MockArcNotificationItem(const std::string& notification_key); + ~MockArcNotificationItem() override; + + // Methods for testing. + size_t count_close() { return count_close_; } + base::WeakPtr<MockArcNotificationItem> GetWeakPtr() { + return weak_factory_.GetWeakPtr(); + } + + void SetCloseCallback(base::OnceClosure close_callback); + + // Overriding methods for testing. + void Close(bool by_user) override; + const gfx::ImageSkia& GetSnapshot() const override; + const std::string& GetNotificationKey() const override; + const std::string& GetNotificationId() const override; + + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + + // Overriding methods for returning dummy data or doing nothing. + void OnClosedFromAndroid() override {} + void Click() override {} + void ToggleExpansion() override {} + void OpenSettings() override {} + void IncrementWindowRefCount() override {} + void DecrementWindowRefCount() override {} + mojom::ArcNotificationType GetNotificationType() const override; + mojom::ArcNotificationExpandState GetExpandState() const override; + mojom::ArcNotificationShownContents GetShownContents() const override; + gfx::Rect GetSwipeInputRect() const override; + + void OnUpdatedFromAndroid(mojom::ArcNotificationDataPtr data, + const std::string& app_id) override {} + bool IsManuallyExpandedOrCollapsed() const override; + + private: + std::string notification_key_; + std::string notification_id_; + gfx::ImageSkia snapshot_; + size_t count_close_ = 0; + + base::ObserverList<Observer> observers_; + base::OnceClosure close_callback_; + + base::WeakPtrFactory<MockArcNotificationItem> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(MockArcNotificationItem); +}; + +} // namespace arc + +#endif // UI_ARC_NOTIFICATION_MOCK_ARC_NOTIFICATION_ITEM_H_ |