1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <chrono>
17 #include <cinttypes>
18 #include <iostream>
19 #include <thread>
20 #include <gtest/gtest.h>
21 #include "accesstoken_kit.h"
22 #include "nativetoken_kit.h"
23 #include "token_setproc.h"
24 #include "driver_ext_mgr_callback_stub.h"
25 #include "driver_ext_mgr_client.h"
26 #include "edm_errors.h"
27 #include "ext_object.h"
28 #include "hilog_wrapper.h"
29 #include "iservice_registry.h"
30 #include "system_ability_definition.h"
31 #include "system_ability_load_callback_stub.h"
32 
33 namespace OHOS {
34 namespace ExternalDeviceManager {
35 using namespace testing::ext;
36 
37 class DrvExtMgrClientTest : public testing::Test {
38 public:
39     static void SetUpTestCase();
40     static void TearDownTestCase();
41 
SetUp()42     void SetUp() override {}
TearDown()43     void TearDown() override {}
44 
45 private:
46     class LoadCallback : public SystemAbilityLoadCallbackStub {
47     public:
48         void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject) override;
49         void OnLoadSystemAbilityFail(int32_t systemAbilityId) override;
50     };
51 };
52 
53 enum class LoadStatus {
54     LOAD_SUCCESS,
55     LOAD_FAILED,
56     ALREADY_EXISTS,
57 };
58 
59 static LoadStatus g_loadStatus_ = LoadStatus::LOAD_FAILED;
60 static sptr<IRemoteObject> g_saObject = nullptr;
61 static constexpr int32_t ERROR_CODE_WITH_INVALID_CODE = 305;
62 static constexpr uint64_t START_SA_SERVICE_WAIT_TIME = 3;
63 
GetNativeToken()64 void GetNativeToken()
65 {
66     uint64_t tokenId;
67     const char **perms = new const char *[1];
68     perms[0] = "ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVER";
69 
70     NativeTokenInfoParams infoInstance = {
71         .dcapsNum = 0,
72         .permsNum = 1,
73         .aclsNum = 0,
74         .dcaps = nullptr,
75         .perms = perms,
76         .acls = nullptr,
77         .aplStr = "system_core",
78     };
79 
80     infoInstance.processName = "TestCase";
81     tokenId = GetAccessTokenId(&infoInstance);
82     EXPECT_EQ(0, SetSelfTokenID(tokenId));
83     OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
84     delete[] perms;
85 }
86 
SetUpTestCase()87 void DrvExtMgrClientTest::SetUpTestCase()
88 {
89     GetNativeToken();
90     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
91     if (samgr == nullptr) {
92         EDM_LOGE(EDM_MODULE_TEST, "%{public}s get samgr failed", __func__);
93         g_loadStatus_ = LoadStatus::LOAD_FAILED;
94         return;
95     }
96 
97     auto saObj = samgr->CheckSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
98     if (saObj != nullptr) {
99         g_saObject = saObj;
100         g_loadStatus_ = LoadStatus::ALREADY_EXISTS;
101         return;
102     }
103 
104     sptr<LoadCallback> loadCallback_ = new LoadCallback();
105     int32_t ret = samgr->LoadSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID, loadCallback_);
106     if (ret != UsbErrCode::EDM_OK) {
107         EDM_LOGE(EDM_MODULE_TEST, "%{public}s load hdf_ext_devmgr failed", __func__);
108         g_loadStatus_ = LoadStatus::LOAD_FAILED;
109         return;
110     }
111 }
112 
TearDownTestCase()113 void DrvExtMgrClientTest::TearDownTestCase()
114 {
115     if (g_loadStatus_ == LoadStatus::LOAD_FAILED || g_loadStatus_ == LoadStatus::ALREADY_EXISTS) {
116         return;
117     }
118 
119     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
120     if (samgr == nullptr) {
121         EDM_LOGE(EDM_MODULE_TEST, "%{public}s get samgr failed", __func__);
122         return;
123     }
124 
125     int32_t ret = samgr->UnloadSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
126     if (ret != UsbErrCode::EDM_OK) {
127         EDM_LOGE(EDM_MODULE_TEST, "%{public}s unload hdf_ext_devmgr failed, ret:%{public}d", __func__, ret);
128     } else {
129         EDM_LOGE(EDM_MODULE_TEST, "%{public}s unload hdf_ext_devmgr successlfuly", __func__);
130     }
131 }
132 
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)133 void DrvExtMgrClientTest::LoadCallback::OnLoadSystemAbilitySuccess(
134     int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject)
135 {
136     std::cout << "load success: systemAbilityId:" << systemAbilityId
137               << " IRemoteObject result:" << ((remoteObject != nullptr) ? "succeed" : "failed") << std::endl;
138     g_loadStatus_ = LoadStatus::LOAD_SUCCESS;
139     g_saObject = remoteObject;
140 }
141 
OnLoadSystemAbilityFail(int32_t systemAbilityId)142 void DrvExtMgrClientTest::LoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
143 {
144     std::cout << "load failed: systemAbilityId:" << systemAbilityId << std::endl;
145     g_loadStatus_ = LoadStatus::LOAD_FAILED;
146     g_saObject = nullptr;
147 }
148 
149 HWTEST_F(DrvExtMgrClientTest, CheckSAServiceLoad001, TestSize.Level1)
150 {
151     if (g_loadStatus_ != LoadStatus::ALREADY_EXISTS) {
152         std::this_thread::sleep_for(std::chrono::seconds(START_SA_SERVICE_WAIT_TIME));
153     }
154 
155     ASSERT_NE(g_saObject, nullptr);
156 }
157 
158 HWTEST_F(DrvExtMgrClientTest, QueryDevice001, TestSize.Level1)
159 {
160     uint32_t busType = static_cast<uint32_t>(BusType::BUS_TYPE_INVALID);
161     std::vector<std::shared_ptr<DeviceData>> devices;
162     UsbErrCode ret = DriverExtMgrClient::GetInstance().QueryDevice(busType, devices);
163     ASSERT_EQ(ret, UsbErrCode::EDM_ERR_INVALID_PARAM);
164     ASSERT_TRUE(devices.empty());
165 }
166 
167 HWTEST_F(DrvExtMgrClientTest, QueryDevice002, TestSize.Level1)
168 {
169     uint32_t busType = static_cast<uint32_t>(BusType::BUS_TYPE_USB);
170     std::vector<std::shared_ptr<DeviceData>> devices;
171     UsbErrCode ret = DriverExtMgrClient::GetInstance().QueryDevice(busType, devices);
172     ASSERT_EQ(ret, UsbErrCode::EDM_OK);
173     std::cout << "size of devices:" << devices.size() << std::endl;
174     for (const auto &device : devices) {
175         std::cout << device->Dump() << std::endl;
176     }
177 }
178 
179 HWTEST_F(DrvExtMgrClientTest, BindDevice001, TestSize.Level1)
180 {
181     uint64_t deviceId = 0;
182     sptr<IDriverExtMgrCallback> connectCallback = nullptr;
183     UsbErrCode ret = DriverExtMgrClient::GetInstance().BindDevice(deviceId, connectCallback);
184     ASSERT_EQ(ret, UsbErrCode::EDM_ERR_INVALID_PARAM);
185 }
186 
187 class DriverExtMgrCallbackTest : public DriverExtMgrCallbackStub {
188 public:
189     void OnConnect(uint64_t deviceId, const sptr<IRemoteObject> &drvExtObj, const ErrMsg &errMsg) override;
190 
191     void OnDisconnect(uint64_t deviceId, const ErrMsg &errMsg) override;
192 
193     void OnUnBind(uint64_t deviceId, const ErrMsg &errMsg) override;
194 };
195 
OnConnect(uint64_t deviceId,const sptr<IRemoteObject> & drvExtObj,const ErrMsg & errMsg)196 void DriverExtMgrCallbackTest::OnConnect(uint64_t deviceId, const sptr<IRemoteObject> &drvExtObj, const ErrMsg &errMsg)
197 {
198     EDM_LOGE(EDM_MODULE_TEST, "ErrMsg:%{public}d:%{public}s, deviceId:%{public}016" PRIX64 "",
199         static_cast<UsbErrCode>(errMsg.errCode), errMsg.msg.c_str(), deviceId);
200     std::cout << "OnConnect {errCode:" << static_cast<UsbErrCode>(errMsg.errCode) << ", ";
201     std::cout << "msg:" << errMsg.msg << ", ";
202     std::cout << "deviceId:" << deviceId << "}" << std::endl;
203 }
204 
OnDisconnect(uint64_t deviceId,const ErrMsg & errMsg)205 void DriverExtMgrCallbackTest::OnDisconnect(uint64_t deviceId, const ErrMsg &errMsg)
206 {
207     EDM_LOGE(EDM_MODULE_TEST, "ErrMsg:%{public}d:%{public}s, deviceId:%{public}016" PRIX64 "",
208         static_cast<UsbErrCode>(errMsg.errCode), errMsg.msg.c_str(), deviceId);
209     std::cout << "OnDisconnect {errCode:" << static_cast<UsbErrCode>(errMsg.errCode) << ", ";
210     std::cout << "msg:" << errMsg.msg << ", ";
211     std::cout << "deviceId:" << deviceId << "}" << std::endl;
212 }
213 
OnUnBind(uint64_t deviceId,const ErrMsg & errMsg)214 void DriverExtMgrCallbackTest::OnUnBind(uint64_t deviceId, const ErrMsg &errMsg)
215 {
216     EDM_LOGE(EDM_MODULE_TEST, "ErrMsg:%{public}d:%{public}s, deviceId:%{public}016" PRIX64 "",
217         static_cast<UsbErrCode>(errMsg.errCode), errMsg.msg.c_str(), deviceId);
218     std::cout << "OnUnBind {errCode:" << static_cast<UsbErrCode>(errMsg.errCode) << ", ";
219     std::cout << "msg:" << errMsg.msg << ", ";
220     std::cout << "deviceId:" << deviceId << "}" << std::endl;
221 }
222 
223 HWTEST_F(DrvExtMgrClientTest, BindDevice002, TestSize.Level1)
224 {
225     uint64_t deviceId = 0;
226     sptr<IDriverExtMgrCallback> connectCallback = new DriverExtMgrCallbackTest {};
227     UsbErrCode ret = DriverExtMgrClient::GetInstance().BindDevice(deviceId, connectCallback);
228     ASSERT_EQ(ret, UsbErrCode::EDM_NOK);
229 }
230 
231 HWTEST_F(DrvExtMgrClientTest, UnBindDevice001, TestSize.Level1)
232 {
233     uint64_t deviceId = 0;
234     UsbErrCode ret = DriverExtMgrClient::GetInstance().UnBindDevice(deviceId);
235     ASSERT_EQ(ret, UsbErrCode::EDM_NOK);
236 }
237 
238 HWTEST_F(DrvExtMgrClientTest, InvalidCode001, TestSize.Level1)
239 {
240     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
241     ASSERT_NE(samgr, nullptr);
242 
243     auto saObj = samgr->CheckSystemAbility(HDF_EXTERNAL_DEVICE_MANAGER_SA_ID);
244     ASSERT_NE(saObj, nullptr);
245 
246     uint32_t invalid_code = static_cast<uint32_t>(DriverExtMgrInterfaceCode::INVALID_CODE);
247     MessageParcel data;
248     MessageParcel reply;
249     MessageOption option;
250 
251     ASSERT_TRUE(data.WriteInterfaceToken(IDriverExtMgr::GetDescriptor()));
252     int32_t ret = saObj->SendRequest(invalid_code, data, reply, option);
253     ASSERT_EQ(ret, ERROR_CODE_WITH_INVALID_CODE);
254 }
255 } // namespace ExternalDeviceManager
256 } // namespace OHOS