• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //  Copyright 2017 Google, Inc.
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 <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 
20 #include "service/a2dp_sink.h"
21 #include "service/hal/fake_bluetooth_av_interface.h"
22 
23 using ::testing::_;
24 using ::testing::Return;
25 
26 namespace bluetooth {
27 namespace {
28 
29 class MockA2dpSinkHandler
30     : public hal::FakeBluetoothAvInterface::TestA2dpSinkHandler {
31  public:
32   MockA2dpSinkHandler() = default;
33   ~MockA2dpSinkHandler() override = default;
34 
35   MOCK_METHOD1(Connect, bt_status_t(RawAddress));
36   MOCK_METHOD1(Disconnect, bt_status_t(RawAddress));
37   MOCK_METHOD1(SetAudioFocusState, void(int));
38   MOCK_METHOD1(SetAudioTrackGain, void(float));
39 
40  private:
41   DISALLOW_COPY_AND_ASSIGN(MockA2dpSinkHandler);
42 };
43 
44 class TestDelegate : public A2dpSink::Delegate {
45  public:
46   TestDelegate() = default;
47   ~TestDelegate() override = default;
48 
49   struct RequestData {
50     std::string device_address;
51     int state = -1;
52     uint32_t sample_rate = 0;
53     uint8_t channel_count = 0;
54     int count = 0;
55   };
56 
57   // A2dpSink::Delegate implementation:
OnConnectionState(const std::string & device_address,int state)58   void OnConnectionState(const std::string& device_address,
59                          int state) override {
60     ++connection_state_.count;
61     connection_state_.device_address = device_address;
62     connection_state_.state = state;
63   }
OnAudioState(const std::string & device_address,int state)64   void OnAudioState(const std::string& device_address, int state) override {
65     ++audio_state_.count;
66     audio_state_.device_address = device_address;
67     audio_state_.state = state;
68   }
OnAudioConfig(const std::string & device_address,uint32_t sample_rate,uint8_t channel_count)69   void OnAudioConfig(const std::string& device_address, uint32_t sample_rate,
70                      uint8_t channel_count) override {
71     ++audio_config_.count;
72     audio_config_.device_address = device_address;
73     audio_config_.sample_rate = sample_rate;
74     audio_config_.channel_count = channel_count;
75   }
76 
connection_state() const77   const RequestData& connection_state() const { return connection_state_; }
audio_state() const78   const RequestData& audio_state() const { return audio_state_; }
audio_config() const79   const RequestData& audio_config() const { return audio_config_; }
80 
81  private:
82   RequestData connection_state_;
83   RequestData audio_state_;
84   RequestData audio_config_;
85 };
86 
87 class A2dpSinkTest : public ::testing::Test {
88  public:
89   A2dpSinkTest() = default;
90   ~A2dpSinkTest() override = default;
91 
SetUp()92   void SetUp() override {
93     mock_handler_.reset(new MockA2dpSinkHandler());
94     fake_hal_av_iface_ = new hal::FakeBluetoothAvInterface(mock_handler_);
95     hal::BluetoothAvInterface::InitializeForTesting(fake_hal_av_iface_);
96     factory_.reset(new A2dpSinkFactory());
97   }
98 
TearDown()99   void TearDown() override {
100     factory_.reset();
101     hal::BluetoothAvInterface::CleanUp();
102   }
103 
104  protected:
105   hal::FakeBluetoothAvInterface* fake_hal_av_iface_;
106   std::shared_ptr<MockA2dpSinkHandler> mock_handler_;
107   std::unique_ptr<A2dpSinkFactory> factory_;
108 
109  private:
110   DISALLOW_COPY_AND_ASSIGN(A2dpSinkTest);
111 };
112 
113 class A2dpSinkPostRegisterTest : public A2dpSinkTest {
114  public:
115   A2dpSinkPostRegisterTest() = default;
116   ~A2dpSinkPostRegisterTest() override = default;
117 
SetUp()118   void SetUp() override {
119     A2dpSinkTest::SetUp();
120     Uuid uuid = Uuid::GetRandom();
121     auto callback = [&](BLEStatus status, const Uuid& in_uuid,
122                         std::unique_ptr<BluetoothInstance> in_client) {
123       CHECK(in_uuid == uuid);
124       CHECK(in_client.get());
125       CHECK(status == BLE_STATUS_SUCCESS);
126 
127       a2dp_sink_ = std::unique_ptr<A2dpSink>(
128           static_cast<A2dpSink*>(in_client.release()));
129     };
130 
131     factory_->RegisterInstance(uuid, callback);
132   }
133 
TearDown()134   void TearDown() override {
135     a2dp_sink_ = nullptr;
136     A2dpSinkTest::TearDown();
137   }
138 
139  protected:
Connect(const std::string & addr)140   void Connect(const std::string& addr) {
141     RawAddress hal_addr;
142     ASSERT_TRUE(RawAddress::FromString(addr, hal_addr));
143 
144     EXPECT_CALL(*mock_handler_, Connect(hal_addr))
145         .WillOnce(Return(BT_STATUS_SUCCESS));
146 
147     EXPECT_TRUE(a2dp_sink_->Connect(addr));
148   }
149 
Disconnect(const std::string & addr)150   void Disconnect(const std::string& addr) {
151     RawAddress hal_addr;
152     ASSERT_TRUE(RawAddress::FromString(addr, hal_addr));
153 
154     EXPECT_CALL(*mock_handler_, Disconnect(hal_addr))
155         .WillOnce(Return(BT_STATUS_SUCCESS));
156 
157     EXPECT_TRUE(a2dp_sink_->Disconnect(addr));
158   }
159 
160   std::unique_ptr<A2dpSink> a2dp_sink_;
161 
162  private:
163   DISALLOW_COPY_AND_ASSIGN(A2dpSinkPostRegisterTest);
164 };
165 
TEST_F(A2dpSinkTest,RegisterA2dpSink)166 TEST_F(A2dpSinkTest, RegisterA2dpSink) {
167   // These will be asynchronously populate with a result when the callback
168   // executes.
169   BLEStatus status = BLE_STATUS_SUCCESS;
170   Uuid cb_uuid;
171   std::unique_ptr<A2dpSink> a2dp_sink;
172   int callback_count = 0;
173 
174   auto callback = [&](BLEStatus in_status, const Uuid& uuid,
175                       std::unique_ptr<BluetoothInstance> in_a2dp_sink) {
176     status = in_status;
177     cb_uuid = uuid;
178     a2dp_sink = std::unique_ptr<A2dpSink>(
179         static_cast<A2dpSink*>(in_a2dp_sink.release()));
180     callback_count++;
181   };
182 
183   Uuid uuid0 = Uuid::GetRandom();
184 
185   // This should always succeed.
186   EXPECT_TRUE(factory_->RegisterInstance(uuid0, callback));
187   EXPECT_EQ(1, callback_count);
188 
189   testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
190 
191   ASSERT_TRUE(a2dp_sink.get() !=
192               nullptr);  // Assert to terminate in case of error
193   EXPECT_EQ(BLE_STATUS_SUCCESS, status);
194   EXPECT_EQ(bluetooth::A2dpSink::kSingletonInstanceId,
195             a2dp_sink->GetInstanceId());
196   EXPECT_EQ(uuid0, a2dp_sink->GetAppIdentifier());
197   EXPECT_EQ(uuid0, cb_uuid);
198 
199   testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
200 }
201 
TEST_F(A2dpSinkPostRegisterTest,Connect)202 TEST_F(A2dpSinkPostRegisterTest, Connect) {
203   static const char kTestAddr[] = "AA:BB:CC:DD:EE:FF";
204   Connect(kTestAddr);
205   Disconnect(kTestAddr);
206 }
207 
TEST_F(A2dpSinkPostRegisterTest,SetAudioFocusState)208 TEST_F(A2dpSinkPostRegisterTest, SetAudioFocusState) {
209   static const char kTestAddr[] = "AA:BB:CC:DD:EE:FF";
210   static const int kFocusState = 2;
211   Connect(kTestAddr);
212 
213   EXPECT_CALL(*mock_handler_, SetAudioFocusState(kFocusState));
214   a2dp_sink_->SetAudioFocusState(kFocusState);
215 
216   Disconnect(kTestAddr);
217 }
218 
TEST_F(A2dpSinkPostRegisterTest,SetAudioTrackGain)219 TEST_F(A2dpSinkPostRegisterTest, SetAudioTrackGain) {
220   static const char kTestAddr[] = "AA:BB:CC:DD:EE:FF";
221   static const float kTrackGain = 0.5;
222   Connect(kTestAddr);
223 
224   EXPECT_CALL(*mock_handler_, SetAudioTrackGain(kTrackGain));
225   a2dp_sink_->SetAudioTrackGain(kTrackGain);
226 
227   Disconnect(kTestAddr);
228 }
229 
TEST_F(A2dpSinkPostRegisterTest,CallbackTest)230 TEST_F(A2dpSinkPostRegisterTest, CallbackTest) {
231   static const char kTestAddr[] = "AA:BB:CC:DD:EE:FF";
232   RawAddress hal_addr;
233   ASSERT_TRUE(RawAddress::FromString(kTestAddr, hal_addr));
234 
235   TestDelegate delegate;
236   a2dp_sink_->SetDelegate(&delegate);
237   Connect(kTestAddr);
238 
239   // OnConnectionState
240   const int kConnectionState = 2;
241   EXPECT_EQ(0, delegate.connection_state().count);
242   fake_hal_av_iface_->NotifyConnectionState(
243       hal_addr, static_cast<btav_connection_state_t>(kConnectionState));
244   EXPECT_EQ(1, delegate.connection_state().count);
245   EXPECT_EQ(kTestAddr, delegate.connection_state().device_address);
246   EXPECT_EQ(kConnectionState, delegate.connection_state().state);
247 
248   // OnAudioState
249   const int kAudioState = 1;
250   EXPECT_EQ(0, delegate.audio_state().count);
251   fake_hal_av_iface_->NotifyAudioState(
252       hal_addr, static_cast<btav_audio_state_t>(kAudioState));
253   EXPECT_EQ(1, delegate.audio_state().count);
254   EXPECT_EQ(kTestAddr, delegate.audio_state().device_address);
255   EXPECT_EQ(kAudioState, delegate.audio_state().state);
256 
257   // OnAudioConfig
258   const uint32_t kSampleRate = 44100;
259   const uint32_t kChannelCount = 2;
260   EXPECT_EQ(0, delegate.audio_config().count);
261   fake_hal_av_iface_->NotifyAudioConfig(hal_addr, kSampleRate, kChannelCount);
262   EXPECT_EQ(1, delegate.audio_config().count);
263   EXPECT_EQ(kTestAddr, delegate.audio_config().device_address);
264   EXPECT_EQ(kSampleRate, delegate.audio_config().sample_rate);
265   EXPECT_EQ(kChannelCount, delegate.audio_config().channel_count);
266 
267   Disconnect(kTestAddr);
268 }
269 
270 }  // namespace
271 }  // namespace bluetooth
272