1 /*
2  *
3  *  Copyright 2024 The Android Open Source Project
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  */
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 #include "stack/btm/btm_sco.h"
23 #include "stack/test/btm/btm_test_fixtures.h"
24 #include "test/common/mock_functions.h"
25 #include "udrv/include/uipc.h"
26 
27 extern std::unique_ptr<tUIPC_STATE> mock_uipc_init_ret;
28 extern uint32_t mock_uipc_read_ret;
29 extern bool mock_uipc_send_ret;
30 
31 namespace {
32 
33 class ScoHciTest : public BtmWithMocksTest {
34 public:
35 protected:
SetUp()36   void SetUp() override {
37     BtmWithMocksTest::SetUp();
38     mock_uipc_init_ret = nullptr;
39     mock_uipc_read_ret = 0;
40     mock_uipc_send_ret = true;
41   }
TearDown()42   void TearDown() override { BtmWithMocksTest::TearDown(); }
43 };
44 
45 class ScoHciWithOpenCleanTest : public ScoHciTest {
46 public:
47 protected:
SetUp()48   void SetUp() override {
49     ScoHciTest::SetUp();
50     mock_uipc_init_ret = std::make_unique<tUIPC_STATE>();
51     bluetooth::audio::sco::open();
52   }
TearDown()53   void TearDown() override { bluetooth::audio::sco::cleanup(); }
54 };
55 
TEST_F(ScoHciTest,ScoOverHciOpenFail)56 TEST_F(ScoHciTest, ScoOverHciOpenFail) {
57   bluetooth::audio::sco::open();
58   ASSERT_EQ(get_func_call_count("UIPC_Init"), 1);
59   ASSERT_EQ(get_func_call_count("UIPC_Open"), 0);
60   bluetooth::audio::sco::cleanup();
61 
62   // UIPC is nullptr and shouldn't require an actual call of UIPC_Close;
63   ASSERT_EQ(get_func_call_count("UIPC_Close"), 0);
64 }
65 
TEST_F(ScoHciWithOpenCleanTest,ScoOverHciOpenClean)66 TEST_F(ScoHciWithOpenCleanTest, ScoOverHciOpenClean) {
67   ASSERT_EQ(get_func_call_count("UIPC_Init"), 1);
68   ASSERT_EQ(get_func_call_count("UIPC_Open"), 1);
69   ASSERT_EQ(mock_uipc_init_ret, nullptr);
70 
71   mock_uipc_init_ret = std::make_unique<tUIPC_STATE>();
72   // Double open will override uipc
73   bluetooth::audio::sco::open();
74   ASSERT_EQ(get_func_call_count("UIPC_Init"), 2);
75   ASSERT_EQ(get_func_call_count("UIPC_Open"), 2);
76   ASSERT_EQ(mock_uipc_init_ret, nullptr);
77 
78   bluetooth::audio::sco::cleanup();
79   ASSERT_EQ(get_func_call_count("UIPC_Close"), 1);
80 
81   // Double clean shouldn't fail
82   bluetooth::audio::sco::cleanup();
83   ASSERT_EQ(get_func_call_count("UIPC_Close"), 1);
84 }
85 
TEST_F(ScoHciTest,ScoOverHciReadNoOpen)86 TEST_F(ScoHciTest, ScoOverHciReadNoOpen) {
87   uint8_t buf[100];
88   ASSERT_EQ(bluetooth::audio::sco::read(buf, sizeof(buf)), size_t(0));
89   ASSERT_EQ(get_func_call_count("UIPC_Read"), 0);
90 }
91 
TEST_F(ScoHciWithOpenCleanTest,ScoOverHciRead)92 TEST_F(ScoHciWithOpenCleanTest, ScoOverHciRead) {
93   uint8_t buf[100];
94   // The UPIC should be ready
95   ASSERT_EQ(get_func_call_count("UIPC_Init"), 1);
96   ASSERT_EQ(get_func_call_count("UIPC_Open"), 1);
97   ASSERT_EQ(mock_uipc_init_ret, nullptr);
98 
99   mock_uipc_read_ret = sizeof(buf);
100   ASSERT_EQ(bluetooth::audio::sco::read(buf, sizeof(buf)), mock_uipc_read_ret);
101   ASSERT_EQ(get_func_call_count("UIPC_Read"), 1);
102 }
103 
TEST_F(ScoHciTest,ScoOverHciWriteNoOpen)104 TEST_F(ScoHciTest, ScoOverHciWriteNoOpen) {
105   uint8_t buf[100];
106   bluetooth::audio::sco::write(buf, sizeof(buf));
107   ASSERT_EQ(get_func_call_count("UIPC_Send"), 0);
108 }
109 
TEST_F(ScoHciWithOpenCleanTest,ScoOverHciWrite)110 TEST_F(ScoHciWithOpenCleanTest, ScoOverHciWrite) {
111   uint8_t buf[100];
112   // The UPIC should be ready
113   ASSERT_EQ(get_func_call_count("UIPC_Init"), 1);
114   ASSERT_EQ(get_func_call_count("UIPC_Open"), 1);
115   ASSERT_EQ(mock_uipc_init_ret, nullptr);
116 
117   ASSERT_EQ(bluetooth::audio::sco::write(buf, sizeof(buf)), sizeof(buf));
118   ASSERT_EQ(get_func_call_count("UIPC_Send"), 1);
119 
120   // Send fails
121   mock_uipc_send_ret = false;
122   ASSERT_EQ(bluetooth::audio::sco::write(buf, sizeof(buf)), size_t(0));
123   ASSERT_EQ(get_func_call_count("UIPC_Send"), 2);
124 }
125 }  // namespace
126