From 0c348413fb8d0a579acb8178c7e006d751508a3e Mon Sep 17 00:00:00 2001 From: Ajay Panicker Date: Sat, 17 Feb 2018 11:22:48 -0800 Subject: [PATCH] Add packet classes needed for AVRCP Absolute Volume Add the Register Notification Request packet as well as the packets Set Absolute Volume packet. Bug: 68854188 Test: run host native test net_test_packets Change-Id: Ie0d1f1fb23254c1353b6a73529ca93e92f231ed5 --- packet/Android.bp | 1 + packet/avrcp/Android.bp | 1 + packet/avrcp/avrcp_common.h | 1 + packet/avrcp/register_notification_packet.cc | 129 ++++++++++++++++++--- packet/avrcp/register_notification_packet.h | 61 +++++++++- packet/avrcp/set_absolute_volume.cc | 76 ++++++++++++ packet/avrcp/set_absolute_volume.h | 81 +++++++++++++ packet/include/avrcp_packet.h | 1 + packet/tests/avrcp/avrcp_test_packets.h | 17 +++ .../avrcp/register_notification_packet_test.cc | 60 +++++++++- .../tests/avrcp/set_absolute_volume_packet_test.cc | 74 ++++++++++++ 11 files changed, 479 insertions(+), 23 deletions(-) create mode 100644 packet/avrcp/set_absolute_volume.cc create mode 100644 packet/avrcp/set_absolute_volume.h create mode 100644 packet/tests/avrcp/set_absolute_volume_packet_test.cc diff --git a/packet/Android.bp b/packet/Android.bp index ea0f2df55..a10b975f0 100644 --- a/packet/Android.bp +++ b/packet/Android.bp @@ -31,6 +31,7 @@ cc_test { "tests/avrcp/pass_through_packet_test.cc", "tests/avrcp/play_item_packet_test.cc", "tests/avrcp/register_notification_packet_test.cc", + "tests/avrcp/set_absolute_volume_packet_test.cc", "tests/avrcp/set_browsed_player_packet_test.cc", "tests/avrcp/vendor_packet_test.cc", "tests/base/iterator_test.cc", diff --git a/packet/avrcp/Android.bp b/packet/avrcp/Android.bp index e6214491e..99c1bad4d 100644 --- a/packet/avrcp/Android.bp +++ b/packet/avrcp/Android.bp @@ -17,6 +17,7 @@ cc_library_static { "pass_through_packet.cc", "play_item.cc", "register_notification_packet.cc", + "set_absolute_volume.cc", "set_browsed_player.cc", "vendor_packet.cc", ], diff --git a/packet/avrcp/avrcp_common.h b/packet/avrcp/avrcp_common.h index 40e254654..c627ebd94 100644 --- a/packet/avrcp/avrcp_common.h +++ b/packet/avrcp/avrcp_common.h @@ -52,6 +52,7 @@ enum class CommandPdu : uint8_t { GET_ELEMENT_ATTRIBUTES = 0x20, GET_PLAY_STATUS = 0x30, REGISTER_NOTIFICATION = 0x31, + SET_ABSOLUTE_VOLUME = 0x50, SET_ADDRESSED_PLAYER = 0x60, PLAY_ITEM = 0x74, }; diff --git a/packet/avrcp/register_notification_packet.cc b/packet/avrcp/register_notification_packet.cc index 1bf2bf004..513127847 100644 --- a/packet/avrcp/register_notification_packet.cc +++ b/packet/avrcp/register_notification_packet.cc @@ -21,6 +21,54 @@ namespace bluetooth { namespace avrcp { +bool RegisterNotificationResponse::IsInterim() const { + return GetCType() == CType::INTERIM; +} + +Event RegisterNotificationResponse::GetEvent() const { + auto value = *(begin() + VendorPacket::kMinSize()); + return static_cast(value); +} + +uint8_t RegisterNotificationResponse::GetVolume() const { + CHECK(GetEvent() == Event::VOLUME_CHANGED); + auto it = begin() + VendorPacket::kMinSize() + static_cast(1); + return *it; +} + +bool RegisterNotificationResponse::IsValid() const { + if (!VendorPacket::IsValid()) return false; + if (size() < kMinSize()) return false; + if (GetCType() != CType::INTERIM && GetCType() != CType::CHANGED) + return false; + + switch (GetEvent()) { + case Event::VOLUME_CHANGED: + return size() == (kMinSize() + 1); + default: + // TODO (apanicke): Add the remaining events when implementing AVRCP + // Controller + return false; + } +} + +std::string RegisterNotificationResponse::ToString() const { + std::stringstream ss; + ss << "RegisterNotificationResponse: " << std::endl; + ss << " └ cType = " << GetCType() << std::endl; + ss << " └ Subunit Type = " << loghex(GetSubunitType()) << std::endl; + ss << " └ Subunit ID = " << loghex(GetSubunitId()) << std::endl; + ss << " └ OpCode = " << GetOpcode() << std::endl; + ss << " └ Company ID = " << loghex(GetCompanyId()) << std::endl; + ss << " └ Command PDU = " << GetCommandPdu() << std::endl; + ss << " └ PacketType = " << GetPacketType() << std::endl; + ss << " └ Parameter Length = " << loghex(GetParameterLength()) << std::endl; + ss << " └ Event Registered = " << GetEvent() << std::endl; + ss << std::endl; + + return ss.str(); +} + std::unique_ptr RegisterNotificationResponseBuilder::MakePlaybackStatusBuilder( bool interim, uint8_t play_status) { @@ -124,22 +172,43 @@ bool RegisterNotificationResponseBuilder::Serialize( VendorPacketBuilder::PushHeader(pkt, 1 + data_size); AddPayloadOctets1(pkt, static_cast(event_)); - if (event_ == Event::PLAYBACK_STATUS_CHANGED) { - uint8_t playback_status = data_ & 0xFF; - AddPayloadOctets1(pkt, playback_status); - } else if (event_ == Event::TRACK_CHANGED) { - AddPayloadOctets8(pkt, base::ByteSwap(data_)); - } else if (event_ == Event::PLAYBACK_POS_CHANGED) { - uint32_t playback_pos = data_ & 0xFFFFFFFF; - AddPayloadOctets4(pkt, base::ByteSwap(playback_pos)); - } else if (event_ == Event::ADDRESSED_PLAYER_CHANGED) { - uint16_t uid_counter = data_ & 0xFFFF; - uint16_t player_id = (data_ >> 16) & 0xFFFF; - AddPayloadOctets2(pkt, base::ByteSwap(player_id)); - AddPayloadOctets2(pkt, base::ByteSwap(uid_counter)); - } else if (event_ == Event::UIDS_CHANGED) { - uint16_t uid_counter = data_ & 0xFFFF; - AddPayloadOctets2(pkt, base::ByteSwap(uid_counter)); + switch (event_) { + case Event::PLAYBACK_STATUS_CHANGED: { + uint8_t playback_status = data_ & 0xFF; + AddPayloadOctets1(pkt, playback_status); + break; + } + case Event::TRACK_CHANGED: { + AddPayloadOctets8(pkt, base::ByteSwap(data_)); + break; + } + case Event::PLAYBACK_POS_CHANGED: { + uint32_t playback_pos = data_ & 0xFFFFFFFF; + AddPayloadOctets4(pkt, base::ByteSwap(playback_pos)); + break; + } + case Event::PLAYER_APPLICATION_SETTING_CHANGED: + break; // No additional data + case Event::NOW_PLAYING_CONTENT_CHANGED: + break; // No additional data + case Event::AVAILABLE_PLAYERS_CHANGED: + break; // No additional data + case Event::ADDRESSED_PLAYER_CHANGED: { + uint16_t uid_counter = data_ & 0xFFFF; + uint16_t player_id = (data_ >> 16) & 0xFFFF; + AddPayloadOctets2(pkt, base::ByteSwap(player_id)); + AddPayloadOctets2(pkt, base::ByteSwap(uid_counter)); + break; + } + case Event::UIDS_CHANGED: { + uint16_t uid_counter = data_ & 0xFFFF; + AddPayloadOctets2(pkt, base::ByteSwap(uid_counter)); + break; + } + default: + // TODO (apanicke): Add Volume Changed builder for when we are controller. + LOG(FATAL) << "Unhandled event for register notification"; + break; } return true; @@ -177,5 +246,33 @@ std::string RegisterNotificationRequest::ToString() const { return ss.str(); } +std::unique_ptr +RegisterNotificationRequestBuilder::MakeBuilder(Event event, + uint32_t interval) { + std::unique_ptr builder( + new RegisterNotificationRequestBuilder(event, interval)); + + return builder; +} + +size_t RegisterNotificationRequestBuilder::size() const { + return RegisterNotificationRequest::kMinSize(); +} + +bool RegisterNotificationRequestBuilder::Serialize( + const std::shared_ptr<::bluetooth::Packet>& pkt) { + ReserveSpace(pkt, size()); + + PacketBuilder::PushHeader(pkt); + + VendorPacketBuilder::PushHeader(pkt, size() - VendorPacket::kMinSize()); + + AddPayloadOctets1(pkt, static_cast(event_)); + + AddPayloadOctets4(pkt, base::ByteSwap(interval_)); + + return true; +} + } // namespace avrcp } // namespace bluetooth \ No newline at end of file diff --git a/packet/avrcp/register_notification_packet.h b/packet/avrcp/register_notification_packet.h index a22f17769..53286c424 100644 --- a/packet/avrcp/register_notification_packet.h +++ b/packet/avrcp/register_notification_packet.h @@ -21,17 +21,50 @@ namespace bluetooth { namespace avrcp { +class RegisterNotificationResponse : public VendorPacket { + public: + virtual ~RegisterNotificationResponse() = default; + + /** + * Register Notificaiton Request Packet Layout + * AvrcpPacket: + * CType c_type_; + * uint8_t subunit_type_ : 5; + * uint8_t subunit_id_ : 3; + * Opcode opcode_; + * VendorPacket: + * uint8_t company_id[3]; + * uint8_t command_pdu; + * uint8_t packet_type; + * uint16_t param_length; + * RegisterNotificationRequestPacket: + * uint8_t event_id; + * uint8_t[] data; // Length changes based on the event_id + */ + static constexpr size_t kMinSize() { return VendorPacket::kMinSize() + 1; } + + // TODO (apanicke): Add other getters when implementing AVRCP Controller + bool IsInterim() const; + Event GetEvent() const; + uint8_t GetVolume() const; + + virtual bool IsValid() const override; + virtual std::string ToString() const override; + + protected: + using VendorPacket::VendorPacket; +}; + class RegisterNotificationResponseBuilder : public VendorPacketBuilder { public: virtual ~RegisterNotificationResponseBuilder() = default; - // Playback Status Changed Maker static std::unique_ptr MakePlaybackStatusBuilder(bool interim, uint8_t play_status); - // Track Changed Maker + static std::unique_ptr MakeTrackChangedBuilder(bool interim, uint64_t track_uid); - // Playback Position Changed Maker + static std::unique_ptr MakePlaybackPositionBuilder(bool interim, uint32_t playback_pos); @@ -97,5 +130,27 @@ class RegisterNotificationRequest : public VendorPacket { using VendorPacket::VendorPacket; }; +class RegisterNotificationRequestBuilder : public VendorPacketBuilder { + public: + virtual ~RegisterNotificationRequestBuilder() = default; + + static std::unique_ptr MakeBuilder( + Event event, uint32_t interval); + + virtual size_t size() const override; + virtual bool Serialize( + const std::shared_ptr<::bluetooth::Packet>& pkt) override; + + protected: + Event event_; + uint32_t interval_; + + RegisterNotificationRequestBuilder(Event event, uint32_t interval) + : VendorPacketBuilder(CType::NOTIFY, CommandPdu::REGISTER_NOTIFICATION, + PacketType::SINGLE), + event_(event), + interval_(interval){}; +}; + } // namespace avrcp } // namespace bluetooth \ No newline at end of file diff --git a/packet/avrcp/set_absolute_volume.cc b/packet/avrcp/set_absolute_volume.cc new file mode 100644 index 000000000..ff6b7acac --- /dev/null +++ b/packet/avrcp/set_absolute_volume.cc @@ -0,0 +1,76 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "set_absolute_volume.h" + +namespace bluetooth { +namespace avrcp { + +std::unique_ptr +SetAbsoluteVolumeRequestBuilder::MakeBuilder(uint8_t volume) { + std::unique_ptr builder( + new SetAbsoluteVolumeRequestBuilder(volume & 0x7F)); + + return builder; +} + +size_t SetAbsoluteVolumeRequestBuilder::size() const { + return VendorPacket::kMinSize() + 1; +} + +bool SetAbsoluteVolumeRequestBuilder::Serialize( + const std::shared_ptr<::bluetooth::Packet>& pkt) { + ReserveSpace(pkt, size()); + + PacketBuilder::PushHeader(pkt); + + VendorPacketBuilder::PushHeader(pkt, size() - VendorPacket::kMinSize()); + + AddPayloadOctets1(pkt, volume_); + + return true; +} + +uint8_t SetAbsoluteVolumeResponse::GetVolume() const { + auto it = begin() + VendorPacket::kMinSize(); + return *it; +} + +bool SetAbsoluteVolumeResponse::IsValid() const { + if (!VendorPacket::IsValid()) return false; + if (GetCType() != CType::ACCEPTED) return false; + return size() == kMinSize(); +} + +std::string SetAbsoluteVolumeResponse::ToString() const { + std::stringstream ss; + ss << "SetAbsoluteVolumeResponse: " << std::endl; + ss << " └ cType = " << GetCType() << std::endl; + ss << " └ Subunit Type = " << loghex(GetSubunitType()) << std::endl; + ss << " └ Subunit ID = " << loghex(GetSubunitId()) << std::endl; + ss << " └ OpCode = " << GetOpcode() << std::endl; + ss << " └ Company ID = " << loghex(GetCompanyId()) << std::endl; + ss << " └ Command PDU = " << GetCommandPdu() << std::endl; + ss << " └ PacketType = " << GetPacketType() << std::endl; + ss << " └ Parameter Length = " << loghex(GetParameterLength()) << std::endl; + ss << " └ Volume = " << GetVolume() << std::endl; + ss << std::endl; + + return ss.str(); +} + +} // namespace avrcp +} // namespace bluetooth \ No newline at end of file diff --git a/packet/avrcp/set_absolute_volume.h b/packet/avrcp/set_absolute_volume.h new file mode 100644 index 000000000..48cd38879 --- /dev/null +++ b/packet/avrcp/set_absolute_volume.h @@ -0,0 +1,81 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "vendor_packet.h" + +// TODO (apanicke): Set Absolute Volume request vs response have the same +// packet structure, the only difference between the two is the CType. +// Adding a passed flag as a parameter would be possible but I feel that +// this would break the design pattern of request vs response. Look into +// this for the future. + +namespace bluetooth { +namespace avrcp { + +class SetAbsoluteVolumeRequestBuilder : public VendorPacketBuilder { + public: + virtual ~SetAbsoluteVolumeRequestBuilder() = default; + + static std::unique_ptr MakeBuilder( + uint8_t volume); + + virtual size_t size() const override; + virtual bool Serialize( + const std::shared_ptr<::bluetooth::Packet>& pkt) override; + + protected: + uint8_t volume_; + + SetAbsoluteVolumeRequestBuilder(uint8_t volume) + : VendorPacketBuilder(CType::CONTROL, CommandPdu::SET_ABSOLUTE_VOLUME, + PacketType::SINGLE), + volume_(volume){}; +}; + +class SetAbsoluteVolumeResponse : public VendorPacket { + public: + virtual ~SetAbsoluteVolumeResponse() = default; + + /** + * AVRCP Play Item Request Packet Layout + * AvrcpPacket: + * CType c_type_; + * uint8_t subunit_type_ : 5; + * uint8_t subunit_id_ : 3; + * Opcode opcode_; + * VendorPacket: + * uint8_t company_id[3]; + * uint8_t command_pdu; + * uint8_t packet_type; + * uint16_t parameter_length; + * SetAbsoluteVolumeResponse: + * uint8_t volume; + */ + static constexpr size_t kMinSize() { return VendorPacket::kMinSize() + 1; } + + uint8_t GetVolume() const; + + virtual bool IsValid() const override; + virtual std::string ToString() const override; + + protected: + using VendorPacket::VendorPacket; +}; + +} // namespace avrcp +} // namespace bluetooth \ No newline at end of file diff --git a/packet/include/avrcp_packet.h b/packet/include/avrcp_packet.h index 9aa37a4f6..54ec2c390 100644 --- a/packet/include/avrcp_packet.h +++ b/packet/include/avrcp_packet.h @@ -31,4 +31,5 @@ #include "avrcp/get_item_attributes.h" #include "avrcp/get_total_number_of_items.h" #include "avrcp/play_item.h" +#include "avrcp/set_absolute_volume.h" #include "avrcp/set_browsed_player.h" \ No newline at end of file diff --git a/packet/tests/avrcp/avrcp_test_packets.h b/packet/tests/avrcp/avrcp_test_packets.h index 2a822c1b9..e40fab2c9 100644 --- a/packet/tests/avrcp/avrcp_test_packets.h +++ b/packet/tests/avrcp/avrcp_test_packets.h @@ -92,6 +92,11 @@ std::vector register_play_status_notification = { 0x03, 0x48, 0x00, 0x00, 0x19, 0x58, 0x31, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x05}; +// AVRCP Register Volume Changed Notification +std::vector register_volume_changed_notification = { + 0x03, 0x48, 0x00, 0x00, 0x19, 0x58, 0x31, 0x00, + 0x00, 0x05, 0x0d, 0x00, 0x00, 0x00, 0x00}; + // AVRCP Interim Playback Status Notification std::vector interim_play_status_notification = { 0x0f, 0x48, 0x00, 0x00, 0x19, 0x58, 0x31, 0x00, 0x00, 0x02, 0x01, 0x00}; @@ -106,6 +111,10 @@ std::vector changed_play_pos_notification = { 0x0d, 0x48, 0x00, 0x00, 0x19, 0x58, 0x31, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00}; +// AVRCP Interim Volume Changed Notification with volume at 55% (0x47) +std::vector interim_volume_changed_notification = { + 0x0f, 0x48, 0x00, 0x00, 0x19, 0x58, 0x31, 0x00, 0x00, 0x02, 0x0d, 0x47}; + // AVRCP Reject List Player Application Settings Response std::vector reject_player_app_settings_response = { 0x0a, 0x48, 0x00, 0x00, 0x19, 0x58, 0x11, 0x00, 0x00, 0x01, 0x00}; @@ -230,4 +239,12 @@ std::vector play_item_request = { std::vector play_item_response = {0x09, 0x48, 0x00, 0x00, 0x19, 0x58, 0x74, 0x00, 0x00, 0x01, 0x04}; +// AVRCP Set Absolute Volume Request with volume at 56% (0x48) +std::vector set_absolute_volume_request = { + 0x00, 0x48, 0x00, 0x00, 0x19, 0x58, 0x50, 0x00, 0x00, 0x01, 0x48}; + +// AVRCP Set Absolute Volume Response with voume at 52% (0x43) +std::vector set_absolute_volume_response = { + 0x09, 0x48, 0x00, 0x00, 0x19, 0x58, 0x50, 0x00, 0x00, 0x01, 0x43}; + } // namespace \ No newline at end of file diff --git a/packet/tests/avrcp/register_notification_packet_test.cc b/packet/tests/avrcp/register_notification_packet_test.cc index 7897587ae..79fb87b03 100644 --- a/packet/tests/avrcp/register_notification_packet_test.cc +++ b/packet/tests/avrcp/register_notification_packet_test.cc @@ -24,6 +24,7 @@ namespace bluetooth { namespace avrcp { using TestRegNotifReqPacket = TestPacketType; +using TestRegNotifRspPacket = TestPacketType; TEST(RegisterNotificationRequestTest, getterTest) { auto test_packet = @@ -50,7 +51,58 @@ TEST(RegisterNotificationRequestTest, invalidTest) { ASSERT_FALSE(test_packet->IsValid()); } -TEST(RegisterNotificationResponseTest, playStatusBuilderTest) { +TEST(RegisterNotificationRequestBuilderTest, builderTest) { + auto builder = + RegisterNotificationRequestBuilder::MakeBuilder(Event::VOLUME_CHANGED, 0); + ASSERT_EQ(builder->size(), register_volume_changed_notification.size()); + + auto test_packet = TestRegNotifReqPacket::Make(); + builder->Serialize(test_packet); + ASSERT_EQ(test_packet->GetData(), register_volume_changed_notification); +} + +TEST(RegisterNotificationResponseTest, volumeGetterTest) { + auto test_packet = + TestRegNotifRspPacket::Make(interim_volume_changed_notification); + + ASSERT_TRUE(test_packet->IsInterim()); + ASSERT_EQ(test_packet->GetEvent(), Event::VOLUME_CHANGED); + ASSERT_EQ(test_packet->GetVolume(), 0x47); +} + +TEST(RegisterNotificationResponseTest, validTest) { + auto test_packet = + TestRegNotifRspPacket::Make(interim_volume_changed_notification); + + ASSERT_TRUE(test_packet->IsValid()); +} + +TEST(RegisterNotificationResponseTest, invalidTest) { + std::vector packet_copy = interim_volume_changed_notification; + packet_copy.push_back(0x00); + auto test_packet = TestRegNotifRspPacket::Make(packet_copy); + ASSERT_FALSE(test_packet->IsValid()); + + std::vector short_packet = {0, 1, 2, 3, 4}; + test_packet = TestRegNotifRspPacket::Make(short_packet); + ASSERT_FALSE(test_packet->IsValid()); + + auto wrong_ctype = interim_volume_changed_notification; + wrong_ctype[0] = 0x00; + test_packet = TestRegNotifRspPacket::Make(short_packet); + ASSERT_FALSE(test_packet->IsValid()); +} + +TEST(RegisterNotificationResponseTest, wrongEventDeathTest) { + auto wrong_event = interim_volume_changed_notification; + wrong_event[10] = 0x00; + auto test_packet = TestRegNotifRspPacket::Make(wrong_event); + + ASSERT_DEATH(test_packet->GetVolume(), + "GetEvent\\(\\) == Event::VOLUME_CHANGED"); +} + +TEST(RegisterNotificationResponseBuilderTest, playStatusBuilderTest) { auto builder = RegisterNotificationResponseBuilder::MakePlaybackStatusBuilder( true, 0x00); ASSERT_EQ(builder->size(), interim_play_status_notification.size()); @@ -59,7 +111,7 @@ TEST(RegisterNotificationResponseTest, playStatusBuilderTest) { ASSERT_EQ(test_packet->GetData(), interim_play_status_notification); } -TEST(RegisterNotificationResponseTest, trackChangedBuilderTest) { +TEST(RegisterNotificationResponseBuilderTest, trackChangedBuilderTest) { auto builder = RegisterNotificationResponseBuilder::MakeTrackChangedBuilder( true, 0x0000000000000000); ASSERT_EQ(builder->size(), interim_track_changed_notification.size()); @@ -68,7 +120,7 @@ TEST(RegisterNotificationResponseTest, trackChangedBuilderTest) { ASSERT_EQ(test_packet->GetData(), interim_track_changed_notification); } -TEST(RegisterNotificationResponseTest, playPositionBuilderTest) { +TEST(RegisterNotificationResponseBuilderTest, playPositionBuilderTest) { auto builder = RegisterNotificationResponseBuilder::MakePlaybackPositionBuilder( false, 0x00000000); @@ -79,4 +131,4 @@ TEST(RegisterNotificationResponseTest, playPositionBuilderTest) { } } // namespace avrcp -} // namespace bluetooth \ No newline at end of file +} // namespace bluetooth diff --git a/packet/tests/avrcp/set_absolute_volume_packet_test.cc b/packet/tests/avrcp/set_absolute_volume_packet_test.cc new file mode 100644 index 000000000..8be462ecd --- /dev/null +++ b/packet/tests/avrcp/set_absolute_volume_packet_test.cc @@ -0,0 +1,74 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "avrcp_test_packets.h" +#include "packet_test_helper.h" +#include "set_absolute_volume.h" + +namespace bluetooth { +namespace avrcp { + +using TestSetVolumeRspPacket = TestPacketType; + +TEST(SetAbsoluteVolumeRequestBuilderTest, builderTest) { + auto builder = SetAbsoluteVolumeRequestBuilder::MakeBuilder(0x48); + ASSERT_EQ(builder->size(), set_absolute_volume_request.size()); + + auto test_packet = TestSetVolumeRspPacket::Make(); + builder->Serialize(test_packet); + ASSERT_EQ(test_packet->GetData(), set_absolute_volume_request); +} + +// Test whether the volume field has the highest bit masked +TEST(SetAbsoluteVolumeRequestBuilderTest, volumeMaskTest) { + auto builder = SetAbsoluteVolumeRequestBuilder::MakeBuilder(0xc8); + auto test_packet = TestSetVolumeRspPacket::Make(); + builder->Serialize(test_packet); + ASSERT_EQ(test_packet->GetData(), set_absolute_volume_request); +} + +TEST(SetAbsoluteVolumeResponseTest, getterTest) { + auto test_packet = TestSetVolumeRspPacket::Make(set_absolute_volume_response); + + ASSERT_EQ(test_packet->GetVolume(), 0x43); +} + +TEST(SetAbsoluteVolumeResponseTest, validTest) { + auto test_packet = TestSetVolumeRspPacket::Make(set_absolute_volume_response); + + ASSERT_TRUE(test_packet->IsValid()); +} + +TEST(SetAbsoluteVolumeResponseTest, invalidTest) { + auto packet_copy = set_absolute_volume_request; + packet_copy.push_back(0x00); + auto test_packet = TestSetVolumeRspPacket::Make(packet_copy); + ASSERT_FALSE(test_packet->IsValid()); + + std::vector short_packet = {0x00, 0x01, 0x02, 0x03, 0x04}; + test_packet = TestSetVolumeRspPacket::Make(short_packet); + ASSERT_FALSE(test_packet->IsValid()); + + auto wrong_ctype = set_absolute_volume_request; + wrong_ctype[0] = 0x00; + test_packet = TestSetVolumeRspPacket::Make(wrong_ctype); + ASSERT_FALSE(test_packet->IsValid()); +} + +} // namespace avrcp +} // namespace bluetooth \ No newline at end of file -- 2.11.0