1 /*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <algorithm>
18 #include <iostream>
19
20 #include <base/bind.h>
21 #include <base/logging.h>
22 #include <base/threading/thread.h>
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25
26 #include "avrcp_packet.h"
27 #include "avrcp_test_helper.h"
28 #include "device.h"
29 #include "stack_config.h"
30 #include "tests/avrcp/avrcp_test_packets.h"
31 #include "tests/packet_test_helper.h"
32
33 namespace bluetooth {
34 namespace avrcp {
35
36 // TODO (apanicke): All the tests below are just basic positive unit tests.
37 // Add more tests to increase code coverage.
38
39 using AvrcpResponse = std::unique_ptr<::bluetooth::PacketBuilder>;
40 using TestAvrcpPacket = TestPacketType<Packet>;
41 using TestBrowsePacket = TestPacketType<BrowsePacket>;
42
43 using ::testing::_;
44 using ::testing::Mock;
45 using ::testing::MockFunction;
46 using ::testing::NiceMock;
47 using ::testing::Return;
48 using ::testing::SaveArg;
49
get_pts_avrcp_test(void)50 bool get_pts_avrcp_test(void) { return false; }
51
52 const stack_config_t interface = {
53 nullptr, get_pts_avrcp_test, nullptr, nullptr, nullptr, nullptr, nullptr,
54 nullptr};
55
56 // TODO (apanicke): All the tests below are just basic positive unit tests.
57 // Add more tests to increase code coverage.
58 class AvrcpDeviceTest : public ::testing::Test {
59 public:
SetUp()60 void SetUp() override {
61 // NOTE: We use a wrapper lambda for the MockFunction in order to
62 // add a const qualifier to the response. Otherwise the MockFunction
63 // type doesn't match the callback type and a compiler error occurs.
64 base::Callback<void(uint8_t, bool, AvrcpResponse)> cb = base::Bind(
65 [](MockFunction<void(uint8_t, bool, const AvrcpResponse&)>* a,
66 uint8_t b, bool c, AvrcpResponse d) { a->Call(b, c, d); },
67 &response_cb);
68
69 // TODO (apanicke): Test setting avrc13 to false once we have full
70 // functionality.
71 test_device = new Device(RawAddress::kAny, true, cb, 0xFFFF, 0xFFFF);
72 }
73
TearDown()74 void TearDown() override {
75 delete test_device;
76 Mock::VerifyAndClear(&response_cb);
77 }
78
SendMessage(uint8_t label,std::shared_ptr<Packet> message)79 void SendMessage(uint8_t label, std::shared_ptr<Packet> message) {
80 test_device->MessageReceived(label, message);
81 }
82
SendBrowseMessage(uint8_t label,std::shared_ptr<BrowsePacket> message)83 void SendBrowseMessage(uint8_t label, std::shared_ptr<BrowsePacket> message) {
84 test_device->BrowseMessageReceived(label, message);
85 }
86
SetBipClientStatus(bool connected)87 void SetBipClientStatus(bool connected) {
88 test_device->SetBipClientStatus(connected);
89 }
90
FilterCoverArt(SongInfo & s)91 void FilterCoverArt(SongInfo& s) {
92 for (auto it = s.attributes.begin(); it != s.attributes.end(); it++) {
93 if (it->attribute() == Attribute::DEFAULT_COVER_ART) {
94 s.attributes.erase(it);
95 break;
96 }
97 }
98 }
99
100 MockFunction<void(uint8_t, bool, const AvrcpResponse&)> response_cb;
101 Device* test_device;
102 };
103
TEST_F(AvrcpDeviceTest,addressTest)104 TEST_F(AvrcpDeviceTest, addressTest) {
105 base::Callback<void(uint8_t, bool, AvrcpResponse)> cb =
106 base::Bind([](MockFunction<void(uint8_t, bool, const AvrcpResponse&)>* a,
107 uint8_t b, bool c, AvrcpResponse d) { a->Call(b, c, d); },
108 &response_cb);
109
110 Device device(RawAddress::kAny, true, cb, 0xFFFF, 0xFFFF);
111 ASSERT_EQ(device.GetAddress(), RawAddress::kAny);
112 }
113
TEST_F(AvrcpDeviceTest,setBipClientStatusTest)114 TEST_F(AvrcpDeviceTest, setBipClientStatusTest) {
115 ASSERT_EQ(test_device->HasBipClient(), false);
116 SetBipClientStatus(true);
117 ASSERT_EQ(test_device->HasBipClient(), true);
118 SetBipClientStatus(false);
119 ASSERT_EQ(test_device->HasBipClient(), false);
120 }
121
TEST_F(AvrcpDeviceTest,trackChangedTest)122 TEST_F(AvrcpDeviceTest, trackChangedTest) {
123 MockMediaInterface interface;
124 NiceMock<MockA2dpInterface> a2dp_interface;
125
126 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
127
128 SongInfo info = {"test_id",
129 {// The attribute map
130 AttributeEntry(Attribute::TITLE, "Test Song"),
131 AttributeEntry(Attribute::ARTIST_NAME, "Test Artist"),
132 AttributeEntry(Attribute::ALBUM_NAME, "Test Album"),
133 AttributeEntry(Attribute::TRACK_NUMBER, "1"),
134 AttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2"),
135 AttributeEntry(Attribute::GENRE, "Test Genre"),
136 AttributeEntry(Attribute::PLAYING_TIME, "1000"),
137 AttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001")}};
138 std::vector<SongInfo> list = {info};
139
140 EXPECT_CALL(interface, GetNowPlayingList(_))
141 .Times(2)
142 .WillRepeatedly(InvokeCb<0>("test_id", list));
143
144 // Test the interim response for track changed
145 auto interim_response =
146 RegisterNotificationResponseBuilder::MakeTrackChangedBuilder(true, 0x01);
147 EXPECT_CALL(response_cb,
148 Call(1, false, matchPacket(std::move(interim_response))))
149 .Times(1);
150
151 auto request =
152 RegisterNotificationRequestBuilder::MakeBuilder(Event::TRACK_CHANGED, 0);
153 auto pkt = TestAvrcpPacket::Make();
154 request->Serialize(pkt);
155 SendMessage(1, pkt);
156
157 // Test the changed response for track changed
158 auto changed_response =
159 RegisterNotificationResponseBuilder::MakeTrackChangedBuilder(false, 0x01);
160 EXPECT_CALL(response_cb,
161 Call(1, false, matchPacket(std::move(changed_response))))
162 .Times(1);
163
164 test_device->HandleTrackUpdate();
165 }
166
TEST_F(AvrcpDeviceTest,playStatusTest)167 TEST_F(AvrcpDeviceTest, playStatusTest) {
168 MockMediaInterface interface;
169 NiceMock<MockA2dpInterface> a2dp_interface;
170
171 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
172
173 PlayStatus status1 = {0x1234, 0x5678, PlayState::PLAYING};
174 PlayStatus status2 = {0x1234, 0x5678, PlayState::STOPPED};
175
176 EXPECT_CALL(interface, GetPlayStatus(_))
177 .Times(2)
178 .WillOnce(InvokeCb<0>(status1))
179 .WillOnce(InvokeCb<0>(status2));
180
181 // Pretend the device is active
182 EXPECT_CALL(a2dp_interface, active_peer())
183 .WillRepeatedly(Return(test_device->GetAddress()));
184
185 // Test the interim response for play status changed
186 auto interim_response =
187 RegisterNotificationResponseBuilder::MakePlaybackStatusBuilder(
188 true, PlayState::PLAYING);
189 EXPECT_CALL(response_cb,
190 Call(1, false, matchPacket(std::move(interim_response))))
191 .Times(1);
192
193 auto request = RegisterNotificationRequestBuilder::MakeBuilder(
194 Event::PLAYBACK_STATUS_CHANGED, 0);
195 auto pkt = TestAvrcpPacket::Make();
196 request->Serialize(pkt);
197 SendMessage(1, pkt);
198
199 // Test the changed response for play status changed
200 auto changed_response =
201 RegisterNotificationResponseBuilder::MakePlaybackStatusBuilder(
202 false, PlayState::STOPPED);
203 EXPECT_CALL(response_cb,
204 Call(1, false, matchPacket(std::move(changed_response))))
205 .Times(1);
206 test_device->HandlePlayStatusUpdate();
207 }
208
TEST_F(AvrcpDeviceTest,playPositionTest)209 TEST_F(AvrcpDeviceTest, playPositionTest) {
210 MockMediaInterface interface;
211 NiceMock<MockA2dpInterface> a2dp_interface;
212
213 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
214
215 // TODO (apanicke): Add an underlying message loop so we can test the playing
216 // state.
217 PlayStatus status1 = {0x1234, 0x5678, PlayState::PAUSED};
218 PlayStatus status2 = {0x5678, 0x9ABC, PlayState::STOPPED};
219
220 EXPECT_CALL(interface, GetPlayStatus(_))
221 .Times(2)
222 .WillOnce(InvokeCb<0>(status1))
223 .WillOnce(InvokeCb<0>(status2));
224
225 // Pretend the device is active
226 EXPECT_CALL(a2dp_interface, active_peer())
227 .WillRepeatedly(Return(test_device->GetAddress()));
228
229 // Test the interim response for play position changed
230 auto interim_response =
231 RegisterNotificationResponseBuilder::MakePlaybackPositionBuilder(true,
232 0x1234);
233 EXPECT_CALL(response_cb,
234 Call(1, false, matchPacket(std::move(interim_response))))
235 .Times(1);
236
237 auto request = RegisterNotificationRequestBuilder::MakeBuilder(
238 Event::PLAYBACK_POS_CHANGED, 0);
239 auto pkt = TestAvrcpPacket::Make();
240 request->Serialize(pkt);
241 SendMessage(1, pkt);
242
243 // Test the changed response for play position changed
244 auto changed_response =
245 RegisterNotificationResponseBuilder::MakePlaybackPositionBuilder(false,
246 0x5678);
247 EXPECT_CALL(response_cb,
248 Call(1, false, matchPacket(std::move(changed_response))))
249 .Times(1);
250 test_device->HandlePlayPosUpdate();
251 }
252
TEST_F(AvrcpDeviceTest,trackChangedBeforeInterimTest)253 TEST_F(AvrcpDeviceTest, trackChangedBeforeInterimTest) {
254 MockMediaInterface interface;
255 NiceMock<MockA2dpInterface> a2dp_interface;
256
257 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
258
259 // Pretend the device is active
260 EXPECT_CALL(a2dp_interface, active_peer())
261 .WillRepeatedly(Return(test_device->GetAddress()));
262
263 SongInfo info = {"test_id",
264 {// The attribute map
265 AttributeEntry(Attribute::TITLE, "Test Song"),
266 AttributeEntry(Attribute::ARTIST_NAME, "Test Artist"),
267 AttributeEntry(Attribute::ALBUM_NAME, "Test Album"),
268 AttributeEntry(Attribute::TRACK_NUMBER, "1"),
269 AttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2"),
270 AttributeEntry(Attribute::GENRE, "Test Genre"),
271 AttributeEntry(Attribute::PLAYING_TIME, "1000"),
272 AttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001")}};
273 std::vector<SongInfo> list = {info};
274
275 MediaInterface::NowPlayingCallback interim_cb;
276 MediaInterface::NowPlayingCallback changed_cb;
277
278 EXPECT_CALL(interface, GetNowPlayingList(_))
279 .Times(2)
280 .WillOnce(SaveArg<0>(&interim_cb))
281 .WillOnce(SaveArg<0>(&changed_cb));
282
283 // Test that the changed response doesn't get sent before the interim
284 ::testing::InSequence s;
285 auto interim_response =
286 RegisterNotificationResponseBuilder::MakeTrackChangedBuilder(true, 0x01);
287 EXPECT_CALL(response_cb,
288 Call(1, false, matchPacket(std::move(interim_response))))
289 .Times(1);
290 auto changed_response =
291 RegisterNotificationResponseBuilder::MakeTrackChangedBuilder(false, 0x01);
292 EXPECT_CALL(response_cb,
293 Call(1, false, matchPacket(std::move(changed_response))))
294 .Times(1);
295
296 // Register for the update, sets interim_cb
297 auto request =
298 RegisterNotificationRequestBuilder::MakeBuilder(Event::TRACK_CHANGED, 0);
299 auto pkt = TestAvrcpPacket::Make();
300 request->Serialize(pkt);
301 SendMessage(1, pkt);
302
303 // Try to send track changed update, should fail and do nothing
304 test_device->HandleTrackUpdate();
305
306 // Send the interim response
307 interim_cb.Run("test_id", list);
308
309 // Try to send track changed update, should succeed
310 test_device->HandleTrackUpdate();
311 changed_cb.Run("test_id", list);
312 }
313
TEST_F(AvrcpDeviceTest,playStatusChangedBeforeInterimTest)314 TEST_F(AvrcpDeviceTest, playStatusChangedBeforeInterimTest) {
315 MockMediaInterface interface;
316 NiceMock<MockA2dpInterface> a2dp_interface;
317
318 // Pretend the device is active
319 EXPECT_CALL(a2dp_interface, active_peer())
320 .WillRepeatedly(Return(test_device->GetAddress()));
321
322 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
323
324 MediaInterface::PlayStatusCallback interim_cb;
325 MediaInterface::PlayStatusCallback changed_cb;
326
327 EXPECT_CALL(interface, GetPlayStatus(_))
328 .Times(2)
329 .WillOnce(SaveArg<0>(&interim_cb))
330 .WillOnce(SaveArg<0>(&changed_cb));
331
332 // Test that the changed response doesn't get sent before the interim
333 ::testing::InSequence s;
334 auto interim_response =
335 RegisterNotificationResponseBuilder::MakePlaybackStatusBuilder(
336 true, PlayState::PLAYING);
337 EXPECT_CALL(response_cb,
338 Call(1, false, matchPacket(std::move(interim_response))))
339 .Times(1);
340 auto changed_response =
341 RegisterNotificationResponseBuilder::MakePlaybackStatusBuilder(
342 false, PlayState::STOPPED);
343 EXPECT_CALL(response_cb,
344 Call(1, false, matchPacket(std::move(changed_response))))
345 .Times(1);
346
347 // Send the registration packet
348 auto request = RegisterNotificationRequestBuilder::MakeBuilder(
349 Event::PLAYBACK_STATUS_CHANGED, 0);
350 auto pkt = TestAvrcpPacket::Make();
351 request->Serialize(pkt);
352 SendMessage(1, pkt);
353
354 // Send a play status update, should be ignored since the interim response
355 // hasn't been sent yet.
356 test_device->HandlePlayStatusUpdate();
357
358 // Send the interim response.
359 PlayStatus status1 = {0x1234, 0x5678, PlayState::PLAYING};
360 interim_cb.Run(status1);
361
362 // Send the changed response, should succeed this time
363 test_device->HandlePlayStatusUpdate();
364 PlayStatus status2 = {0x1234, 0x5678, PlayState::STOPPED};
365 changed_cb.Run(status2);
366 }
367
TEST_F(AvrcpDeviceTest,playPositionChangedBeforeInterimTest)368 TEST_F(AvrcpDeviceTest, playPositionChangedBeforeInterimTest) {
369 MockMediaInterface interface;
370 NiceMock<MockA2dpInterface> a2dp_interface;
371
372 // Pretend the device is active
373 EXPECT_CALL(a2dp_interface, active_peer())
374 .WillRepeatedly(Return(test_device->GetAddress()));
375
376 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
377
378 MediaInterface::PlayStatusCallback interim_cb;
379 MediaInterface::PlayStatusCallback changed_cb;
380
381 EXPECT_CALL(interface, GetPlayStatus(_))
382 .Times(2)
383 .WillOnce(SaveArg<0>(&interim_cb))
384 .WillOnce(SaveArg<0>(&changed_cb));
385
386 // Test that the changed response doesn't get sent before the interim
387 ::testing::InSequence s;
388 auto interim_response =
389 RegisterNotificationResponseBuilder::MakePlaybackPositionBuilder(true,
390 0x1234);
391 EXPECT_CALL(response_cb,
392 Call(1, false, matchPacket(std::move(interim_response))))
393 .Times(1);
394 auto changed_response =
395 RegisterNotificationResponseBuilder::MakePlaybackPositionBuilder(false,
396 0x5678);
397 EXPECT_CALL(response_cb,
398 Call(1, false, matchPacket(std::move(changed_response))))
399 .Times(1);
400
401 // Send the registration packet
402 auto request = RegisterNotificationRequestBuilder::MakeBuilder(
403 Event::PLAYBACK_POS_CHANGED, 0);
404 auto pkt = TestAvrcpPacket::Make();
405 request->Serialize(pkt);
406 SendMessage(1, pkt);
407
408 // Send a play position update, should be ignored since the notification
409 // isn't registered since no interim response has been sent.
410 test_device->HandlePlayPosUpdate();
411
412 // Run the interim callback for GetPlayStatus which should be pointing to the
413 // GetPlayStatus call made by the update.
414 PlayStatus status1 = {0x1234, 0x5678, PlayState::PAUSED};
415 interim_cb.Run(status1);
416
417 // Send a play position update, this one should succeed.
418 test_device->HandlePlayPosUpdate();
419 PlayStatus status2 = {0x5678, 0x9ABC, PlayState::STOPPED};
420 changed_cb.Run(status2);
421 }
422
TEST_F(AvrcpDeviceTest,nowPlayingChangedBeforeInterim)423 TEST_F(AvrcpDeviceTest, nowPlayingChangedBeforeInterim) {
424 MockMediaInterface interface;
425 NiceMock<MockA2dpInterface> a2dp_interface;
426
427 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
428
429 SongInfo info = {"test_id",
430 {// The attribute map
431 AttributeEntry(Attribute::TITLE, "Test Song"),
432 AttributeEntry(Attribute::ARTIST_NAME, "Test Artist"),
433 AttributeEntry(Attribute::ALBUM_NAME, "Test Album"),
434 AttributeEntry(Attribute::TRACK_NUMBER, "1"),
435 AttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2"),
436 AttributeEntry(Attribute::GENRE, "Test Genre"),
437 AttributeEntry(Attribute::PLAYING_TIME, "1000"),
438 AttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001")}};
439 std::vector<SongInfo> list = {info};
440
441 MediaInterface::NowPlayingCallback interim_cb;
442 MediaInterface::NowPlayingCallback changed_cb;
443
444 EXPECT_CALL(interface, GetNowPlayingList(_))
445 .Times(2)
446 .WillOnce(SaveArg<0>(&interim_cb))
447 .WillOnce(SaveArg<0>(&changed_cb));
448
449 // Test that the changed response doesn't get sent before the interim
450 ::testing::InSequence s;
451 auto interim_response =
452 RegisterNotificationResponseBuilder::MakeNowPlayingBuilder(true);
453 EXPECT_CALL(response_cb,
454 Call(1, false, matchPacket(std::move(interim_response))))
455 .Times(1);
456 auto changed_response =
457 RegisterNotificationResponseBuilder::MakeNowPlayingBuilder(false);
458 EXPECT_CALL(response_cb,
459 Call(1, false, matchPacket(std::move(changed_response))))
460 .Times(1);
461
462 // Send the registration packet
463 auto request = RegisterNotificationRequestBuilder::MakeBuilder(
464 Event::NOW_PLAYING_CONTENT_CHANGED, 0);
465 auto pkt = TestAvrcpPacket::Make();
466 request->Serialize(pkt);
467 SendMessage(1, pkt);
468
469 // Send now playing changed, should fail since the interim response hasn't
470 // been sent
471 test_device->HandleNowPlayingUpdate();
472
473 // Send the data needed for the interim response
474 interim_cb.Run("test_id", list);
475
476 // Send now playing changed, should succeed
477 test_device->HandleNowPlayingUpdate();
478 changed_cb.Run("test_id", list);
479 }
480
TEST_F(AvrcpDeviceTest,addressPlayerChangedBeforeInterim)481 TEST_F(AvrcpDeviceTest, addressPlayerChangedBeforeInterim) {
482 MockMediaInterface interface;
483 NiceMock<MockA2dpInterface> a2dp_interface;
484
485 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
486
487 MediaInterface::MediaListCallback interim_cb;
488 MediaInterface::MediaListCallback changed_cb;
489
490 EXPECT_CALL(interface, GetMediaPlayerList(_))
491 .Times(2)
492 .WillOnce(SaveArg<0>(&interim_cb))
493 .WillOnce(SaveArg<0>(&changed_cb));
494
495 // Test that the changed response doesn't get sent before the interim
496 ::testing::InSequence s;
497 auto interim_response =
498 RegisterNotificationResponseBuilder::MakeAddressedPlayerBuilder(true, 0,
499 0);
500 EXPECT_CALL(response_cb,
501 Call(1, false, matchPacket(std::move(interim_response))))
502 .Times(1);
503 auto changed_response =
504 RegisterNotificationResponseBuilder::MakeAddressedPlayerBuilder(false, 0,
505 0);
506 EXPECT_CALL(response_cb,
507 Call(1, false, matchPacket(std::move(changed_response))))
508 .Times(1);
509 // TODO (apanicke): Remove this expectation once b/110957802 is fixed and
510 // we don't try to reject notifications that aren't registered.
511 auto rejected_response = RejectBuilder::MakeBuilder(
512 CommandPdu::REGISTER_NOTIFICATION, Status::ADDRESSED_PLAYER_CHANGED);
513 EXPECT_CALL(response_cb,
514 Call(_, false, matchPacket(std::move(rejected_response))))
515 .Times(4);
516
517 // Send the registration packet
518 auto request = RegisterNotificationRequestBuilder::MakeBuilder(
519 Event::ADDRESSED_PLAYER_CHANGED, 0);
520 auto pkt = TestAvrcpPacket::Make();
521 request->Serialize(pkt);
522 SendMessage(1, pkt);
523
524 // Send addressed player update, should fail since the interim response
525 // hasn't been sent
526 test_device->HandleAddressedPlayerUpdate();
527
528 // Send the data needed for the interim response
529 MediaPlayerInfo info = {0, "Test Player", true};
530 std::vector<MediaPlayerInfo> list = {info};
531 interim_cb.Run(0, list);
532
533 // Send addressed player update, should succeed
534 test_device->HandleAddressedPlayerUpdate();
535 changed_cb.Run(0, list);
536 }
537
TEST_F(AvrcpDeviceTest,nowPlayingTest)538 TEST_F(AvrcpDeviceTest, nowPlayingTest) {
539 MockMediaInterface interface;
540 NiceMock<MockA2dpInterface> a2dp_interface;
541
542 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
543
544 SongInfo info = {"test_id",
545 {// The attribute map
546 AttributeEntry(Attribute::TITLE, "Test Song"),
547 AttributeEntry(Attribute::ARTIST_NAME, "Test Artist"),
548 AttributeEntry(Attribute::ALBUM_NAME, "Test Album"),
549 AttributeEntry(Attribute::TRACK_NUMBER, "1"),
550 AttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2"),
551 AttributeEntry(Attribute::GENRE, "Test Genre"),
552 AttributeEntry(Attribute::PLAYING_TIME, "1000"),
553 AttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001")}};
554 std::vector<SongInfo> list = {info};
555 EXPECT_CALL(interface, GetNowPlayingList(_))
556 .Times(2)
557 .WillRepeatedly(InvokeCb<0>("test_id", list));
558
559 // Test the interim response for now playing list changed
560 auto interim_response =
561 RegisterNotificationResponseBuilder::MakeNowPlayingBuilder(true);
562 EXPECT_CALL(response_cb,
563 Call(1, false, matchPacket(std::move(interim_response))))
564 .Times(1);
565
566 auto request = RegisterNotificationRequestBuilder::MakeBuilder(
567 Event::NOW_PLAYING_CONTENT_CHANGED, 0);
568 auto pkt = TestAvrcpPacket::Make();
569 request->Serialize(pkt);
570 SendMessage(1, pkt);
571
572 // Test the changed response for now playing list changed
573 auto changed_response =
574 RegisterNotificationResponseBuilder::MakeNowPlayingBuilder(false);
575 EXPECT_CALL(response_cb,
576 Call(1, false, matchPacket(std::move(changed_response))))
577 .Times(1);
578 test_device->HandleNowPlayingUpdate();
579 }
580
TEST_F(AvrcpDeviceTest,getPlayStatusTest)581 TEST_F(AvrcpDeviceTest, getPlayStatusTest) {
582 MockMediaInterface interface;
583 NiceMock<MockA2dpInterface> a2dp_interface;
584
585 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
586
587 PlayStatus status = {0x1234, 0x5678, PlayState::PLAYING};
588
589 EXPECT_CALL(interface, GetPlayStatus(_))
590 .Times(1)
591 .WillOnce(InvokeCb<0>(status));
592
593 // Pretend the device is active
594 EXPECT_CALL(a2dp_interface, active_peer())
595 .WillRepeatedly(Return(test_device->GetAddress()));
596
597 auto expected_response = GetPlayStatusResponseBuilder::MakeBuilder(
598 0x5678, 0x1234, PlayState::PLAYING);
599 EXPECT_CALL(response_cb,
600 Call(1, false, matchPacket(std::move(expected_response))))
601 .Times(1);
602
603 auto request = TestAvrcpPacket::Make(get_play_status_request);
604 SendMessage(1, request);
605 }
606
TEST_F(AvrcpDeviceTest,getElementAttributesTest)607 TEST_F(AvrcpDeviceTest, getElementAttributesTest) {
608 MockMediaInterface interface;
609 NiceMock<MockA2dpInterface> a2dp_interface;
610
611 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
612
613 SongInfo info = {"test_id",
614 {// The attribute map
615 AttributeEntry(Attribute::TITLE, "Test Song"),
616 AttributeEntry(Attribute::ARTIST_NAME, "Test Artist"),
617 AttributeEntry(Attribute::ALBUM_NAME, "Test Album"),
618 AttributeEntry(Attribute::TRACK_NUMBER, "1"),
619 AttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2"),
620 AttributeEntry(Attribute::GENRE, "Test Genre"),
621 AttributeEntry(Attribute::PLAYING_TIME, "1000"),
622 AttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001")}};
623
624 EXPECT_CALL(interface, GetSongInfo(_)).WillRepeatedly(InvokeCb<0>(info));
625
626 auto compare_to_partial =
627 GetElementAttributesResponseBuilder::MakeBuilder(0xFFFF);
628 compare_to_partial->AddAttributeEntry(Attribute::TITLE, "Test Song");
629 EXPECT_CALL(response_cb,
630 Call(2, false, matchPacket(std::move(compare_to_partial))))
631 .Times(1);
632 SendMessage(2, TestAvrcpPacket::Make(get_element_attributes_request_partial));
633
634 auto compare_to_full =
635 GetElementAttributesResponseBuilder::MakeBuilder(0xFFFF);
636 compare_to_full->AddAttributeEntry(Attribute::TITLE, "Test Song");
637 compare_to_full->AddAttributeEntry(Attribute::ARTIST_NAME, "Test Artist");
638 compare_to_full->AddAttributeEntry(Attribute::ALBUM_NAME, "Test Album");
639 compare_to_full->AddAttributeEntry(Attribute::TRACK_NUMBER, "1");
640 compare_to_full->AddAttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2");
641 compare_to_full->AddAttributeEntry(Attribute::GENRE, "Test Genre");
642 compare_to_full->AddAttributeEntry(Attribute::PLAYING_TIME, "1000");
643 EXPECT_CALL(response_cb,
644 Call(3, false, matchPacket(std::move(compare_to_full))))
645 .Times(1);
646 SendMessage(3, TestAvrcpPacket::Make(get_element_attributes_request_full));
647 }
648
TEST_F(AvrcpDeviceTest,getElementAttributesWithCoverArtTest)649 TEST_F(AvrcpDeviceTest, getElementAttributesWithCoverArtTest) {
650 MockMediaInterface interface;
651 NiceMock<MockA2dpInterface> a2dp_interface;
652
653 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
654
655 SongInfo info = {"test_id",
656 {// The attribute map
657 AttributeEntry(Attribute::TITLE, "Test Song"),
658 AttributeEntry(Attribute::ARTIST_NAME, "Test Artist"),
659 AttributeEntry(Attribute::ALBUM_NAME, "Test Album"),
660 AttributeEntry(Attribute::TRACK_NUMBER, "1"),
661 AttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2"),
662 AttributeEntry(Attribute::GENRE, "Test Genre"),
663 AttributeEntry(Attribute::PLAYING_TIME, "1000"),
664 AttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001")}};
665
666 EXPECT_CALL(interface, GetSongInfo(_)).WillRepeatedly(InvokeCb<0>(info));
667 SetBipClientStatus(false);
668
669 auto compare_to_no_art =
670 GetElementAttributesResponseBuilder::MakeBuilder(0xFFFF);
671 compare_to_no_art->AddAttributeEntry(Attribute::TITLE, "Test Song");
672 compare_to_no_art->AddAttributeEntry(Attribute::ARTIST_NAME, "Test Artist");
673 compare_to_no_art->AddAttributeEntry(Attribute::ALBUM_NAME, "Test Album");
674 compare_to_no_art->AddAttributeEntry(Attribute::TRACK_NUMBER, "1");
675 compare_to_no_art->AddAttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2");
676 compare_to_no_art->AddAttributeEntry(Attribute::GENRE, "Test Genre");
677 compare_to_no_art->AddAttributeEntry(Attribute::PLAYING_TIME, "1000");
678 EXPECT_CALL(response_cb,
679 Call(3, false, matchPacket(std::move(compare_to_no_art))))
680 .Times(1);
681 SendMessage(3,
682 TestAvrcpPacket::Make(get_element_attributes_request_full_cover_art));
683
684 SetBipClientStatus(true);
685
686 auto compare_to_full =
687 GetElementAttributesResponseBuilder::MakeBuilder(0xFFFF);
688 compare_to_full->AddAttributeEntry(Attribute::TITLE, "Test Song");
689 compare_to_full->AddAttributeEntry(Attribute::ARTIST_NAME, "Test Artist");
690 compare_to_full->AddAttributeEntry(Attribute::ALBUM_NAME, "Test Album");
691 compare_to_full->AddAttributeEntry(Attribute::TRACK_NUMBER, "1");
692 compare_to_full->AddAttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2");
693 compare_to_full->AddAttributeEntry(Attribute::GENRE, "Test Genre");
694 compare_to_full->AddAttributeEntry(Attribute::PLAYING_TIME, "1000");
695 compare_to_full->AddAttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001");
696 EXPECT_CALL(response_cb,
697 Call(3, false, matchPacket(std::move(compare_to_full))))
698 .Times(1);
699 SendMessage(3,
700 TestAvrcpPacket::Make(get_element_attributes_request_full_cover_art));
701 }
702
TEST_F(AvrcpDeviceTest,getElementAttributesMtuTest)703 TEST_F(AvrcpDeviceTest, getElementAttributesMtuTest) {
704 auto truncated_packet =
705 GetElementAttributesResponseBuilder::MakeBuilder(0xFFFF);
706 truncated_packet->AddAttributeEntry(Attribute::TITLE, "1234");
707
708 MockMediaInterface interface;
709 NiceMock<MockA2dpInterface> a2dp_interface;
710
711 base::Callback<void(uint8_t, bool, AvrcpResponse)> cb =
712 base::Bind([](MockFunction<void(uint8_t, bool, const AvrcpResponse&)>* a,
713 uint8_t b, bool c, AvrcpResponse d) { a->Call(b, c, d); },
714 &response_cb);
715 Device device(RawAddress::kAny, true, cb, truncated_packet->size(), 0xFFFF);
716
717 device.RegisterInterfaces(&interface, &a2dp_interface, nullptr);
718
719 SongInfo info = {"test_id",
720 {AttributeEntry(Attribute::TITLE, "1234truncated")}};
721 EXPECT_CALL(interface, GetSongInfo(_)).WillRepeatedly(InvokeCb<0>(info));
722
723 EXPECT_CALL(response_cb,
724 Call(1, false, matchPacket(std::move(truncated_packet))))
725 .Times(1);
726
727 device.MessageReceived(
728 1, TestAvrcpPacket::Make(get_element_attributes_request_full));
729 }
730
TEST_F(AvrcpDeviceTest,getTotalNumberOfItemsMediaPlayersTest)731 TEST_F(AvrcpDeviceTest, getTotalNumberOfItemsMediaPlayersTest) {
732 MockMediaInterface interface;
733 NiceMock<MockA2dpInterface> a2dp_interface;
734
735 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
736
737 std::vector<MediaPlayerInfo> player_list = {
738 {0, "player1", true}, {1, "player2", true}, {2, "player3", true},
739 };
740
741 EXPECT_CALL(interface, GetMediaPlayerList(_))
742 .Times(1)
743 .WillOnce(InvokeCb<0>(0, player_list));
744
745 auto expected_response = GetTotalNumberOfItemsResponseBuilder::MakeBuilder(
746 Status::NO_ERROR, 0, player_list.size());
747 EXPECT_CALL(response_cb,
748 Call(1, true, matchPacket(std::move(expected_response))))
749 .Times(1);
750
751 SendBrowseMessage(1, TestBrowsePacket::Make(
752 get_total_number_of_items_request_media_players));
753 }
754
TEST_F(AvrcpDeviceTest,getTotalNumberOfItemsVFSTest)755 TEST_F(AvrcpDeviceTest, getTotalNumberOfItemsVFSTest) {
756 MockMediaInterface interface;
757 NiceMock<MockA2dpInterface> a2dp_interface;
758
759 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
760
761 std::vector<ListItem> vfs_list = {
762 {ListItem::FOLDER, {"id1", true, "folder1"}, SongInfo()},
763 {ListItem::FOLDER, {"id2", true, "folder2"}, SongInfo()},
764 };
765
766 EXPECT_CALL(interface, GetFolderItems(_, "", _))
767 .Times(1)
768 .WillOnce(InvokeCb<2>(vfs_list));
769
770 auto expected_response = GetTotalNumberOfItemsResponseBuilder::MakeBuilder(
771 Status::NO_ERROR, 0, vfs_list.size());
772 EXPECT_CALL(response_cb,
773 Call(1, true, matchPacket(std::move(expected_response))))
774 .Times(1);
775
776 SendBrowseMessage(
777 1, TestBrowsePacket::Make(get_total_number_of_items_request_vfs));
778 }
779
TEST_F(AvrcpDeviceTest,getTotalNumberOfItemsNowPlayingTest)780 TEST_F(AvrcpDeviceTest, getTotalNumberOfItemsNowPlayingTest) {
781 MockMediaInterface interface;
782 NiceMock<MockA2dpInterface> a2dp_interface;
783
784 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
785
786 std::vector<SongInfo> now_playing_list = {
787 {"test_id1", {}}, {"test_id2", {}}, {"test_id3", {}},
788 {"test_id4", {}}, {"test_id5", {}},
789 };
790
791 EXPECT_CALL(interface, GetNowPlayingList(_))
792 .WillRepeatedly(InvokeCb<0>("test_id1", now_playing_list));
793
794 auto expected_response = GetTotalNumberOfItemsResponseBuilder::MakeBuilder(
795 Status::NO_ERROR, 0, now_playing_list.size());
796 EXPECT_CALL(response_cb,
797 Call(1, true, matchPacket(std::move(expected_response))))
798 .Times(1);
799
800 SendBrowseMessage(
801 1, TestBrowsePacket::Make(get_total_number_of_items_request_now_playing));
802 }
803
TEST_F(AvrcpDeviceTest,getMediaPlayerListTest)804 TEST_F(AvrcpDeviceTest, getMediaPlayerListTest) {
805 MockMediaInterface interface;
806 NiceMock<MockA2dpInterface> a2dp_interface;
807
808 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
809
810 MediaPlayerInfo info = {0, "Test Player", true};
811 std::vector<MediaPlayerInfo> list = {info};
812
813 EXPECT_CALL(interface, GetMediaPlayerList(_))
814 .Times(1)
815 .WillOnce(InvokeCb<0>(0, list));
816
817 auto expected_response = GetFolderItemsResponseBuilder::MakePlayerListBuilder(
818 Status::NO_ERROR, 0x0000, 0xFFFF);
819 expected_response->AddMediaPlayer(MediaPlayerItem(0, "Test Player", true));
820 EXPECT_CALL(response_cb,
821 Call(1, true, matchPacket(std::move(expected_response))))
822 .Times(1);
823
824 auto request = TestBrowsePacket::Make(get_folder_items_request);
825 SendBrowseMessage(1, request);
826 }
827
TEST_F(AvrcpDeviceTest,getNowPlayingListTest)828 TEST_F(AvrcpDeviceTest, getNowPlayingListTest) {
829 MockMediaInterface interface;
830 NiceMock<MockA2dpInterface> a2dp_interface;
831
832 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
833 SetBipClientStatus(false);
834
835 SongInfo info = {"test_id",
836 {// The attribute map
837 AttributeEntry(Attribute::TITLE, "Test Song"),
838 AttributeEntry(Attribute::ARTIST_NAME, "Test Artist"),
839 AttributeEntry(Attribute::ALBUM_NAME, "Test Album"),
840 AttributeEntry(Attribute::TRACK_NUMBER, "1"),
841 AttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2"),
842 AttributeEntry(Attribute::GENRE, "Test Genre"),
843 AttributeEntry(Attribute::PLAYING_TIME, "1000"),
844 AttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001")}};
845 std::vector<SongInfo> list = {info};
846
847 EXPECT_CALL(interface, GetNowPlayingList(_))
848 .WillRepeatedly(InvokeCb<0>("test_id", list));
849
850 FilterCoverArt(info);
851 auto expected_response = GetFolderItemsResponseBuilder::MakeNowPlayingBuilder(
852 Status::NO_ERROR, 0x0000, 0xFFFF);
853 expected_response->AddSong(MediaElementItem(1, "Test Song", info.attributes));
854 EXPECT_CALL(response_cb,
855 Call(1, true, matchPacket(std::move(expected_response))))
856 .Times(1);
857 auto request = TestBrowsePacket::Make(get_folder_items_request_now_playing);
858 SendBrowseMessage(1, request);
859 }
860
TEST_F(AvrcpDeviceTest,getNowPlayingListWithCoverArtTest)861 TEST_F(AvrcpDeviceTest, getNowPlayingListWithCoverArtTest) {
862 MockMediaInterface interface;
863 NiceMock<MockA2dpInterface> a2dp_interface;
864
865 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
866 SetBipClientStatus(true);
867
868 SongInfo info = {"test_id",
869 {// The attribute map
870 AttributeEntry(Attribute::TITLE, "Test Song"),
871 AttributeEntry(Attribute::ARTIST_NAME, "Test Artist"),
872 AttributeEntry(Attribute::ALBUM_NAME, "Test Album"),
873 AttributeEntry(Attribute::TRACK_NUMBER, "1"),
874 AttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2"),
875 AttributeEntry(Attribute::GENRE, "Test Genre"),
876 AttributeEntry(Attribute::PLAYING_TIME, "1000"),
877 AttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001")}};
878 std::vector<SongInfo> list = {info};
879
880 EXPECT_CALL(interface, GetNowPlayingList(_))
881 .WillRepeatedly(InvokeCb<0>("test_id", list));
882
883 auto expected_response = GetFolderItemsResponseBuilder::MakeNowPlayingBuilder(
884 Status::NO_ERROR, 0x0000, 0xFFFF);
885 expected_response->AddSong(MediaElementItem(1, "Test Song", info.attributes));
886
887 EXPECT_CALL(response_cb,
888 Call(1, true, matchPacket(std::move(expected_response))))
889 .Times(1);
890 auto request = TestBrowsePacket::Make(get_folder_items_request_now_playing);
891 SendBrowseMessage(1, request);
892 }
893
TEST_F(AvrcpDeviceTest,getVFSFolderTest)894 TEST_F(AvrcpDeviceTest, getVFSFolderTest) {
895 MockMediaInterface interface;
896 NiceMock<MockA2dpInterface> a2dp_interface;
897
898 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
899
900 FolderInfo info = {"test_id", true, "Test Folder"};
901 ListItem item = {ListItem::FOLDER, info, SongInfo()};
902 std::vector<ListItem> list = {item};
903
904 EXPECT_CALL(interface, GetFolderItems(_, "", _))
905 .Times(1)
906 .WillOnce(InvokeCb<2>(list));
907
908 auto expected_response = GetFolderItemsResponseBuilder::MakeVFSBuilder(
909 Status::NO_ERROR, 0x0000, 0xFFFF);
910 expected_response->AddFolder(FolderItem(1, 0, true, "Test Folder"));
911 EXPECT_CALL(response_cb,
912 Call(1, true, matchPacket(std::move(expected_response))))
913 .Times(1);
914
915 auto request = TestBrowsePacket::Make(get_folder_items_request_vfs);
916 SendBrowseMessage(1, request);
917 }
918
TEST_F(AvrcpDeviceTest,getFolderItemsMtuTest)919 TEST_F(AvrcpDeviceTest, getFolderItemsMtuTest) {
920 auto truncated_packet = GetFolderItemsResponseBuilder::MakeVFSBuilder(
921 Status::NO_ERROR, 0x0000, 0xFFFF);
922 truncated_packet->AddFolder(FolderItem(1, 0, true, "Test Folder0"));
923 truncated_packet->AddFolder(FolderItem(2, 0, true, "Test Folder1"));
924
925 MockMediaInterface interface;
926 NiceMock<MockA2dpInterface> a2dp_interface;
927 base::Callback<void(uint8_t, bool, AvrcpResponse)> cb =
928 base::Bind([](MockFunction<void(uint8_t, bool, const AvrcpResponse&)>* a,
929 uint8_t b, bool c, AvrcpResponse d) { a->Call(b, c, d); },
930 &response_cb);
931
932 Device device(RawAddress::kAny, true, cb, 0xFFFF,
933 truncated_packet->size() + FolderItem::kHeaderSize() + 5);
934 device.RegisterInterfaces(&interface, &a2dp_interface, nullptr);
935
936 FolderInfo info0 = {"test_id0", true, "Test Folder0"};
937 FolderInfo info1 = {"test_id1", true, "Test Folder1"};
938 FolderInfo info2 = {"test_id2", true, "Truncated folder"};
939 // Used to ensure that adding an item that would fit in the MTU fails if
940 // adding a large item failed.
941 FolderInfo small_info = {"test_id2", true, "Small"};
942
943 ListItem item0 = {ListItem::FOLDER, info0, SongInfo()};
944 ListItem item1 = {ListItem::FOLDER, info1, SongInfo()};
945 ListItem item2 = {ListItem::FOLDER, info2, SongInfo()};
946 ListItem item3 = {ListItem::FOLDER, small_info, SongInfo()};
947
948 std::vector<ListItem> list0 = {item0, item1, item2, item3};
949 EXPECT_CALL(interface, GetFolderItems(_, "", _))
950 .WillRepeatedly(InvokeCb<2>(list0));
951
952 EXPECT_CALL(response_cb,
953 Call(1, true, matchPacket(std::move(truncated_packet))))
954 .Times(1);
955 device.BrowseMessageReceived(
956 1, TestBrowsePacket::Make(get_folder_items_request_vfs));
957 }
958
TEST_F(AvrcpDeviceTest,changePathTest)959 TEST_F(AvrcpDeviceTest, changePathTest) {
960 MockMediaInterface interface;
961 NiceMock<MockA2dpInterface> a2dp_interface;
962
963 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
964
965 FolderInfo info0 = {"test_id0", true, "Test Folder0"};
966 FolderInfo info1 = {"test_id1", true, "Test Folder1"};
967 ListItem item0 = {ListItem::FOLDER, info0, SongInfo()};
968 ListItem item1 = {ListItem::FOLDER, info1, SongInfo()};
969 std::vector<ListItem> list0 = {item0, item1};
970 EXPECT_CALL(interface, GetFolderItems(_, "", _))
971 .Times(1)
972 .WillRepeatedly(InvokeCb<2>(list0));
973
974 FolderInfo info2 = {"test_id2", true, "Test Folder2"};
975 FolderInfo info3 = {"test_id3", true, "Test Folder3"};
976 FolderInfo info4 = {"test_id4", true, "Test Folder4"};
977 ListItem item2 = {ListItem::FOLDER, info2, SongInfo()};
978 ListItem item3 = {ListItem::FOLDER, info3, SongInfo()};
979 ListItem item4 = {ListItem::FOLDER, info4, SongInfo()};
980 std::vector<ListItem> list1 = {item2, item3, item4};
981 EXPECT_CALL(interface, GetFolderItems(_, "test_id1", _))
982 .Times(3)
983 .WillRepeatedly(InvokeCb<2>(list1));
984
985 std::vector<ListItem> list2 = {};
986 EXPECT_CALL(interface, GetFolderItems(_, "test_id3", _))
987 .Times(1)
988 .WillOnce(InvokeCb<2>(list2));
989
990 // Populate the VFS ID map
991 auto folder_items_response = GetFolderItemsResponseBuilder::MakeVFSBuilder(
992 Status::NO_ERROR, 0x0000, 0xFFFF);
993 folder_items_response->AddFolder(FolderItem(1, 0, true, "Test Folder0"));
994 folder_items_response->AddFolder(FolderItem(2, 0, true, "Test Folder1"));
995 EXPECT_CALL(response_cb,
996 Call(1, true, matchPacket(std::move(folder_items_response))))
997 .Times(1);
998
999 auto folder_request_builder =
1000 GetFolderItemsRequestBuilder::MakeBuilder(Scope::VFS, 0, 3, {});
1001 auto request = TestBrowsePacket::Make();
1002 folder_request_builder->Serialize(request);
1003 SendBrowseMessage(1, request);
1004
1005 // Change path down into Test Folder1
1006 auto change_path_response =
1007 ChangePathResponseBuilder::MakeBuilder(Status::NO_ERROR, list1.size());
1008 EXPECT_CALL(response_cb,
1009 Call(2, true, matchPacket(std::move(change_path_response))));
1010 auto path_request_builder =
1011 ChangePathRequestBuilder::MakeBuilder(0, Direction::DOWN, 2);
1012 request = TestBrowsePacket::Make();
1013 path_request_builder->Serialize(request);
1014 SendBrowseMessage(2, request);
1015
1016 // Populate the new VFS ID
1017 folder_items_response = GetFolderItemsResponseBuilder::MakeVFSBuilder(
1018 Status::NO_ERROR, 0x0000, 0xFFFF);
1019 folder_items_response->AddFolder(FolderItem(3, 0, true, "Test Folder2"));
1020 folder_items_response->AddFolder(FolderItem(4, 0, true, "Test Folder3"));
1021 folder_items_response->AddFolder(FolderItem(5, 0, true, "Test Folder4"));
1022 EXPECT_CALL(response_cb,
1023 Call(3, true, matchPacket(std::move(folder_items_response))))
1024 .Times(1);
1025 folder_request_builder =
1026 GetFolderItemsRequestBuilder::MakeBuilder(Scope::VFS, 0, 3, {});
1027 request = TestBrowsePacket::Make();
1028 folder_request_builder->Serialize(request);
1029 SendBrowseMessage(3, request);
1030
1031 // Change path down into Test Folder3
1032 change_path_response =
1033 ChangePathResponseBuilder::MakeBuilder(Status::NO_ERROR, list2.size());
1034 EXPECT_CALL(response_cb,
1035 Call(4, true, matchPacket(std::move(change_path_response))));
1036 path_request_builder =
1037 ChangePathRequestBuilder::MakeBuilder(0, Direction::DOWN, 4);
1038 request = TestBrowsePacket::Make();
1039 path_request_builder->Serialize(request);
1040 SendBrowseMessage(4, request);
1041
1042 // Change path up back into Test Folder1
1043 change_path_response =
1044 ChangePathResponseBuilder::MakeBuilder(Status::NO_ERROR, list1.size());
1045 EXPECT_CALL(response_cb,
1046 Call(5, true, matchPacket(std::move(change_path_response))));
1047 path_request_builder =
1048 ChangePathRequestBuilder::MakeBuilder(0, Direction::UP, 0);
1049 request = TestBrowsePacket::Make();
1050 path_request_builder->Serialize(request);
1051 SendBrowseMessage(5, request);
1052 }
1053
TEST_F(AvrcpDeviceTest,getItemAttributesNowPlayingTest)1054 TEST_F(AvrcpDeviceTest, getItemAttributesNowPlayingTest) {
1055 MockMediaInterface interface;
1056 NiceMock<MockA2dpInterface> a2dp_interface;
1057
1058 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1059
1060 SongInfo info = {"test_id",
1061 {// The attribute map
1062 AttributeEntry(Attribute::TITLE, "Test Song"),
1063 AttributeEntry(Attribute::ARTIST_NAME, "Test Artist"),
1064 AttributeEntry(Attribute::ALBUM_NAME, "Test Album"),
1065 AttributeEntry(Attribute::TRACK_NUMBER, "1"),
1066 AttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2"),
1067 AttributeEntry(Attribute::GENRE, "Test Genre"),
1068 AttributeEntry(Attribute::PLAYING_TIME, "1000"),
1069 AttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001")}};
1070 std::vector<SongInfo> list = {info};
1071
1072 EXPECT_CALL(interface, GetNowPlayingList(_))
1073 .WillRepeatedly(InvokeCb<0>("test_id", list));
1074
1075 SetBipClientStatus(false);
1076
1077 auto compare_to_full =
1078 GetItemAttributesResponseBuilder::MakeBuilder(Status::NO_ERROR, 0xFFFF);
1079 compare_to_full->AddAttributeEntry(Attribute::TITLE, "Test Song");
1080 compare_to_full->AddAttributeEntry(Attribute::ARTIST_NAME, "Test Artist");
1081 compare_to_full->AddAttributeEntry(Attribute::ALBUM_NAME, "Test Album");
1082 compare_to_full->AddAttributeEntry(Attribute::TRACK_NUMBER, "1");
1083 compare_to_full->AddAttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2");
1084 compare_to_full->AddAttributeEntry(Attribute::GENRE, "Test Genre");
1085 compare_to_full->AddAttributeEntry(Attribute::PLAYING_TIME, "1000");
1086 EXPECT_CALL(response_cb,
1087 Call(1, true, matchPacket(std::move(compare_to_full))))
1088 .Times(1);
1089
1090 auto request =
1091 TestBrowsePacket::Make(get_item_attributes_request_all_attributes);
1092 SendBrowseMessage(1, request);
1093 }
1094
TEST_F(AvrcpDeviceTest,getItemAttributesNowPlayingWithCoverArtTest)1095 TEST_F(AvrcpDeviceTest, getItemAttributesNowPlayingWithCoverArtTest) {
1096 MockMediaInterface interface;
1097 NiceMock<MockA2dpInterface> a2dp_interface;
1098
1099 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1100
1101 SongInfo info = {"test_id",
1102 {// The attribute map
1103 AttributeEntry(Attribute::TITLE, "Test Song"),
1104 AttributeEntry(Attribute::ARTIST_NAME, "Test Artist"),
1105 AttributeEntry(Attribute::ALBUM_NAME, "Test Album"),
1106 AttributeEntry(Attribute::TRACK_NUMBER, "1"),
1107 AttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2"),
1108 AttributeEntry(Attribute::GENRE, "Test Genre"),
1109 AttributeEntry(Attribute::PLAYING_TIME, "1000"),
1110 AttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001")}};
1111 std::vector<SongInfo> list = {info};
1112
1113 EXPECT_CALL(interface, GetNowPlayingList(_))
1114 .WillRepeatedly(InvokeCb<0>("test_id", list));
1115
1116 SetBipClientStatus(true);
1117
1118 auto compare_to_full =
1119 GetItemAttributesResponseBuilder::MakeBuilder(Status::NO_ERROR, 0xFFFF);
1120 compare_to_full->AddAttributeEntry(Attribute::TITLE,"Test Song");
1121 compare_to_full->AddAttributeEntry(Attribute::ARTIST_NAME, "Test Artist");
1122 compare_to_full->AddAttributeEntry(Attribute::ALBUM_NAME, "Test Album");
1123 compare_to_full->AddAttributeEntry(Attribute::TRACK_NUMBER, "1");
1124 compare_to_full->AddAttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2");
1125 compare_to_full->AddAttributeEntry(Attribute::GENRE, "Test Genre");
1126 compare_to_full->AddAttributeEntry(Attribute::PLAYING_TIME, "1000");
1127 compare_to_full->AddAttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001");
1128 EXPECT_CALL(response_cb,
1129 Call(1, true, matchPacket(std::move(compare_to_full))))
1130 .Times(1);
1131
1132 auto requestWithBip =
1133 TestBrowsePacket::Make(
1134 get_item_attributes_request_all_attributes_with_cover_art);
1135 SendBrowseMessage(1, requestWithBip);
1136
1137 SetBipClientStatus(false);
1138
1139 auto compare_to_no_art =
1140 GetItemAttributesResponseBuilder::MakeBuilder(Status::NO_ERROR, 0xFFFF);
1141 compare_to_no_art->AddAttributeEntry(Attribute::TITLE, "Test Song");
1142 compare_to_no_art->AddAttributeEntry(Attribute::ARTIST_NAME, "Test Artist");
1143 compare_to_no_art->AddAttributeEntry(Attribute::ALBUM_NAME, "Test Album");
1144 compare_to_no_art->AddAttributeEntry(Attribute::TRACK_NUMBER, "1");
1145 compare_to_no_art->AddAttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2");
1146 compare_to_no_art->AddAttributeEntry(Attribute::GENRE, "Test Genre");
1147 compare_to_no_art->AddAttributeEntry(Attribute::PLAYING_TIME, "1000");
1148 EXPECT_CALL(response_cb,
1149 Call(1, true, matchPacket(std::move(compare_to_no_art))))
1150 .Times(1);
1151
1152 auto requestWithoutBip =
1153 TestBrowsePacket::Make(
1154 get_item_attributes_request_all_attributes_with_cover_art);
1155 SendBrowseMessage(1, requestWithoutBip);
1156 }
1157
TEST_F(AvrcpDeviceTest,getItemAttributesMtuTest)1158 TEST_F(AvrcpDeviceTest, getItemAttributesMtuTest) {
1159 auto truncated_packet =
1160 GetItemAttributesResponseBuilder::MakeBuilder(Status::NO_ERROR, 0xFFFF);
1161 truncated_packet->AddAttributeEntry(Attribute::TITLE, "1234");
1162
1163 MockMediaInterface interface;
1164 NiceMock<MockA2dpInterface> a2dp_interface;
1165 base::Callback<void(uint8_t, bool, AvrcpResponse)> cb =
1166 base::Bind([](MockFunction<void(uint8_t, bool, const AvrcpResponse&)>* a,
1167 uint8_t b, bool c, AvrcpResponse d) { a->Call(b, c, d); },
1168 &response_cb);
1169 Device device(RawAddress::kAny, true, cb, 0xFFFF, truncated_packet->size());
1170 device.RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1171
1172 SongInfo info = {"test_id",
1173 {AttributeEntry(Attribute::TITLE, "1234truncated")}};
1174 std::vector<SongInfo> list = {info};
1175 EXPECT_CALL(interface, GetNowPlayingList(_))
1176 .WillRepeatedly(InvokeCb<0>("test_id", list));
1177
1178 EXPECT_CALL(response_cb,
1179 Call(1, true, matchPacket(std::move(truncated_packet))))
1180 .Times(1);
1181 device.BrowseMessageReceived(
1182 1, TestBrowsePacket::Make(get_item_attributes_request_all_attributes));
1183 }
1184
TEST_F(AvrcpDeviceTest,setAddressedPlayerTest)1185 TEST_F(AvrcpDeviceTest, setAddressedPlayerTest) {
1186 MockMediaInterface interface;
1187 NiceMock<MockA2dpInterface> a2dp_interface;
1188
1189 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1190
1191 MediaPlayerInfo info = {0, "Test Player", true};
1192 std::vector<MediaPlayerInfo> list = {info};
1193
1194 EXPECT_CALL(interface, GetMediaPlayerList(_))
1195 .WillRepeatedly(InvokeCb<0>(0, list));
1196
1197 auto set_addr_player_rej_rsp = RejectBuilder::MakeBuilder(
1198 CommandPdu::SET_ADDRESSED_PLAYER, Status::INVALID_PLAYER_ID);
1199
1200 EXPECT_CALL(response_cb,
1201 Call(1, false, matchPacket(std::move(set_addr_player_rej_rsp))))
1202 .Times(1);
1203
1204 auto player_id_1_request =
1205 TestAvrcpPacket::Make(set_addressed_player_id_1_request);
1206 SendMessage(1, player_id_1_request);
1207
1208 auto set_addr_player_rsp =
1209 SetAddressedPlayerResponseBuilder::MakeBuilder(Status::NO_ERROR);
1210
1211 EXPECT_CALL(response_cb,
1212 Call(1, false, matchPacket(std::move(set_addr_player_rsp))))
1213 .Times(1);
1214
1215 auto request = TestAvrcpPacket::Make(set_addressed_player_request);
1216 SendMessage(1, request);
1217 }
1218
TEST_F(AvrcpDeviceTest,setBrowsedPlayerTest)1219 TEST_F(AvrcpDeviceTest, setBrowsedPlayerTest) {
1220 MockMediaInterface interface;
1221 NiceMock<MockA2dpInterface> a2dp_interface;
1222
1223 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1224
1225 EXPECT_CALL(interface, SetBrowsedPlayer(_, _))
1226 .Times(3)
1227 .WillOnce(InvokeCb<1>(true, "", 0))
1228 .WillOnce(InvokeCb<1>(false, "", 0))
1229 .WillOnce(InvokeCb<1>(true, "", 2));
1230
1231 auto not_browsable_rsp = SetBrowsedPlayerResponseBuilder::MakeBuilder(
1232 Status::PLAYER_NOT_BROWSABLE, 0x0000, 0, 0, "");
1233 EXPECT_CALL(response_cb,
1234 Call(1, true, matchPacket(std::move(not_browsable_rsp))))
1235 .Times(1);
1236
1237 auto player_id_0_request =
1238 TestBrowsePacket::Make(set_browsed_player_id_0_request);
1239 SendBrowseMessage(1, player_id_0_request);
1240
1241 auto invalid_id_rsp = SetBrowsedPlayerResponseBuilder::MakeBuilder(
1242 Status::INVALID_PLAYER_ID, 0x0000, 0, 0, "");
1243 EXPECT_CALL(response_cb,
1244 Call(2, true, matchPacket(std::move(invalid_id_rsp))))
1245 .Times(1);
1246
1247 SendBrowseMessage(2, player_id_0_request);
1248
1249 auto response = SetBrowsedPlayerResponseBuilder::MakeBuilder(
1250 Status::NO_ERROR, 0x0000, 2, 0, "");
1251 EXPECT_CALL(response_cb, Call(3, true, matchPacket(std::move(response))))
1252 .Times(1);
1253
1254 SendBrowseMessage(3, player_id_0_request);
1255 }
1256
TEST_F(AvrcpDeviceTest,volumeChangedTest)1257 TEST_F(AvrcpDeviceTest, volumeChangedTest) {
1258 MockMediaInterface interface;
1259 NiceMock<MockA2dpInterface> a2dp_interface;
1260 MockVolumeInterface vol_interface;
1261
1262 test_device->RegisterInterfaces(&interface, &a2dp_interface, &vol_interface);
1263
1264 // Pretend the device is active
1265 EXPECT_CALL(a2dp_interface, active_peer())
1266 .WillRepeatedly(Return(test_device->GetAddress()));
1267
1268 auto reg_notif =
1269 RegisterNotificationRequestBuilder::MakeBuilder(Event::VOLUME_CHANGED, 0);
1270 EXPECT_CALL(response_cb, Call(_, false, matchPacket(std::move(reg_notif))))
1271 .Times(1);
1272 test_device->RegisterVolumeChanged();
1273
1274 EXPECT_CALL(vol_interface, DeviceConnected(test_device->GetAddress(), _))
1275 .Times(1)
1276 .WillOnce(InvokeCb<1>(0x30));
1277 auto set_vol = SetAbsoluteVolumeRequestBuilder::MakeBuilder(0x30);
1278 EXPECT_CALL(response_cb, Call(_, false, matchPacket(std::move(set_vol))))
1279 .Times(1);
1280
1281 auto response = TestAvrcpPacket::Make(interim_volume_changed_notification);
1282 SendMessage(1, response);
1283
1284 EXPECT_CALL(vol_interface, SetVolume(0x47)).Times(1);
1285 auto reg_notif2 =
1286 RegisterNotificationRequestBuilder::MakeBuilder(Event::VOLUME_CHANGED, 0);
1287 EXPECT_CALL(response_cb, Call(_, false, matchPacket(std::move(reg_notif2))))
1288 .Times(1);
1289 response = TestAvrcpPacket::Make(changed_volume_changed_notification);
1290 SendMessage(1, response);
1291 response = TestAvrcpPacket::Make(interim_volume_changed_notification);
1292 SendMessage(1, response);
1293 }
1294
TEST_F(AvrcpDeviceTest,volumeChangedNonActiveTest)1295 TEST_F(AvrcpDeviceTest, volumeChangedNonActiveTest) {
1296 MockMediaInterface interface;
1297 NiceMock<MockA2dpInterface> a2dp_interface;
1298 MockVolumeInterface vol_interface;
1299
1300 test_device->RegisterInterfaces(&interface, &a2dp_interface, &vol_interface);
1301
1302 // Pretend the device isn't active
1303 EXPECT_CALL(a2dp_interface, active_peer())
1304 .WillRepeatedly(Return(RawAddress::kEmpty));
1305
1306 auto reg_notif =
1307 RegisterNotificationRequestBuilder::MakeBuilder(Event::VOLUME_CHANGED, 0);
1308 EXPECT_CALL(response_cb, Call(_, false, matchPacket(std::move(reg_notif))))
1309 .Times(1);
1310 test_device->RegisterVolumeChanged();
1311
1312 EXPECT_CALL(vol_interface, DeviceConnected(test_device->GetAddress(), _))
1313 .Times(1)
1314 .WillOnce(InvokeCb<1>(0x30));
1315 auto set_vol = SetAbsoluteVolumeRequestBuilder::MakeBuilder(0x30);
1316 EXPECT_CALL(response_cb, Call(_, false, matchPacket(std::move(set_vol))))
1317 .Times(1);
1318
1319 auto response = TestAvrcpPacket::Make(interim_volume_changed_notification);
1320 SendMessage(1, response);
1321
1322 // Ensure that SetVolume is never called
1323 EXPECT_CALL(vol_interface, SetVolume(0x47)).Times(0);
1324
1325 auto reg_notif2 =
1326 RegisterNotificationRequestBuilder::MakeBuilder(Event::VOLUME_CHANGED, 0);
1327 EXPECT_CALL(response_cb, Call(_, false, matchPacket(std::move(reg_notif2))))
1328 .Times(1);
1329 response = TestAvrcpPacket::Make(changed_volume_changed_notification);
1330 SendMessage(1, response);
1331 response = TestAvrcpPacket::Make(interim_volume_changed_notification);
1332 SendMessage(1, response);
1333 }
1334
TEST_F(AvrcpDeviceTest,volumeRejectedTest)1335 TEST_F(AvrcpDeviceTest, volumeRejectedTest) {
1336 MockMediaInterface interface;
1337 NiceMock<MockA2dpInterface> a2dp_interface;
1338 MockVolumeInterface vol_interface;
1339
1340 test_device->RegisterInterfaces(&interface, &a2dp_interface, &vol_interface);
1341
1342 auto reg_notif =
1343 RegisterNotificationRequestBuilder::MakeBuilder(Event::VOLUME_CHANGED, 0);
1344 EXPECT_CALL(response_cb, Call(_, false, matchPacket(std::move(reg_notif))))
1345 .Times(1);
1346 test_device->RegisterVolumeChanged();
1347
1348 auto response = TestAvrcpPacket::Make(rejected_volume_changed_notification);
1349 SendMessage(1, response);
1350
1351 EXPECT_CALL(response_cb, Call(_, _, _)).Times(0);
1352 }
1353
TEST_F(AvrcpDeviceTest,playPushedActiveDeviceTest)1354 TEST_F(AvrcpDeviceTest, playPushedActiveDeviceTest) {
1355 MockMediaInterface interface;
1356 NiceMock<MockA2dpInterface> a2dp_interface;
1357 MockVolumeInterface vol_interface;
1358
1359 test_device->RegisterInterfaces(&interface, &a2dp_interface, &vol_interface);
1360
1361 // Pretend the device is active
1362 EXPECT_CALL(a2dp_interface, active_peer())
1363 .WillRepeatedly(Return(test_device->GetAddress()));
1364
1365 auto play_pushed = PassThroughPacketBuilder::MakeBuilder(false, true, 0x44);
1366 auto play_pushed_response =
1367 PassThroughPacketBuilder::MakeBuilder(true, true, 0x44);
1368 EXPECT_CALL(response_cb,
1369 Call(_, false, matchPacket(std::move(play_pushed_response))))
1370 .Times(1);
1371
1372 PlayStatus status = {0x1234, 0x5678, PlayState::PLAYING};
1373 EXPECT_CALL(interface, GetPlayStatus(_))
1374 .Times(1)
1375 .WillOnce(InvokeCb<0>(status));
1376
1377 EXPECT_CALL(interface, SendKeyEvent(0x44, KeyState::PUSHED)).Times(1);
1378
1379 auto play_pushed_pkt = TestAvrcpPacket::Make();
1380 play_pushed->Serialize(play_pushed_pkt);
1381
1382 SendMessage(1, play_pushed_pkt);
1383 }
1384
TEST_F(AvrcpDeviceTest,playPushedInactiveDeviceTest)1385 TEST_F(AvrcpDeviceTest, playPushedInactiveDeviceTest) {
1386 MockMediaInterface interface;
1387 NiceMock<MockA2dpInterface> a2dp_interface;
1388 MockVolumeInterface vol_interface;
1389
1390 test_device->RegisterInterfaces(&interface, &a2dp_interface, &vol_interface);
1391
1392 // Pretend the device is not active
1393 EXPECT_CALL(a2dp_interface, active_peer())
1394 .WillRepeatedly(Return(RawAddress::kEmpty));
1395
1396 auto play_pushed = PassThroughPacketBuilder::MakeBuilder(false, true, 0x44);
1397 auto play_pushed_response =
1398 PassThroughPacketBuilder::MakeBuilder(true, true, 0x44);
1399 EXPECT_CALL(response_cb,
1400 Call(_, false, matchPacket(std::move(play_pushed_response))))
1401 .Times(1);
1402
1403 // Expect that the device will try to set itself as active
1404 EXPECT_CALL(interface, SetActiveDevice(test_device->GetAddress())).Times(1);
1405
1406 // No play command should be sent since the music is already playing
1407 PlayStatus status = {0x1234, 0x5678, PlayState::PLAYING};
1408 EXPECT_CALL(interface, GetPlayStatus(_))
1409 .Times(1)
1410 .WillOnce(InvokeCb<0>(status));
1411 EXPECT_CALL(interface, SendKeyEvent(0x44, KeyState::PUSHED)).Times(0);
1412
1413 auto play_pushed_pkt = TestAvrcpPacket::Make();
1414 play_pushed->Serialize(play_pushed_pkt);
1415
1416 SendMessage(1, play_pushed_pkt);
1417 }
1418
TEST_F(AvrcpDeviceTest,mediaKeyActiveDeviceTest)1419 TEST_F(AvrcpDeviceTest, mediaKeyActiveDeviceTest) {
1420 MockMediaInterface interface;
1421 NiceMock<MockA2dpInterface> a2dp_interface;
1422 MockVolumeInterface vol_interface;
1423
1424 test_device->RegisterInterfaces(&interface, &a2dp_interface, &vol_interface);
1425
1426 // Pretend the device is active
1427 EXPECT_CALL(a2dp_interface, active_peer())
1428 .WillRepeatedly(Return(test_device->GetAddress()));
1429
1430 auto play_released =
1431 PassThroughPacketBuilder::MakeBuilder(false, false, 0x44);
1432 auto play_released_response =
1433 PassThroughPacketBuilder::MakeBuilder(true, false, 0x44);
1434 EXPECT_CALL(response_cb,
1435 Call(_, false, matchPacket(std::move(play_released_response))))
1436 .Times(1);
1437
1438 EXPECT_CALL(interface, GetPlayStatus(_)).Times(0);
1439
1440 EXPECT_CALL(interface, SendKeyEvent(0x44, KeyState::RELEASED)).Times(1);
1441
1442 auto play_released_pkt = TestAvrcpPacket::Make();
1443 play_released->Serialize(play_released_pkt);
1444
1445 SendMessage(1, play_released_pkt);
1446 }
1447
TEST_F(AvrcpDeviceTest,mediaKeyInactiveDeviceTest)1448 TEST_F(AvrcpDeviceTest, mediaKeyInactiveDeviceTest) {
1449 MockMediaInterface interface;
1450 NiceMock<MockA2dpInterface> a2dp_interface;
1451 MockVolumeInterface vol_interface;
1452
1453 test_device->RegisterInterfaces(&interface, &a2dp_interface, &vol_interface);
1454
1455 // Pretend the device is not active
1456 EXPECT_CALL(a2dp_interface, active_peer())
1457 .WillRepeatedly(Return(RawAddress::kEmpty));
1458
1459 auto play_released =
1460 PassThroughPacketBuilder::MakeBuilder(false, false, 0x44);
1461 auto play_released_response =
1462 PassThroughPacketBuilder::MakeBuilder(true, false, 0x44);
1463 EXPECT_CALL(response_cb,
1464 Call(_, false, matchPacket(std::move(play_released_response))))
1465 .Times(1);
1466
1467 EXPECT_CALL(interface, GetPlayStatus(_)).Times(0);
1468
1469 // Expect that the key event wont be sent to the media interface
1470 EXPECT_CALL(interface, SendKeyEvent(0x44, KeyState::RELEASED)).Times(0);
1471
1472 auto play_released_pkt = TestAvrcpPacket::Make();
1473 play_released->Serialize(play_released_pkt);
1474
1475 SendMessage(1, play_released_pkt);
1476 }
1477
TEST_F(AvrcpDeviceTest,getCapabilitiesTest)1478 TEST_F(AvrcpDeviceTest, getCapabilitiesTest) {
1479 MockMediaInterface interface;
1480 NiceMock<MockA2dpInterface> a2dp_interface;
1481
1482 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1483
1484 // GetCapabilities with CapabilityID COMPANY_ID
1485 auto request_company_id_response =
1486 GetCapabilitiesResponseBuilder::MakeCompanyIdBuilder(0x001958);
1487 request_company_id_response->AddCompanyId(0x002345);
1488 EXPECT_CALL(
1489 response_cb,
1490 Call(1, false, matchPacket(std::move(request_company_id_response))))
1491 .Times(1);
1492
1493 auto request_company_id =
1494 TestAvrcpPacket::Make(get_capabilities_request_company_id);
1495 SendMessage(1, request_company_id);
1496
1497 // GetCapabilities with CapabilityID EVENTS_SUPPORTED
1498 auto request_events_supported_response =
1499 GetCapabilitiesResponseBuilder::MakeEventsSupportedBuilder(
1500 Event::PLAYBACK_STATUS_CHANGED);
1501 request_events_supported_response->AddEvent(Event::TRACK_CHANGED);
1502 request_events_supported_response->AddEvent(Event::PLAYBACK_POS_CHANGED);
1503
1504 EXPECT_CALL(
1505 response_cb,
1506 Call(2, false, matchPacket(std::move(request_events_supported_response))))
1507 .Times(1);
1508
1509 auto request_events_supported =
1510 TestAvrcpPacket::Make(get_capabilities_request);
1511 SendMessage(2, request_events_supported);
1512
1513 // GetCapabilities with CapabilityID UNKNOWN
1514 auto request_unknown_response = RejectBuilder::MakeBuilder(
1515 CommandPdu::GET_CAPABILITIES, Status::INVALID_PARAMETER);
1516
1517 EXPECT_CALL(response_cb,
1518 Call(3, false, matchPacket(std::move(request_unknown_response))))
1519 .Times(1);
1520
1521 auto request_unknown =
1522 TestAvrcpPacket::Make(get_capabilities_request_unknown);
1523 SendMessage(3, request_unknown);
1524 }
1525
TEST_F(AvrcpDeviceTest,getInvalidItemAttributesTest)1526 TEST_F(AvrcpDeviceTest, getInvalidItemAttributesTest) {
1527 MockMediaInterface interface;
1528 NiceMock<MockA2dpInterface> a2dp_interface;
1529
1530 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1531
1532 SongInfo info = {"test_id",
1533 {// The attribute map
1534 AttributeEntry(Attribute::TITLE, "Test Song"),
1535 AttributeEntry(Attribute::ARTIST_NAME, "Test Artist"),
1536 AttributeEntry(Attribute::ALBUM_NAME, "Test Album"),
1537 AttributeEntry(Attribute::TRACK_NUMBER, "1"),
1538 AttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2"),
1539 AttributeEntry(Attribute::GENRE, "Test Genre"),
1540 AttributeEntry(Attribute::PLAYING_TIME, "1000")}};
1541 std::vector<SongInfo> list = {info};
1542
1543 EXPECT_CALL(interface, GetNowPlayingList(_))
1544 .WillRepeatedly(InvokeCb<0>("test_id", list));
1545
1546 auto compare_to_full = GetItemAttributesResponseBuilder::MakeBuilder(
1547 Status::UIDS_CHANGED, 0xFFFF);
1548 compare_to_full->AddAttributeEntry(Attribute::TITLE, "Test Song");
1549 compare_to_full->AddAttributeEntry(Attribute::ARTIST_NAME, "Test Artist");
1550 compare_to_full->AddAttributeEntry(Attribute::ALBUM_NAME, "Test Album");
1551 compare_to_full->AddAttributeEntry(Attribute::TRACK_NUMBER, "1");
1552 compare_to_full->AddAttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2");
1553 compare_to_full->AddAttributeEntry(Attribute::GENRE, "Test Genre");
1554 compare_to_full->AddAttributeEntry(Attribute::PLAYING_TIME, "1000");
1555 compare_to_full->AddAttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001");
1556 EXPECT_CALL(response_cb,
1557 Call(1, true, matchPacket(std::move(compare_to_full))))
1558 .Times(1);
1559
1560 auto request = TestBrowsePacket::Make(
1561 get_item_attributes_request_all_attributes_invalid);
1562 SendBrowseMessage(1, request);
1563 }
1564
TEST_F(AvrcpDeviceTest,invalidRegisterNotificationTest)1565 TEST_F(AvrcpDeviceTest, invalidRegisterNotificationTest) {
1566 MockMediaInterface interface;
1567 NiceMock<MockA2dpInterface> a2dp_interface;
1568
1569 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1570
1571 auto reg_notif_rej_rsp = RejectBuilder::MakeBuilder(
1572 CommandPdu::REGISTER_NOTIFICATION, Status::INVALID_PARAMETER);
1573 EXPECT_CALL(response_cb,
1574 Call(1, false, matchPacket(std::move(reg_notif_rej_rsp))))
1575 .Times(1);
1576
1577 auto reg_notif_request = TestAvrcpPacket::Make(register_notification_invalid);
1578 SendMessage(1, reg_notif_request);
1579 }
1580
TEST_F(AvrcpDeviceTest,invalidVendorPacketTest)1581 TEST_F(AvrcpDeviceTest, invalidVendorPacketTest) {
1582 MockMediaInterface interface;
1583 NiceMock<MockA2dpInterface> a2dp_interface;
1584
1585 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1586
1587 auto rsp = RejectBuilder::MakeBuilder(static_cast<CommandPdu>(0), Status::INVALID_COMMAND);
1588 EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
1589 auto short_packet = TestAvrcpPacket::Make(short_vendor_packet);
1590 SendMessage(1, short_packet);
1591 }
1592
TEST_F(AvrcpDeviceTest,invalidCapabilitiesPacketTest)1593 TEST_F(AvrcpDeviceTest, invalidCapabilitiesPacketTest) {
1594 MockMediaInterface interface;
1595 NiceMock<MockA2dpInterface> a2dp_interface;
1596
1597 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1598
1599 auto rsp = RejectBuilder::MakeBuilder(CommandPdu::GET_CAPABILITIES, Status::INVALID_PARAMETER);
1600 EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
1601 auto short_packet = TestAvrcpPacket::Make(short_get_capabilities_request);
1602 SendMessage(1, short_packet);
1603 }
1604
TEST_F(AvrcpDeviceTest,invalidGetElementAttributesPacketTest)1605 TEST_F(AvrcpDeviceTest, invalidGetElementAttributesPacketTest) {
1606 MockMediaInterface interface;
1607 NiceMock<MockA2dpInterface> a2dp_interface;
1608
1609 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1610
1611 auto rsp = RejectBuilder::MakeBuilder(CommandPdu::GET_ELEMENT_ATTRIBUTES, Status::INVALID_PARAMETER);
1612 EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
1613 auto short_packet = TestAvrcpPacket::Make(short_get_element_attributes_request);
1614 SendMessage(1, short_packet);
1615 }
1616
TEST_F(AvrcpDeviceTest,invalidPlayItemPacketTest)1617 TEST_F(AvrcpDeviceTest, invalidPlayItemPacketTest) {
1618 MockMediaInterface interface;
1619 NiceMock<MockA2dpInterface> a2dp_interface;
1620
1621 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1622
1623 auto rsp = RejectBuilder::MakeBuilder(CommandPdu::PLAY_ITEM, Status::INVALID_PARAMETER);
1624 EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
1625 auto short_packet = TestAvrcpPacket::Make(short_play_item_request);
1626 SendMessage(1, short_packet);
1627 }
1628
TEST_F(AvrcpDeviceTest,invalidSetAddressedPlayerPacketTest)1629 TEST_F(AvrcpDeviceTest, invalidSetAddressedPlayerPacketTest) {
1630 MockMediaInterface interface;
1631 NiceMock<MockA2dpInterface> a2dp_interface;
1632
1633 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1634
1635 auto rsp = RejectBuilder::MakeBuilder(CommandPdu::SET_ADDRESSED_PLAYER, Status::INVALID_PARAMETER);
1636 EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
1637 auto short_packet = TestAvrcpPacket::Make(short_set_addressed_player_request);
1638 SendMessage(1, short_packet);
1639 }
1640
TEST_F(AvrcpDeviceTest,invalidBrowsePacketTest)1641 TEST_F(AvrcpDeviceTest, invalidBrowsePacketTest) {
1642 MockMediaInterface interface;
1643 NiceMock<MockA2dpInterface> a2dp_interface;
1644
1645 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1646
1647 auto rsp = GeneralRejectBuilder::MakeBuilder(Status::INVALID_COMMAND);
1648 EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
1649 auto short_packet = TestBrowsePacket::Make(short_browse_packet);
1650 SendBrowseMessage(1, short_packet);
1651 }
1652
TEST_F(AvrcpDeviceTest,invalidGetFolderItemsPacketTest)1653 TEST_F(AvrcpDeviceTest, invalidGetFolderItemsPacketTest) {
1654 MockMediaInterface interface;
1655 NiceMock<MockA2dpInterface> a2dp_interface;
1656
1657 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1658
1659 auto rsp = GetFolderItemsResponseBuilder::MakePlayerListBuilder(Status::INVALID_PARAMETER, 0x0000, 0xFFFF);
1660 EXPECT_CALL(response_cb, Call(1, true, matchPacket(std::move(rsp)))).Times(1);
1661 auto short_packet = TestBrowsePacket::Make(short_get_folder_items_request);
1662 SendBrowseMessage(1, short_packet);
1663 }
1664
TEST_F(AvrcpDeviceTest,invalidGetTotalNumberOfItemsPacketTest)1665 TEST_F(AvrcpDeviceTest, invalidGetTotalNumberOfItemsPacketTest) {
1666 MockMediaInterface interface;
1667 NiceMock<MockA2dpInterface> a2dp_interface;
1668
1669 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1670
1671 auto rsp = GetTotalNumberOfItemsResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0x0000, 0xFFFF);
1672 EXPECT_CALL(response_cb, Call(1, true, matchPacket(std::move(rsp)))).Times(1);
1673 auto short_packet = TestBrowsePacket::Make(short_get_total_number_of_items_request);
1674 SendBrowseMessage(1, short_packet);
1675 }
1676
TEST_F(AvrcpDeviceTest,invalidChangePathPacketTest)1677 TEST_F(AvrcpDeviceTest, invalidChangePathPacketTest) {
1678 MockMediaInterface interface;
1679 NiceMock<MockA2dpInterface> a2dp_interface;
1680
1681 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1682
1683 auto rsp = ChangePathResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0);
1684 EXPECT_CALL(response_cb, Call(1, true, matchPacket(std::move(rsp)))).Times(1);
1685 auto short_packet = TestBrowsePacket::Make(short_change_path_request);
1686 SendBrowseMessage(1, short_packet);
1687 }
1688
TEST_F(AvrcpDeviceTest,invalidGetItemAttributesPacketTest)1689 TEST_F(AvrcpDeviceTest, invalidGetItemAttributesPacketTest) {
1690 MockMediaInterface interface;
1691 NiceMock<MockA2dpInterface> a2dp_interface;
1692
1693 test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1694
1695 auto rsp = GetItemAttributesResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0xFFFF);
1696 EXPECT_CALL(response_cb, Call(1, true, matchPacket(std::move(rsp)))).Times(1);
1697 auto short_packet = TestBrowsePacket::Make(short_get_item_attributes_request);
1698 SendBrowseMessage(1, short_packet);
1699 }
1700
1701 } // namespace avrcp
1702 } // namespace bluetooth
1703
stack_config_get_interface(void)1704 const stack_config_t* stack_config_get_interface(void) {
1705 return &bluetooth::avrcp::interface;
1706 }
1707