OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <map> | |
6 #include <memory> | |
7 #include <set> | |
8 #include <string> | |
9 #include <utility> | |
10 | |
11 #include "base/strings/utf_string_conversions.h" | |
12 #include "ui/arc/notification/arc_notification_content_view.h" | |
13 #include "ui/arc/notification/arc_notification_delegate.h" | |
14 #include "ui/arc/notification/arc_notification_item.h" | |
15 #include "ui/arc/notification/arc_notification_surface.h" | |
16 #include "ui/arc/notification/arc_notification_view.h" | |
17 #include "ui/aura/test/test_window_delegate.h" | |
18 #include "ui/aura/window.h" | |
19 #include "ui/message_center/notification.h" | |
20 #include "ui/message_center/views/message_center_controller.h" | |
21 #include "ui/message_center/views/message_view_factory.h" | |
22 #include "ui/views/controls/button/image_button.h" | |
23 #include "ui/views/test/views_test_base.h" | |
24 | |
25 namespace arc { | |
26 | |
27 namespace { | |
28 | |
29 constexpr char kNotificationIdPrefix[] = "ARC_NOTIFICATION_"; | |
30 | |
31 class MockNotificationSurface : public ArcNotificationSurface { | |
32 public: | |
33 MockNotificationSurface(const std::string& notification_key, | |
34 std::unique_ptr<aura::Window> window) | |
35 : notification_key_(notification_key), window_(std::move(window)) {} | |
36 | |
37 gfx::Size GetSize() const override { return gfx::Size(100, 200); } | |
38 | |
39 void Attach(views::NativeViewHost* nvh) override { | |
40 native_view_host_ = nvh; | |
41 nvh->Attach(window_.get()); | |
42 } | |
43 | |
44 void Detach() override { | |
45 EXPECT_TRUE(native_view_host_); | |
46 EXPECT_EQ(window_.get(), native_view_host_->native_view()); | |
47 native_view_host_->Detach(); | |
48 native_view_host_ = nullptr; | |
49 } | |
50 | |
51 bool IsAttached() const override { return native_view_host_; } | |
52 | |
53 aura::Window* GetWindow() const override { return window_.get(); } | |
54 aura::Window* GetContentWindow() const override { return window_.get(); } | |
55 | |
56 const std::string& GetNotificationKey() const override { | |
57 return notification_key_; | |
58 } | |
59 | |
60 private: | |
61 std::string notification_key_; | |
62 std::unique_ptr<aura::Window> window_; | |
63 views::NativeViewHost* native_view_host_ = nullptr; | |
64 | |
65 DISALLOW_COPY_AND_ASSIGN(MockNotificationSurface); | |
66 }; | |
67 | |
68 class TestNotificationSurfaceManager : public ArcNotificationSurfaceManager { | |
69 public: | |
70 TestNotificationSurfaceManager() = default; | |
71 | |
72 void PrepareSurface(std::string& notification_key) { | |
73 auto surface_window = base::MakeUnique<aura::Window>(&window_delegate_); | |
74 surface_window->SetType(aura::client::WINDOW_TYPE_CONTROL); | |
75 surface_window->Init(ui::LAYER_NOT_DRAWN); | |
76 surface_window->set_owned_by_parent(false); | |
77 surface_window->SetBounds(gfx::Rect(0, 0, 100, 200)); | |
78 | |
79 surface_map_[notification_key] = base::MakeUnique<MockNotificationSurface>( | |
80 notification_key, std::move(surface_window)); | |
81 } | |
82 size_t surface_found_count() const { return surface_found_count_; } | |
83 | |
84 ArcNotificationSurface* GetArcSurface( | |
85 const std::string& notification_key) const override { | |
86 auto it = surface_map_.find(notification_key); | |
87 if (it != surface_map_.end()) { | |
88 ++surface_found_count_; | |
89 return it->second.get(); | |
90 } | |
91 return nullptr; | |
92 } | |
93 void AddObserver(Observer* observer) override {} | |
94 void RemoveObserver(Observer* observer) override {} | |
95 | |
96 private: | |
97 // Static for modifying in const method. | |
98 static int surface_found_count_; | |
hidehiko
2017/06/18 17:44:05
Then what you need is mutable, I think.
https://go
yoshiki
2017/06/19 09:09:02
Done.
| |
99 | |
100 aura::test::TestWindowDelegate window_delegate_; | |
101 std::map<std::string, std::unique_ptr<ArcNotificationSurface>> surface_map_; | |
102 | |
103 DISALLOW_COPY_AND_ASSIGN(TestNotificationSurfaceManager); | |
104 }; | |
105 | |
106 int TestNotificationSurfaceManager::surface_found_count_ = 0; | |
107 | |
108 } // anonymous namespace | |
109 | |
110 class MockArcNotificationItem : public ArcNotificationItem { | |
111 public: | |
112 MockArcNotificationItem(const std::string& notification_key) | |
113 : notification_key_(notification_key), | |
114 notification_id_(kNotificationIdPrefix + notification_key), | |
115 weak_factory_(this) {} | |
116 | |
117 // Methods for testing. | |
118 size_t count_close() { return count_close_; } | |
119 base::WeakPtr<MockArcNotificationItem> GetWeakPtr() { | |
120 return weak_factory_.GetWeakPtr(); | |
121 } | |
122 | |
123 // Overriding methods for testing. | |
124 void Close(bool by_user) override { count_close_++; } | |
125 const gfx::ImageSkia& GetSnapshot() const override { return snapshot_; } | |
126 const std::string& GetNotificationKey() const override { | |
127 return notification_key_; | |
128 } | |
129 const std::string& GetNotificationId() const override { | |
130 return notification_id_; | |
131 } | |
132 | |
133 // Overriding methods for returning dummy data or doing nothing. | |
134 void OnClosedFromAndroid() override {} | |
135 void Click() override {} | |
136 void ToggleExpansion() override {} | |
137 void OpenSettings() override {} | |
138 void AddObserver(Observer* observer) override {} | |
139 void RemoveObserver(Observer* observer) override {} | |
140 void IncrementWindowRefCount() override {} | |
141 void DecrementWindowRefCount() override {} | |
142 bool GetPinned() const override { return false; } | |
143 bool IsOpeningSettingsSupported() const override { return true; } | |
144 mojom::ArcNotificationExpandState GetExpandState() const override { | |
145 return mojom::ArcNotificationExpandState::FIXED_SIZE; | |
146 } | |
147 mojom::ArcNotificationShownContents GetShownContents() const override { | |
148 return mojom::ArcNotificationShownContents::CONTENTS_SHOWN; | |
149 } | |
150 const base::string16& GetAccessibleName() const override { | |
151 return base::EmptyString16(); | |
152 }; | |
153 void OnUpdatedFromAndroid(mojom::ArcNotificationDataPtr data) override {} | |
154 | |
155 private: | |
156 std::string notification_key_; | |
157 std::string notification_id_; | |
158 gfx::ImageSkia snapshot_; | |
159 size_t count_close_ = 0; | |
160 | |
161 base::WeakPtrFactory<MockArcNotificationItem> weak_factory_; | |
162 | |
163 DISALLOW_COPY_AND_ASSIGN(MockArcNotificationItem); | |
164 }; | |
165 | |
166 class TestMessageCenterController | |
167 : public message_center::MessageCenterController { | |
168 public: | |
169 TestMessageCenterController() {} | |
hidehiko
2017/06/18 17:44:05
nit: = default; please.
Ditto for below ctors and
yoshiki
2017/06/19 09:09:02
Done.
| |
170 | |
171 // MessageCenterController | |
172 void ClickOnNotification(const std::string& notification_id) override { | |
173 // For this test, this method should not be invoked. | |
174 NOTREACHED(); | |
175 } | |
176 | |
177 void RemoveNotification(const std::string& notification_id, | |
178 bool by_user) override { | |
179 removed_ids_.insert(notification_id); | |
180 } | |
181 | |
182 std::unique_ptr<ui::MenuModel> CreateMenuModel( | |
183 const message_center::NotifierId& notifier_id, | |
184 const base::string16& display_source) override { | |
185 // For this test, this method should not be invoked. | |
186 NOTREACHED(); | |
187 return nullptr; | |
188 } | |
189 | |
190 bool HasClickedListener(const std::string& notification_id) override { | |
191 return false; | |
192 } | |
193 | |
194 void ClickOnNotificationButton(const std::string& notification_id, | |
195 int button_index) override { | |
196 // For this test, this method should not be invoked. | |
197 NOTREACHED(); | |
198 } | |
199 | |
200 void ClickOnSettingsButton(const std::string& notification_id) override { | |
201 // For this test, this method should not be invoked. | |
202 NOTREACHED(); | |
203 } | |
204 | |
205 void UpdateNotificationSize(const std::string& notification_id) override {} | |
206 | |
207 bool IsRemoved(const std::string& notification_id) const { | |
208 return (removed_ids_.find(notification_id) != removed_ids_.end()); | |
209 } | |
210 | |
211 private: | |
212 std::set<std::string> removed_ids_; | |
213 | |
214 DISALLOW_COPY_AND_ASSIGN(TestMessageCenterController); | |
215 }; | |
216 | |
217 class DummyEvent : public ui::Event { | |
218 public: | |
219 DummyEvent() : Event(ui::ET_UNKNOWN, base::TimeTicks(), 0) {} | |
220 ~DummyEvent() override {} | |
221 }; | |
222 | |
223 class ArcNotificationContentViewTest : public views::ViewsTestBase { | |
224 public: | |
225 ArcNotificationContentViewTest() {} | |
226 ~ArcNotificationContentViewTest() override {} | |
227 | |
228 void SetUp() override { | |
229 views::ViewsTestBase::SetUp(); | |
230 | |
231 surface_manager_ = base::MakeUnique<TestNotificationSurfaceManager>(); | |
232 } | |
233 | |
234 void TearDown() override { | |
hidehiko
2017/06/18 17:44:05
nit/optional: Maybe calling CloseNotificationView
yoshiki
2017/06/19 09:09:02
Added checks not to forget call CloseNotificationV
| |
235 surface_manager_.reset(); | |
236 | |
237 views::ViewsTestBase::TearDown(); | |
238 } | |
239 | |
240 void PressCloseButton() { | |
241 DummyEvent dummy_event; | |
242 views::ImageButton* close_button = | |
243 GetArcNotificationContentView()->close_button_.get(); | |
244 ASSERT_NE(nullptr, close_button); | |
245 GetArcNotificationContentView()->ButtonPressed(close_button, dummy_event); | |
246 } | |
247 | |
248 void CreateAndShowNotificationView( | |
249 const message_center::Notification& notification) { | |
250 DCHECK(!notification_view_); | |
251 | |
252 notification_view_.reset(static_cast<ArcNotificationView*>( | |
253 message_center::MessageViewFactory::Create(controller(), notification, | |
254 true))); | |
255 notification_view_->set_owned_by_client(); | |
256 views::Widget::InitParams params( | |
257 CreateParams(views::Widget::InitParams::TYPE_POPUP)); | |
258 | |
259 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
260 wrapper_widget_ = base::MakeUnique<views::Widget>(); | |
261 wrapper_widget_->Init(params); | |
262 wrapper_widget_->SetContentsView(notification_view_.get()); | |
263 wrapper_widget_->SetSize(notification_view_->GetPreferredSize()); | |
264 } | |
265 | |
266 void CloseNotificationView() { | |
267 wrapper_widget_->Close(); | |
268 wrapper_widget_.reset(); | |
269 | |
270 notification_view_.reset(); | |
271 } | |
272 | |
273 message_center::Notification CreateNotification( | |
274 MockArcNotificationItem* notification_item) { | |
275 auto* notification_delegate = | |
276 new ArcNotificationDelegate(notification_item->GetWeakPtr()); | |
hidehiko
2017/06/18 17:44:05
nit: you can inline for consistency.
yoshiki
2017/06/19 09:09:02
Done.
| |
277 | |
278 return message_center::Notification( | |
279 message_center::NOTIFICATION_TYPE_CUSTOM, | |
280 notification_item->GetNotificationId(), base::UTF8ToUTF16("title"), | |
281 base::UTF8ToUTF16("message"), gfx::Image(), base::UTF8ToUTF16("arc"), | |
282 GURL(), | |
283 message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT, | |
284 "ARC_NOTIFICATION"), | |
285 message_center::RichNotificationData(), notification_delegate); | |
286 } | |
287 | |
288 TestMessageCenterController* controller() { return &controller_; } | |
289 TestNotificationSurfaceManager* surface_manager() { | |
290 return surface_manager_.get(); | |
291 } | |
292 views::Widget* widget() { return notification_view_->GetWidget(); } | |
293 | |
294 ArcNotificationContentView* GetArcNotificationContentView() { | |
295 views::View* view = notification_view_->contents_view_; | |
296 EXPECT_EQ(ArcNotificationContentView::kViewClassName, view->GetClassName()); | |
297 return static_cast<ArcNotificationContentView*>(view); | |
298 } | |
299 | |
300 TestNotificationSurfaceManager* surface_manager() const { | |
301 return surface_manager_.get(); | |
302 } | |
303 | |
304 private: | |
305 TestMessageCenterController controller_; | |
306 std::unique_ptr<TestNotificationSurfaceManager> surface_manager_; | |
307 std::unique_ptr<ArcNotificationView> notification_view_; | |
308 std::unique_ptr<views::Widget> wrapper_widget_; | |
309 | |
310 DISALLOW_COPY_AND_ASSIGN(ArcNotificationContentViewTest); | |
311 }; | |
312 | |
313 TEST_F(ArcNotificationContentViewTest, CreateSurfaceAfterNotification) { | |
314 std::string notification_key("notification id"); | |
315 | |
316 auto notification_item = | |
317 base::MakeUnique<MockArcNotificationItem>(notification_key); | |
318 message_center::Notification notification = | |
319 CreateNotification(notification_item.get()); | |
320 | |
321 surface_manager()->PrepareSurface(notification_key); | |
322 | |
323 CreateAndShowNotificationView(notification); | |
324 CloseNotificationView(); | |
325 } | |
326 | |
327 TEST_F(ArcNotificationContentViewTest, CreateSurfaceBeforeNotification) { | |
328 std::string notification_key("notification id"); | |
329 | |
330 surface_manager()->PrepareSurface(notification_key); | |
331 | |
332 auto notification_item = | |
333 base::MakeUnique<MockArcNotificationItem>(notification_key); | |
334 message_center::Notification notification = | |
335 CreateNotification(notification_item.get()); | |
336 | |
337 CreateAndShowNotificationView(notification); | |
338 CloseNotificationView(); | |
339 } | |
340 | |
341 TEST_F(ArcNotificationContentViewTest, CreateNotificationWithoutSurface) { | |
342 std::string notification_key("notification id"); | |
343 | |
344 auto notification_item = | |
345 base::MakeUnique<MockArcNotificationItem>(notification_key); | |
346 message_center::Notification notification = | |
347 CreateNotification(notification_item.get()); | |
348 | |
349 CreateAndShowNotificationView(notification); | |
350 CloseNotificationView(); | |
351 } | |
352 | |
353 TEST_F(ArcNotificationContentViewTest, CloseButton) { | |
354 std::string notification_key("notification id"); | |
355 | |
356 auto notification_item = | |
357 base::MakeUnique<MockArcNotificationItem>(notification_key); | |
358 surface_manager()->PrepareSurface(notification_key); | |
359 message_center::Notification notification = | |
360 CreateNotification(notification_item.get()); | |
361 CreateAndShowNotificationView(notification); | |
362 | |
363 EXPECT_EQ(1u, surface_manager()->surface_found_count()); | |
364 EXPECT_FALSE(controller()->IsRemoved(notification_item->GetNotificationId())); | |
365 PressCloseButton(); | |
366 EXPECT_TRUE(controller()->IsRemoved(notification_item->GetNotificationId())); | |
367 | |
368 CloseNotificationView(); | |
369 } | |
370 | |
371 } // namespace arc | |
OLD | NEW |