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,setVolumeOnceTest)1354 TEST_F(AvrcpDeviceTest, setVolumeOnceTest) {
1355   int vol = 0x48;
1356 
1357   auto set_abs_vol = SetAbsoluteVolumeRequestBuilder::MakeBuilder(vol);
1358 
1359   // Ensure that SetVolume only been call once.
1360   EXPECT_CALL(response_cb, Call(_, false, matchPacket(std::move(set_abs_vol))))
1361       .Times(1);
1362 
1363   test_device->SetVolume(vol);
1364   test_device->SetVolume(vol);
1365 }
1366 
TEST_F(AvrcpDeviceTest,playPushedActiveDeviceTest)1367 TEST_F(AvrcpDeviceTest, playPushedActiveDeviceTest) {
1368   MockMediaInterface interface;
1369   NiceMock<MockA2dpInterface> a2dp_interface;
1370   MockVolumeInterface vol_interface;
1371 
1372   test_device->RegisterInterfaces(&interface, &a2dp_interface, &vol_interface);
1373 
1374   // Pretend the device is active
1375   EXPECT_CALL(a2dp_interface, active_peer())
1376       .WillRepeatedly(Return(test_device->GetAddress()));
1377 
1378   auto play_pushed = PassThroughPacketBuilder::MakeBuilder(false, true, 0x44);
1379   auto play_pushed_response =
1380       PassThroughPacketBuilder::MakeBuilder(true, true, 0x44);
1381   EXPECT_CALL(response_cb,
1382               Call(_, false, matchPacket(std::move(play_pushed_response))))
1383       .Times(1);
1384 
1385   PlayStatus status = {0x1234, 0x5678, PlayState::PLAYING};
1386   EXPECT_CALL(interface, GetPlayStatus(_))
1387       .Times(1)
1388       .WillOnce(InvokeCb<0>(status));
1389 
1390   EXPECT_CALL(interface, SendKeyEvent(0x44, KeyState::PUSHED)).Times(1);
1391 
1392   auto play_pushed_pkt = TestAvrcpPacket::Make();
1393   play_pushed->Serialize(play_pushed_pkt);
1394 
1395   SendMessage(1, play_pushed_pkt);
1396 }
1397 
TEST_F(AvrcpDeviceTest,playPushedInactiveDeviceTest)1398 TEST_F(AvrcpDeviceTest, playPushedInactiveDeviceTest) {
1399   MockMediaInterface interface;
1400   NiceMock<MockA2dpInterface> a2dp_interface;
1401   MockVolumeInterface vol_interface;
1402 
1403   test_device->RegisterInterfaces(&interface, &a2dp_interface, &vol_interface);
1404 
1405   // Pretend the device is not active
1406   EXPECT_CALL(a2dp_interface, active_peer())
1407       .WillRepeatedly(Return(RawAddress::kEmpty));
1408 
1409   auto play_pushed = PassThroughPacketBuilder::MakeBuilder(false, true, 0x44);
1410   auto play_pushed_response =
1411       PassThroughPacketBuilder::MakeBuilder(true, true, 0x44);
1412   EXPECT_CALL(response_cb,
1413               Call(_, false, matchPacket(std::move(play_pushed_response))))
1414       .Times(1);
1415 
1416   // Expect that the device will try to set itself as active
1417   EXPECT_CALL(interface, SetActiveDevice(test_device->GetAddress())).Times(1);
1418 
1419   // No play command should be sent since the music is already playing
1420   PlayStatus status = {0x1234, 0x5678, PlayState::PLAYING};
1421   EXPECT_CALL(interface, GetPlayStatus(_))
1422       .Times(1)
1423       .WillOnce(InvokeCb<0>(status));
1424   EXPECT_CALL(interface, SendKeyEvent(0x44, KeyState::PUSHED)).Times(0);
1425 
1426   auto play_pushed_pkt = TestAvrcpPacket::Make();
1427   play_pushed->Serialize(play_pushed_pkt);
1428 
1429   SendMessage(1, play_pushed_pkt);
1430 }
1431 
TEST_F(AvrcpDeviceTest,mediaKeyActiveDeviceTest)1432 TEST_F(AvrcpDeviceTest, mediaKeyActiveDeviceTest) {
1433   MockMediaInterface interface;
1434   NiceMock<MockA2dpInterface> a2dp_interface;
1435   MockVolumeInterface vol_interface;
1436 
1437   test_device->RegisterInterfaces(&interface, &a2dp_interface, &vol_interface);
1438 
1439   // Pretend the device is active
1440   EXPECT_CALL(a2dp_interface, active_peer())
1441       .WillRepeatedly(Return(test_device->GetAddress()));
1442 
1443   auto play_released =
1444       PassThroughPacketBuilder::MakeBuilder(false, false, 0x44);
1445   auto play_released_response =
1446       PassThroughPacketBuilder::MakeBuilder(true, false, 0x44);
1447   EXPECT_CALL(response_cb,
1448               Call(_, false, matchPacket(std::move(play_released_response))))
1449       .Times(1);
1450 
1451   EXPECT_CALL(interface, GetPlayStatus(_)).Times(0);
1452 
1453   EXPECT_CALL(interface, SendKeyEvent(0x44, KeyState::RELEASED)).Times(1);
1454 
1455   auto play_released_pkt = TestAvrcpPacket::Make();
1456   play_released->Serialize(play_released_pkt);
1457 
1458   SendMessage(1, play_released_pkt);
1459 }
1460 
TEST_F(AvrcpDeviceTest,mediaKeyInactiveDeviceTest)1461 TEST_F(AvrcpDeviceTest, mediaKeyInactiveDeviceTest) {
1462   MockMediaInterface interface;
1463   NiceMock<MockA2dpInterface> a2dp_interface;
1464   MockVolumeInterface vol_interface;
1465 
1466   test_device->RegisterInterfaces(&interface, &a2dp_interface, &vol_interface);
1467 
1468   // Pretend the device is not active
1469   EXPECT_CALL(a2dp_interface, active_peer())
1470       .WillRepeatedly(Return(RawAddress::kEmpty));
1471 
1472   auto play_released =
1473       PassThroughPacketBuilder::MakeBuilder(false, false, 0x44);
1474   auto play_released_response =
1475       PassThroughPacketBuilder::MakeBuilder(true, false, 0x44);
1476   EXPECT_CALL(response_cb,
1477               Call(_, false, matchPacket(std::move(play_released_response))))
1478       .Times(1);
1479 
1480   EXPECT_CALL(interface, GetPlayStatus(_)).Times(0);
1481 
1482   // Expect that the key event wont be sent to the media interface
1483   EXPECT_CALL(interface, SendKeyEvent(0x44, KeyState::RELEASED)).Times(0);
1484 
1485   auto play_released_pkt = TestAvrcpPacket::Make();
1486   play_released->Serialize(play_released_pkt);
1487 
1488   SendMessage(1, play_released_pkt);
1489 }
1490 
TEST_F(AvrcpDeviceTest,getCapabilitiesTest)1491 TEST_F(AvrcpDeviceTest, getCapabilitiesTest) {
1492   MockMediaInterface interface;
1493   NiceMock<MockA2dpInterface> a2dp_interface;
1494 
1495   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1496 
1497   // GetCapabilities with CapabilityID COMPANY_ID
1498   auto request_company_id_response =
1499       GetCapabilitiesResponseBuilder::MakeCompanyIdBuilder(0x001958);
1500   request_company_id_response->AddCompanyId(0x002345);
1501   EXPECT_CALL(
1502       response_cb,
1503       Call(1, false, matchPacket(std::move(request_company_id_response))))
1504       .Times(1);
1505 
1506   auto request_company_id =
1507       TestAvrcpPacket::Make(get_capabilities_request_company_id);
1508   SendMessage(1, request_company_id);
1509 
1510   // GetCapabilities with CapabilityID EVENTS_SUPPORTED
1511   auto request_events_supported_response =
1512       GetCapabilitiesResponseBuilder::MakeEventsSupportedBuilder(
1513           Event::PLAYBACK_STATUS_CHANGED);
1514   request_events_supported_response->AddEvent(Event::TRACK_CHANGED);
1515   request_events_supported_response->AddEvent(Event::PLAYBACK_POS_CHANGED);
1516 
1517   EXPECT_CALL(
1518       response_cb,
1519       Call(2, false, matchPacket(std::move(request_events_supported_response))))
1520       .Times(1);
1521 
1522   auto request_events_supported =
1523       TestAvrcpPacket::Make(get_capabilities_request);
1524   SendMessage(2, request_events_supported);
1525 
1526   // GetCapabilities with CapabilityID UNKNOWN
1527   auto request_unknown_response = RejectBuilder::MakeBuilder(
1528       CommandPdu::GET_CAPABILITIES, Status::INVALID_PARAMETER);
1529 
1530   EXPECT_CALL(response_cb,
1531               Call(3, false, matchPacket(std::move(request_unknown_response))))
1532       .Times(1);
1533 
1534   auto request_unknown =
1535       TestAvrcpPacket::Make(get_capabilities_request_unknown);
1536   SendMessage(3, request_unknown);
1537 }
1538 
TEST_F(AvrcpDeviceTest,getInvalidItemAttributesTest)1539 TEST_F(AvrcpDeviceTest, getInvalidItemAttributesTest) {
1540   MockMediaInterface interface;
1541   NiceMock<MockA2dpInterface> a2dp_interface;
1542 
1543   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1544 
1545   SongInfo info = {"test_id",
1546                    {// The attribute map
1547                     AttributeEntry(Attribute::TITLE, "Test Song"),
1548                     AttributeEntry(Attribute::ARTIST_NAME, "Test Artist"),
1549                     AttributeEntry(Attribute::ALBUM_NAME, "Test Album"),
1550                     AttributeEntry(Attribute::TRACK_NUMBER, "1"),
1551                     AttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2"),
1552                     AttributeEntry(Attribute::GENRE, "Test Genre"),
1553                     AttributeEntry(Attribute::PLAYING_TIME, "1000")}};
1554   std::vector<SongInfo> list = {info};
1555 
1556   EXPECT_CALL(interface, GetNowPlayingList(_))
1557       .WillRepeatedly(InvokeCb<0>("test_id", list));
1558 
1559   auto compare_to_full = GetItemAttributesResponseBuilder::MakeBuilder(
1560       Status::UIDS_CHANGED, 0xFFFF);
1561   compare_to_full->AddAttributeEntry(Attribute::TITLE, "Test Song");
1562   compare_to_full->AddAttributeEntry(Attribute::ARTIST_NAME, "Test Artist");
1563   compare_to_full->AddAttributeEntry(Attribute::ALBUM_NAME, "Test Album");
1564   compare_to_full->AddAttributeEntry(Attribute::TRACK_NUMBER, "1");
1565   compare_to_full->AddAttributeEntry(Attribute::TOTAL_NUMBER_OF_TRACKS, "2");
1566   compare_to_full->AddAttributeEntry(Attribute::GENRE, "Test Genre");
1567   compare_to_full->AddAttributeEntry(Attribute::PLAYING_TIME, "1000");
1568   compare_to_full->AddAttributeEntry(Attribute::DEFAULT_COVER_ART, "0000001");
1569   EXPECT_CALL(response_cb,
1570               Call(1, true, matchPacket(std::move(compare_to_full))))
1571       .Times(1);
1572 
1573   auto request = TestBrowsePacket::Make(
1574       get_item_attributes_request_all_attributes_invalid);
1575   SendBrowseMessage(1, request);
1576 }
1577 
TEST_F(AvrcpDeviceTest,invalidRegisterNotificationTest)1578 TEST_F(AvrcpDeviceTest, invalidRegisterNotificationTest) {
1579   MockMediaInterface interface;
1580   NiceMock<MockA2dpInterface> a2dp_interface;
1581 
1582   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1583 
1584   auto reg_notif_rej_rsp = RejectBuilder::MakeBuilder(
1585       CommandPdu::REGISTER_NOTIFICATION, Status::INVALID_PARAMETER);
1586   EXPECT_CALL(response_cb,
1587               Call(1, false, matchPacket(std::move(reg_notif_rej_rsp))))
1588       .Times(1);
1589 
1590   auto reg_notif_request = TestAvrcpPacket::Make(register_notification_invalid);
1591   SendMessage(1, reg_notif_request);
1592 }
1593 
TEST_F(AvrcpDeviceTest,invalidVendorPacketTest)1594 TEST_F(AvrcpDeviceTest, invalidVendorPacketTest) {
1595   MockMediaInterface interface;
1596   NiceMock<MockA2dpInterface> a2dp_interface;
1597 
1598   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1599 
1600   auto rsp = RejectBuilder::MakeBuilder(static_cast<CommandPdu>(0), Status::INVALID_COMMAND);
1601   EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
1602   auto short_packet = TestAvrcpPacket::Make(short_vendor_packet);
1603   SendMessage(1, short_packet);
1604 }
1605 
TEST_F(AvrcpDeviceTest,invalidCapabilitiesPacketTest)1606 TEST_F(AvrcpDeviceTest, invalidCapabilitiesPacketTest) {
1607   MockMediaInterface interface;
1608   NiceMock<MockA2dpInterface> a2dp_interface;
1609 
1610   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1611 
1612   auto rsp = RejectBuilder::MakeBuilder(CommandPdu::GET_CAPABILITIES, Status::INVALID_PARAMETER);
1613   EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
1614   auto short_packet = TestAvrcpPacket::Make(short_get_capabilities_request);
1615   SendMessage(1, short_packet);
1616 }
1617 
TEST_F(AvrcpDeviceTest,invalidGetElementAttributesPacketTest)1618 TEST_F(AvrcpDeviceTest, invalidGetElementAttributesPacketTest) {
1619   MockMediaInterface interface;
1620   NiceMock<MockA2dpInterface> a2dp_interface;
1621 
1622   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1623 
1624   auto rsp = RejectBuilder::MakeBuilder(CommandPdu::GET_ELEMENT_ATTRIBUTES, Status::INVALID_PARAMETER);
1625   EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
1626   auto short_packet = TestAvrcpPacket::Make(short_get_element_attributes_request);
1627   SendMessage(1, short_packet);
1628 }
1629 
TEST_F(AvrcpDeviceTest,invalidPlayItemPacketTest)1630 TEST_F(AvrcpDeviceTest, invalidPlayItemPacketTest) {
1631   MockMediaInterface interface;
1632   NiceMock<MockA2dpInterface> a2dp_interface;
1633 
1634   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1635 
1636   auto rsp = RejectBuilder::MakeBuilder(CommandPdu::PLAY_ITEM, Status::INVALID_PARAMETER);
1637   EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
1638   auto short_packet = TestAvrcpPacket::Make(short_play_item_request);
1639   SendMessage(1, short_packet);
1640 }
1641 
TEST_F(AvrcpDeviceTest,invalidSetAddressedPlayerPacketTest)1642 TEST_F(AvrcpDeviceTest, invalidSetAddressedPlayerPacketTest) {
1643   MockMediaInterface interface;
1644   NiceMock<MockA2dpInterface> a2dp_interface;
1645 
1646   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1647 
1648   auto rsp = RejectBuilder::MakeBuilder(CommandPdu::SET_ADDRESSED_PLAYER, Status::INVALID_PARAMETER);
1649   EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
1650   auto short_packet = TestAvrcpPacket::Make(short_set_addressed_player_request);
1651   SendMessage(1, short_packet);
1652 }
1653 
TEST_F(AvrcpDeviceTest,invalidBrowsePacketTest)1654 TEST_F(AvrcpDeviceTest, invalidBrowsePacketTest) {
1655   MockMediaInterface interface;
1656   NiceMock<MockA2dpInterface> a2dp_interface;
1657 
1658   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1659 
1660   auto rsp = GeneralRejectBuilder::MakeBuilder(Status::INVALID_COMMAND);
1661   EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
1662   auto short_packet = TestBrowsePacket::Make(short_browse_packet);
1663   SendBrowseMessage(1, short_packet);
1664 }
1665 
TEST_F(AvrcpDeviceTest,invalidGetFolderItemsPacketTest)1666 TEST_F(AvrcpDeviceTest, invalidGetFolderItemsPacketTest) {
1667   MockMediaInterface interface;
1668   NiceMock<MockA2dpInterface> a2dp_interface;
1669 
1670   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1671 
1672   auto rsp = GetFolderItemsResponseBuilder::MakePlayerListBuilder(Status::INVALID_PARAMETER, 0x0000, 0xFFFF);
1673   EXPECT_CALL(response_cb, Call(1, true, matchPacket(std::move(rsp)))).Times(1);
1674   auto short_packet = TestBrowsePacket::Make(short_get_folder_items_request);
1675   SendBrowseMessage(1, short_packet);
1676 }
1677 
TEST_F(AvrcpDeviceTest,invalidGetTotalNumberOfItemsPacketTest)1678 TEST_F(AvrcpDeviceTest, invalidGetTotalNumberOfItemsPacketTest) {
1679   MockMediaInterface interface;
1680   NiceMock<MockA2dpInterface> a2dp_interface;
1681 
1682   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1683 
1684   auto rsp = GetTotalNumberOfItemsResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0x0000, 0xFFFF);
1685   EXPECT_CALL(response_cb, Call(1, true, matchPacket(std::move(rsp)))).Times(1);
1686   auto short_packet = TestBrowsePacket::Make(short_get_total_number_of_items_request);
1687   SendBrowseMessage(1, short_packet);
1688 }
1689 
TEST_F(AvrcpDeviceTest,invalidChangePathPacketTest)1690 TEST_F(AvrcpDeviceTest, invalidChangePathPacketTest) {
1691   MockMediaInterface interface;
1692   NiceMock<MockA2dpInterface> a2dp_interface;
1693 
1694   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1695 
1696   auto rsp = ChangePathResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0);
1697   EXPECT_CALL(response_cb, Call(1, true, matchPacket(std::move(rsp)))).Times(1);
1698   auto short_packet = TestBrowsePacket::Make(short_change_path_request);
1699   SendBrowseMessage(1, short_packet);
1700 }
1701 
TEST_F(AvrcpDeviceTest,invalidGetItemAttributesPacketTest)1702 TEST_F(AvrcpDeviceTest, invalidGetItemAttributesPacketTest) {
1703   MockMediaInterface interface;
1704   NiceMock<MockA2dpInterface> a2dp_interface;
1705 
1706   test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
1707 
1708   auto rsp = GetItemAttributesResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0xFFFF);
1709   EXPECT_CALL(response_cb, Call(1, true, matchPacket(std::move(rsp)))).Times(1);
1710   auto short_packet = TestBrowsePacket::Make(short_get_item_attributes_request);
1711   SendBrowseMessage(1, short_packet);
1712 }
1713 
1714 }  // namespace avrcp
1715 }  // namespace bluetooth
1716 
stack_config_get_interface(void)1717 const stack_config_t* stack_config_get_interface(void) {
1718   return &bluetooth::avrcp::interface;
1719 }
1720