1 /*
2 * Copyright (c) 2022 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 "usbd_load_usb_service.h"
17 #include <cstdlib>
18 #include <iostream>
19 #include <unistd.h>
20 #include "iservice_registry.h"
21 #include "osal_thread.h"
22 #include "osal_time.h"
23
24 using namespace OHOS;
25 using namespace std;
26 #define HDF_LOG_TAG usbd_load_usb_service
27
28 namespace OHOS {
29 namespace HDI {
30 namespace Usb {
31 namespace V1_0 {
32 uint32_t UsbdLoadUsbService::count_ = 0;
33 bool UsbdLoadUsbService::alarmRunning_ = false;
34 bool OnDemandLoadCallback::loading_ = false;
35
OnDemandLoadCallback()36 OnDemandLoadCallback::OnDemandLoadCallback()
37 {
38 }
39
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)40 void OnDemandLoadCallback::OnLoadSystemAbilitySuccess(int32_t systemAbilityId,
41 const sptr<IRemoteObject>& remoteObject)
42 {
43 loading_ = false;
44 HDF_LOGI("%s: OnLoadSystemAbilitySuccess systemAbilityId: %d", __func__, systemAbilityId);
45 }
46
OnLoadSystemAbilityFail(int32_t systemAbilityId)47 void OnDemandLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
48 {
49 loading_ = false;
50 HDF_LOGI("%s: OnLoadSystemAbilityFail systemAbilityId: %d", __func__, systemAbilityId);
51 }
52
GetUsbLoadRemoveCount()53 uint32_t UsbdLoadUsbService::GetUsbLoadRemoveCount()
54 {
55 return count_;
56 }
57
SetUsbLoadRemoveCount(uint32_t count)58 void UsbdLoadUsbService::SetUsbLoadRemoveCount(uint32_t count)
59 {
60 count_ = count;
61 if (count_ > 0) {
62 StartThreadUsbLoad();
63 }
64 }
65
IncreaseUsbLoadRemoveCount()66 void UsbdLoadUsbService::IncreaseUsbLoadRemoveCount()
67 {
68 HDF_LOGI("%s: IncreaseUsbLoadRemoveCount count_: %d", __func__, count_);
69 count_++;
70 }
71
DecreaseUsbLoadRemoveCount()72 void UsbdLoadUsbService::DecreaseUsbLoadRemoveCount()
73 {
74 HDF_LOGI("%s: DecreaseUsbLoadRemoveCount count_: %d", __func__, count_);
75 if (count_ == 0) {
76 return;
77 }
78 count_--;
79 }
80
UsbLoadWorkEntry(void * para)81 int32_t UsbdLoadUsbService::UsbLoadWorkEntry(void *para)
82 {
83 sptr<ISystemAbilityManager> sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
84 if (sm == nullptr) {
85 HDF_LOGE("GetSystemAbilityManager samgr object null");
86 return HDF_FAILURE;
87 }
88 sptr<OnDemandLoadCallback> loadCallback_ = new (std::nothrow) OnDemandLoadCallback();
89 OnDemandLoadCallback::loading_ = true;
90 int32_t result = sm->LoadSystemAbility(USB_SYSTEM_ABILITY_ID, loadCallback_);
91 if (result != ERR_OK) {
92 HDF_LOGE("LoadSystemAbility failed");
93 return HDF_FAILURE;
94 }
95 return HDF_SUCCESS;
96 }
97
StartThreadUsbLoad()98 int32_t UsbdLoadUsbService::StartThreadUsbLoad()
99 {
100 int32_t ret;
101 struct OsalThread threadUsbLoad;
102 struct OsalThreadParam threadCfg = {0};
103 threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
104 threadCfg.stackSize = HDF_PROCESS_STACK_SIZE;
105 sptr<ISystemAbilityManager> sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
106 if (sm == nullptr) {
107 HDF_LOGE("%{public}s:GetSystemAbilityManager failed", __func__);
108 return HDF_FAILURE;
109 }
110 auto saObj = sm->CheckSystemAbility(USB_SYSTEM_ABILITY_ID);
111 if (saObj != nullptr) {
112 return HDF_SUCCESS;
113 }
114 ret = OsalThreadCreate(&threadUsbLoad, static_cast<OsalThreadEntry>(UsbLoadWorkEntry), nullptr);
115 if (ret != HDF_SUCCESS) {
116 HDF_LOGE("%{public}s:%d OsalThreadCreate failed, ret = %d ", __func__, __LINE__, ret);
117 return HDF_ERR_DEVICE_BUSY;
118 }
119 ret = OsalThreadStart(&threadUsbLoad, &threadCfg);
120 if (ret != HDF_SUCCESS) {
121 HDF_LOGE("%{public}s:%d OsalThreadStart failed, ret = %d ", __func__, __LINE__, ret);
122 return HDF_ERR_DEVICE_BUSY;
123 }
124 return HDF_SUCCESS;
125 }
126
UsbRemoveWorkEntry(int32_t sig)127 void UsbdLoadUsbService::UsbRemoveWorkEntry(int32_t sig)
128 {
129 if (GetUsbLoadRemoveCount() == 0) {
130 sptr<ISystemAbilityManager> sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
131 if (sm == nullptr) {
132 HDF_LOGE("GetSystemAbilityManager samgr object null");
133 return;
134 }
135 uint32_t checkCount = CHECK_CNT;
136 while (OnDemandLoadCallback::loading_ && (checkCount > 0)) {
137 checkCount--;
138 auto saObj = sm->CheckSystemAbility(USB_SYSTEM_ABILITY_ID);
139 if (saObj == nullptr) {
140 OsalMDelay(SLEEP_DELAY);
141 continue;
142 } else {
143 OnDemandLoadCallback::loading_ = false;
144 }
145 }
146 int32_t result = sm->RemoveSystemAbility(USB_SYSTEM_ABILITY_ID);
147 if (result != ERR_OK) {
148 HDF_LOGE("RemoveSystemAbility failed");
149 } else {
150 HDF_LOGI("RemoveSystemAbility success");
151 }
152 }
153 alarmRunning_ = false;
154 }
155
LoadUsbService()156 int32_t UsbdLoadUsbService::LoadUsbService()
157 {
158 if (GetUsbLoadRemoveCount() == 0 && alarmRunning_ == false) {
159 if (StartThreadUsbLoad() != HDF_SUCCESS) {
160 HDF_LOGE("%s: usb load create thread failed", __func__);
161 }
162 } else if (OnDemandLoadCallback::loading_ == false) {
163 StartThreadUsbLoad();
164 }
165 IncreaseUsbLoadRemoveCount();
166 return HDF_SUCCESS;
167 }
168
RemoveUsbService()169 int32_t UsbdLoadUsbService::RemoveUsbService()
170 {
171 if (GetUsbLoadRemoveCount() == 1 && alarmRunning_ == false) {
172 alarmRunning_ = true;
173 signal(SIGALRM, UsbRemoveWorkEntry);
174 alarm(CHECK_TIME);
175 }
176 DecreaseUsbLoadRemoveCount();
177 return HDF_SUCCESS;
178 }
179
CloseUsbService()180 void UsbdLoadUsbService::CloseUsbService()
181 {
182 sptr<ISystemAbilityManager> sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
183 if (sm == nullptr) {
184 HDF_LOGE("GetSystemAbilityManager samgr object null");
185 return;
186 }
187 auto saObj = sm->CheckSystemAbility(USB_SYSTEM_ABILITY_ID);
188 if (saObj == nullptr) {
189 HDF_LOGI("Usb service not start");
190 return;
191 }
192 if (sm->RemoveSystemAbility(USB_SYSTEM_ABILITY_ID) != ERR_OK) {
193 HDF_LOGE("RemoveSystemAbility failed");
194 return;
195 }
196 // wait for usb service close
197 OsalMSleep(SLEEP_DELAY);
198 }
199 } // namespace V1_0
200 } // namespace Usb
201 } // namespace HDI
202 } // namespace OHOS
203