OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 "chrome/browser/media/combined_desktop_media_list.h" | |
6 | |
7 #include "base/message_loop/message_loop.h" | |
8 #include "base/single_thread_task_runner.h" | |
9 #include "base/strings/utf_string_conversions.h" | |
10 #include "chrome/browser/media/desktop_media_list_base.h" | |
11 #include "chrome/browser/media/desktop_media_list_observer.h" | |
12 #include "content/public/test/test_browser_thread.h" | |
13 #include "testing/gmock/include/gmock/gmock.h" | |
14 #include "testing/gtest/include/gtest/gtest.h" | |
15 #include "ui/gfx/image/image_skia.h" | |
16 | |
17 using testing::DoAll; | |
18 using content::DesktopMediaID; | |
19 | |
20 static const int kThumbnailSize = 50; | |
21 static const int kDefaultSourceCount = 2; // >=2. | |
Sergey Ulanov
2016/01/27 00:36:31
The comment at the end is confusing. Remove it?
GeorgeZ
2016/01/27 22:57:16
Done.
| |
22 | |
23 // Create a greyscale image with certain size and grayscale value. | |
24 gfx::ImageSkia CreateGrayscaleImage(gfx::Size size, int greyscale_value) { | |
25 SkBitmap result; | |
26 result.allocN32Pixels(size.width(), size.height(), true); | |
27 | |
28 result.lockPixels(); | |
29 uint8_t* pixels_data = reinterpret_cast<uint8_t*>(result.getPixels()); | |
30 | |
31 // Set greyscale value for all pixels. | |
32 for (int y = 0; y < result.height(); ++y) { | |
33 for (int x = 0; x < result.width(); ++x) { | |
34 pixels_data[result.rowBytes() * y + x * result.bytesPerPixel()] = | |
35 greyscale_value; | |
36 pixels_data[result.rowBytes() * y + x * result.bytesPerPixel() + 1] = | |
37 greyscale_value; | |
38 pixels_data[result.rowBytes() * y + x * result.bytesPerPixel() + 2] = | |
39 greyscale_value; | |
40 pixels_data[result.rowBytes() * y + x * result.bytesPerPixel() + 3] = | |
41 0xff; | |
42 } | |
43 } | |
44 | |
45 result.unlockPixels(); | |
46 | |
47 return gfx::ImageSkia::CreateFrom1xBitmap(result); | |
48 } | |
49 | |
50 // Fake Implementation of DesktopMediaListBase. | |
51 class FakeDesktopMediaListBaseImpl : public DesktopMediaListBase { | |
52 public: | |
53 explicit FakeDesktopMediaListBaseImpl(DesktopMediaID::Type type) | |
54 : DesktopMediaListBase(base::TimeDelta::FromMilliseconds(1)), | |
55 media_type_(type) { | |
56 SetThumbnailSize(gfx::Size(kThumbnailSize, kThumbnailSize)); | |
57 | |
58 for (int i = 0; i < kDefaultSourceCount; ++i) | |
59 AddFakeSource(i, base::UTF8ToUTF16("Test media"), | |
60 static_cast<uint8_t>(i)); | |
Sergey Ulanov
2016/01/27 00:36:31
Don't need this cast - the parameter is integer.
GeorgeZ
2016/01/27 22:57:16
Done.
| |
61 } | |
62 | |
63 ~FakeDesktopMediaListBaseImpl() override{}; | |
Sergey Ulanov
2016/01/27 00:36:31
remove ;
add space before {
GeorgeZ
2016/01/27 22:57:16
Done.
| |
64 | |
65 void AddFakeSource(int index, base::string16 title, int greyscale_value) { | |
66 DesktopMediaID id(media_type_, index + 1); | |
67 fake_sources_.push_back(DesktopMediaListBase::SourceDescription(id, title)); | |
68 fake_thumbnails_.push_back( | |
69 CreateGrayscaleImage(gfx::Size(10, 10), greyscale_value)); | |
70 current_thumbnail_map_[id.id] = greyscale_value; | |
71 } | |
72 | |
73 void RemoveFakeSource(int index) { | |
74 if (static_cast<size_t>(index) >= fake_sources_.size()) | |
75 return; | |
76 | |
77 current_thumbnail_map_.erase(fake_sources_[index].id.id); | |
78 fake_sources_.erase(fake_sources_.begin() + index); | |
79 fake_thumbnails_.erase(fake_thumbnails_.begin() + index); | |
80 } | |
81 | |
82 private: | |
83 void Refresh() override { | |
84 UpdateSourcesList(fake_sources_); | |
85 | |
86 // Update thumbnails. | |
87 for (size_t i = 0; i < fake_sources_.size(); i++) { | |
88 // only update when a thumbnail is added or changed. | |
89 const int id = fake_sources_[i].id.id; | |
90 if (!refreshed_thumbnail_map_.count(id) || | |
91 (refreshed_thumbnail_map_[id] != current_thumbnail_map_[id])) { | |
92 UpdateSourceThumbnail(fake_sources_[i].id, fake_thumbnails_[i]); | |
93 } | |
94 } | |
95 refreshed_thumbnail_map_ = current_thumbnail_map_; | |
96 | |
97 ScheduleNextRefresh(); | |
98 } | |
99 | |
100 std::vector<DesktopMediaListBase::SourceDescription> fake_sources_; | |
101 std::vector<gfx::ImageSkia> fake_thumbnails_; | |
102 DesktopMediaID::Type media_type_; | |
103 // The current and last refrehed maps of source id and thumbnail's greyscale. | |
104 // They are used for detect the thumbnail add or change. | |
105 std::map<int, int> current_thumbnail_map_, refreshed_thumbnail_map_; | |
106 | |
107 DISALLOW_COPY_AND_ASSIGN(FakeDesktopMediaListBaseImpl); | |
108 }; | |
109 | |
110 class MockObserver : public DesktopMediaListObserver { | |
111 public: | |
112 MOCK_METHOD2(OnSourceAdded, void(DesktopMediaList* list, int index)); | |
113 MOCK_METHOD2(OnSourceRemoved, void(DesktopMediaList* list, int index)); | |
114 MOCK_METHOD3(OnSourceMoved, | |
115 void(DesktopMediaList* list, int old_index, int new_index)); | |
116 MOCK_METHOD2(OnSourceNameChanged, void(DesktopMediaList* list, int index)); | |
117 MOCK_METHOD2(OnSourceThumbnailChanged, | |
118 void(DesktopMediaList* list, int index)); | |
119 | |
120 void VerifyAndClearExpectations() { | |
121 testing::Mock::VerifyAndClearExpectations(this); | |
122 } | |
123 }; | |
124 | |
125 ACTION_P2(CheckListSize, list, expected_list_size) { | |
126 EXPECT_EQ(expected_list_size, list->GetSourceCount()); | |
127 } | |
128 | |
129 ACTION_P(QuitMessageLoop, message_loop) { | |
130 message_loop->task_runner()->PostTask( | |
131 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | |
132 } | |
133 | |
134 class CombinedDesktopMediaListTest : public testing::Test { | |
135 public: | |
136 CombinedDesktopMediaListTest() | |
137 : ui_thread_(content::BrowserThread::UI, &message_loop_) { | |
138 list1_ = new FakeDesktopMediaListBaseImpl(DesktopMediaID::TYPE_SCREEN); | |
139 list2_ = new FakeDesktopMediaListBaseImpl(DesktopMediaID::TYPE_WINDOW); | |
140 | |
141 scoped_ptr<DesktopMediaList> list1(list1_); | |
142 scoped_ptr<DesktopMediaList> list2(list2_); | |
143 | |
144 std::vector<scoped_ptr<DesktopMediaList>> lists; | |
145 lists.push_back(std::move(list1)); | |
146 lists.push_back(std::move(list2)); | |
147 | |
148 combined_list_.reset(new CombinedDesktopMediaList(lists)); | |
149 } | |
150 | |
151 // StartUpdating() and verify the first call of refresh(). | |
152 void InitializeAndVerify() { | |
153 { | |
154 testing::InSequence dummy; | |
155 | |
156 // list1_'s refresh. | |
157 for (int i = 0; i < kDefaultSourceCount; ++i) { | |
158 EXPECT_CALL(observer_, OnSourceAdded(combined_list_.get(), i)) | |
159 .WillOnce(CheckListSize(combined_list_.get(), i + 1)); | |
160 } | |
161 | |
162 for (int i = 0; i < kDefaultSourceCount; ++i) { | |
163 EXPECT_CALL(observer_, | |
164 OnSourceThumbnailChanged(combined_list_.get(), i)); | |
165 } | |
166 | |
167 // list2_'s refresh. | |
168 for (int i = kDefaultSourceCount; i < 2 * kDefaultSourceCount; ++i) { | |
169 EXPECT_CALL(observer_, OnSourceAdded(combined_list_.get(), i)) | |
170 .WillOnce(CheckListSize(combined_list_.get(), i + 1)); | |
171 } | |
172 | |
173 for (int i = kDefaultSourceCount; i < 2 * kDefaultSourceCount - 1; ++i) { | |
174 EXPECT_CALL(observer_, | |
175 OnSourceThumbnailChanged(combined_list_.get(), i)); | |
176 } | |
177 | |
178 EXPECT_CALL(observer_, | |
179 OnSourceThumbnailChanged(combined_list_.get(), | |
180 2 * kDefaultSourceCount - 1)) | |
181 .WillOnce(QuitMessageLoop(&message_loop_)); | |
182 } | |
183 | |
184 combined_list_->StartUpdating(&observer_); | |
185 message_loop_.Run(); | |
186 | |
187 // list1_'s sources. | |
188 for (int i = 0; i < kDefaultSourceCount; ++i) { | |
189 EXPECT_EQ(combined_list_->GetSource(i).id.type, | |
190 content::DesktopMediaID::TYPE_SCREEN); | |
191 EXPECT_EQ(combined_list_->GetSource(i).id.id, i + 1); | |
192 } | |
193 | |
194 // list2_'s sources. | |
195 for (int i = kDefaultSourceCount; i < 2 * kDefaultSourceCount; i++) { | |
196 EXPECT_EQ(combined_list_->GetSource(i).id.type, | |
197 content::DesktopMediaID::TYPE_WINDOW); | |
198 EXPECT_EQ(combined_list_->GetSource(i).id.id, | |
199 i - kDefaultSourceCount + 1); | |
200 } | |
201 | |
202 observer_.VerifyAndClearExpectations(); | |
203 } | |
204 | |
205 protected: | |
206 // Must be listed before |combined_list_|, so it's destroyed last. | |
207 MockObserver observer_; | |
208 FakeDesktopMediaListBaseImpl* list1_; | |
209 FakeDesktopMediaListBaseImpl* list2_; | |
210 scoped_ptr<CombinedDesktopMediaList> combined_list_; | |
211 | |
212 base::MessageLoop message_loop_; | |
213 content::TestBrowserThread ui_thread_; | |
214 | |
215 DISALLOW_COPY_AND_ASSIGN(CombinedDesktopMediaListTest); | |
216 }; | |
217 | |
218 TEST_F(CombinedDesktopMediaListTest, AddSource) { | |
219 InitializeAndVerify(); | |
220 | |
221 int index = kDefaultSourceCount; | |
222 list1_->AddFakeSource(index, base::UTF8ToUTF16("Test media"), | |
223 static_cast<uint8_t>(index)); | |
224 | |
225 EXPECT_CALL(observer_, OnSourceAdded(combined_list_.get(), index)) | |
226 .WillOnce( | |
227 CheckListSize(combined_list_.get(), 2 * kDefaultSourceCount + 1)); | |
228 EXPECT_CALL(observer_, OnSourceThumbnailChanged(combined_list_.get(), index)) | |
229 .WillOnce(QuitMessageLoop(&message_loop_)); | |
230 | |
231 message_loop_.Run(); | |
232 | |
233 list2_->AddFakeSource(index, base::UTF8ToUTF16("Test media"), | |
234 static_cast<uint8_t>(index)); | |
235 | |
236 EXPECT_CALL(observer_, | |
237 OnSourceAdded(combined_list_.get(), 2 * kDefaultSourceCount + 1)) | |
238 .WillOnce( | |
239 CheckListSize(combined_list_.get(), 2 * kDefaultSourceCount + 2)); | |
240 EXPECT_CALL(observer_, OnSourceThumbnailChanged(combined_list_.get(), | |
241 2 * kDefaultSourceCount + 1)) | |
242 .WillOnce(QuitMessageLoop(&message_loop_)); | |
243 | |
244 message_loop_.Run(); | |
Sergey Ulanov
2016/01/27 00:36:31
I think you want to call SetUpdatePeriod() for all
GeorgeZ
2016/01/27 22:57:16
in lines 53&54
explicit FakeDesktopMediaListBaseI
| |
245 | |
246 // Verify last source for list1_ and first source for list2_. | |
247 EXPECT_EQ(combined_list_->GetSource(index).id.type, | |
248 content::DesktopMediaID::TYPE_SCREEN); | |
249 EXPECT_EQ(combined_list_->GetSource(index).id.id, index + 1); | |
250 EXPECT_EQ(combined_list_->GetSource(index + 1).id.type, | |
251 content::DesktopMediaID::TYPE_WINDOW); | |
252 EXPECT_EQ(combined_list_->GetSource(index + 1).id.id, 1); | |
253 } | |
254 | |
255 TEST_F(CombinedDesktopMediaListTest, RemoveSource) { | |
256 InitializeAndVerify(); | |
257 | |
258 int index = kDefaultSourceCount - 1; | |
259 list1_->RemoveFakeSource(index); | |
260 | |
261 EXPECT_CALL(observer_, OnSourceRemoved(combined_list_.get(), index)) | |
262 .WillOnce(DoAll( | |
263 CheckListSize(combined_list_.get(), 2 * kDefaultSourceCount - 1), | |
264 QuitMessageLoop(&message_loop_))); | |
265 | |
266 message_loop_.Run(); | |
267 | |
268 list2_->RemoveFakeSource(index); | |
269 | |
270 EXPECT_CALL(observer_, OnSourceRemoved(combined_list_.get(), | |
271 2 * kDefaultSourceCount - 2)) | |
272 .WillOnce(DoAll( | |
273 CheckListSize(combined_list_.get(), 2 * kDefaultSourceCount - 2), | |
274 QuitMessageLoop(&message_loop_))); | |
275 | |
276 message_loop_.Run(); | |
277 | |
278 // Verify last source for list1_ and first source for list2_. | |
279 EXPECT_EQ(combined_list_->GetSource(index - 1).id.type, | |
280 content::DesktopMediaID::TYPE_SCREEN); | |
281 EXPECT_EQ(combined_list_->GetSource(index - 1).id.id, index); | |
282 EXPECT_EQ(combined_list_->GetSource(index).id.type, | |
283 content::DesktopMediaID::TYPE_WINDOW); | |
284 EXPECT_EQ(combined_list_->GetSource(index).id.id, 1); | |
285 } | |
286 | |
287 TEST_F(CombinedDesktopMediaListTest, MoveSource) { | |
288 InitializeAndVerify(); | |
289 | |
290 // Swap sources. | |
291 list1_->RemoveFakeSource(kDefaultSourceCount - 1); | |
292 list1_->RemoveFakeSource(kDefaultSourceCount - 2); | |
293 list1_->AddFakeSource(kDefaultSourceCount - 1, | |
294 base::UTF8ToUTF16("Test media"), | |
295 static_cast<uint8_t>(kDefaultSourceCount - 1)); | |
296 list1_->AddFakeSource(kDefaultSourceCount - 2, | |
297 base::UTF8ToUTF16("Test media"), | |
298 static_cast<uint8_t>(kDefaultSourceCount - 2)); | |
299 | |
300 EXPECT_CALL(observer_, | |
301 OnSourceMoved(combined_list_.get(), kDefaultSourceCount - 1, | |
302 kDefaultSourceCount - 2)) | |
303 .WillOnce(QuitMessageLoop(&message_loop_)); | |
304 | |
305 message_loop_.Run(); | |
306 | |
307 // Swap sources. | |
308 list2_->RemoveFakeSource(kDefaultSourceCount - 1); | |
309 list2_->RemoveFakeSource(kDefaultSourceCount - 2); | |
310 list2_->AddFakeSource(kDefaultSourceCount - 1, | |
311 base::UTF8ToUTF16("Test media"), | |
312 static_cast<uint8_t>(kDefaultSourceCount - 1)); | |
313 list2_->AddFakeSource(kDefaultSourceCount - 2, | |
314 base::UTF8ToUTF16("Test media"), | |
315 static_cast<uint8_t>(kDefaultSourceCount - 2)); | |
316 | |
317 EXPECT_CALL(observer_, | |
318 OnSourceMoved(combined_list_.get(), 2 * kDefaultSourceCount - 1, | |
319 2 * kDefaultSourceCount - 2)) | |
320 .WillOnce(QuitMessageLoop(&message_loop_)); | |
321 | |
322 message_loop_.Run(); | |
323 } | |
324 | |
325 TEST_F(CombinedDesktopMediaListTest, UpdateTitle) { | |
326 InitializeAndVerify(); | |
327 | |
328 // Change title. | |
329 list1_->RemoveFakeSource(kDefaultSourceCount - 1); | |
330 list1_->AddFakeSource(kDefaultSourceCount - 1, | |
331 base::UTF8ToUTF16("New test media"), | |
332 static_cast<uint8_t>(kDefaultSourceCount - 1)); | |
333 | |
334 EXPECT_CALL(observer_, OnSourceNameChanged(combined_list_.get(), | |
335 kDefaultSourceCount - 1)) | |
336 .WillOnce(QuitMessageLoop(&message_loop_)); | |
337 | |
338 message_loop_.Run(); | |
339 | |
340 // Change title. | |
341 list2_->RemoveFakeSource(kDefaultSourceCount - 1); | |
342 list2_->AddFakeSource(kDefaultSourceCount - 1, | |
343 base::UTF8ToUTF16("New test media"), | |
344 static_cast<uint8_t>(kDefaultSourceCount - 1)); | |
345 | |
346 EXPECT_CALL(observer_, OnSourceNameChanged(combined_list_.get(), | |
347 2 * kDefaultSourceCount - 1)) | |
348 .WillOnce(QuitMessageLoop(&message_loop_)); | |
349 | |
350 message_loop_.Run(); | |
351 | |
352 EXPECT_EQ(combined_list_->GetSource(kDefaultSourceCount - 1).name, | |
353 base::UTF8ToUTF16("New test media")); | |
354 EXPECT_EQ(combined_list_->GetSource(2 * kDefaultSourceCount - 1).name, | |
355 base::UTF8ToUTF16("New test media")); | |
356 } | |
357 | |
358 TEST_F(CombinedDesktopMediaListTest, UpdateThumbnail) { | |
359 InitializeAndVerify(); | |
360 | |
361 // Change thumbnail. | |
362 list1_->RemoveFakeSource(kDefaultSourceCount - 1); | |
363 list1_->AddFakeSource(kDefaultSourceCount - 1, | |
364 base::UTF8ToUTF16("Test media"), 100); | |
365 | |
366 EXPECT_CALL(observer_, OnSourceThumbnailChanged(combined_list_.get(), | |
367 kDefaultSourceCount - 1)) | |
368 .WillOnce(QuitMessageLoop(&message_loop_)); | |
369 | |
370 message_loop_.Run(); | |
371 | |
372 // Change thumbnail. | |
373 list2_->RemoveFakeSource(kDefaultSourceCount - 1); | |
374 list2_->AddFakeSource(kDefaultSourceCount - 1, | |
375 base::UTF8ToUTF16("Test media"), 100); | |
376 | |
377 EXPECT_CALL(observer_, OnSourceThumbnailChanged(combined_list_.get(), | |
378 2 * kDefaultSourceCount - 1)) | |
379 .WillOnce(QuitMessageLoop(&message_loop_)); | |
380 | |
381 message_loop_.Run(); | |
382 } | |
OLD | NEW |