1 /*
2 * Copyright (c) 2022-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 "devicestatus_manager.h"
17
18 namespace OHOS {
19 namespace Msdp {
20 using namespace OHOS::HiviewDFX;
21 namespace {
22 constexpr int32_t ERR_OK = 0;
23 constexpr int32_t ERR_NG = -1;
24 }
OnRemoteDied(const wptr<IRemoteObject> & remote)25 void DevicestatusManager::DevicestatusCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
26 {
27 if (remote == nullptr) {
28 DEV_HILOGE(SERVICE, "OnRemoteDied failed, remote is nullptr");
29 return;
30 }
31 DEV_HILOGD(SERVICE, "Recv death notice");
32 }
33
Init()34 bool DevicestatusManager::Init()
35 {
36 DEV_HILOGI(SERVICE, "Enter");
37 if (devicestatusCBDeathRecipient_ == nullptr) {
38 devicestatusCBDeathRecipient_ = new DevicestatusCallbackDeathRecipient();
39 }
40
41 msdpImpl_ = std::make_unique<DevicestatusMsdpClientImpl>();
42 LoadAlgorithm();
43
44 DEV_HILOGI(SERVICE, "Init success");
45 return true;
46 }
47
GetLatestDevicestatusData(const DevicestatusDataUtils::DevicestatusType & type)48 DevicestatusDataUtils::DevicestatusData DevicestatusManager::GetLatestDevicestatusData(const \
49 DevicestatusDataUtils::DevicestatusType& type)
50 {
51 DEV_HILOGI(SERVICE, "Enter");
52 DevicestatusDataUtils::DevicestatusData data = {type, DevicestatusDataUtils::DevicestatusValue::VALUE_EXIT};
53 if (msdpImpl_ == nullptr) {
54 DEV_HILOGE(SERVICE, "GetObserverData func is nullptr,return default!");
55 data.value = DevicestatusDataUtils::DevicestatusValue::VALUE_INVALID;
56 return data;
57 }
58 msdpData_ = msdpImpl_->GetObserverData();
59 for (auto iter = msdpData_.begin(); iter != msdpData_.end(); ++iter) {
60 if (data.type == iter->first) {
61 data.value = iter->second;
62 return data;
63 }
64 }
65
66 data.value = DevicestatusDataUtils::DevicestatusValue::VALUE_INVALID;
67 return data;
68 }
69
EnableMock(DevicestatusDataUtils::DevicestatusType type)70 bool DevicestatusManager::EnableMock(DevicestatusDataUtils::DevicestatusType type)
71 {
72 DEV_HILOGE(SERVICE, "Enter");
73 if (!InitInterface(type)) {
74 DEV_HILOGE(SERVICE, "init interface fail");
75 return false;
76 }
77
78 if (!InitDataCallback()) {
79 DEV_HILOGE(SERVICE, "init msdp callback fail");
80 return false;
81 }
82 return true;
83 }
84
DisableMock(DevicestatusDataUtils::DevicestatusType type)85 bool DevicestatusManager::DisableMock(DevicestatusDataUtils::DevicestatusType type)
86 {
87 DEV_HILOGE(SERVICE, "Enter");
88 if (msdpImpl_ == nullptr) {
89 DEV_HILOGE(SERVICE, "disable failed, msdpImpl is nullptr");
90 return false;
91 }
92
93 if (msdpImpl_->DisableMsdpImpl(type) == ERR_NG) {
94 DEV_HILOGE(SERVICE, "disable msdp impl failed");
95 return false;
96 }
97
98 if (msdpImpl_->UnregisterImpl() == ERR_NG) {
99 DEV_HILOGE(SERVICE, "unregister impl failed");
100 return false;
101 }
102
103 return true;
104 }
105
InitInterface(DevicestatusDataUtils::DevicestatusType type)106 bool DevicestatusManager::InitInterface(DevicestatusDataUtils::DevicestatusType type)
107 {
108 DEV_HILOGE(SERVICE, "Enter");
109 if (msdpImpl_ == nullptr) {
110 DEV_HILOGE(SERVICE, "msdpImpl_ is nullptr");
111 return false;
112 }
113 if (msdpImpl_->InitMsdpImpl(type) == ERR_NG) {
114 DEV_HILOGE(SERVICE, "init msdp impl failed");
115 return false;
116 };
117 return true;
118 }
119
InitDataCallback()120 bool DevicestatusManager::InitDataCallback()
121 {
122 DEV_HILOGE(SERVICE, "Enter");
123 if (msdpImpl_ == nullptr) {
124 DEV_HILOGE(SERVICE, "msdpImpl_ is nullptr");
125 return false;
126 }
127 DevicestatusMsdpClientImpl::CallbackManager callback =
128 std::bind(&DevicestatusManager::MsdpDataCallback, this, std::placeholders::_1);
129 if (msdpImpl_->RegisterImpl(callback) == ERR_NG) {
130 DEV_HILOGE(SERVICE, "register impl failed");
131 }
132 return true;
133 }
134
MsdpDataCallback(const DevicestatusDataUtils::DevicestatusData & data)135 int32_t DevicestatusManager::MsdpDataCallback(const DevicestatusDataUtils::DevicestatusData& data)
136 {
137 NotifyDevicestatusChange(data);
138 return ERR_OK;
139 }
140
ProcessDeathObserver(wptr<IRemoteObject> object)141 void DevicestatusManager::ProcessDeathObserver(wptr<IRemoteObject> object)
142 {
143 DEV_HILOGI(SERVICE, "Recv death notice");
144 std::lock_guard<std::mutex> lock(mutex_);
145 if (object == nullptr) {
146 DEV_HILOGE(SERVICE, "object is nullptr");
147 return;
148 }
149 sptr<IRemoteObject> client = object.promote();
150 for (auto& typeItem : listenerMap_) {
151 DisableMock(typeItem.first);
152 for (auto iter = typeItem.second.begin(); iter != typeItem.second.end();) {
153 if ((*iter)->AsObject() == client) {
154 iter = typeItem.second.erase(iter);
155 } else {
156 ++iter;
157 }
158 }
159 }
160 }
161
NotifyDevicestatusChange(const DevicestatusDataUtils::DevicestatusData & devicestatusData)162 void DevicestatusManager::NotifyDevicestatusChange(const DevicestatusDataUtils::DevicestatusData& devicestatusData)
163 {
164 DEV_HILOGI(SERVICE, "Enter");
165 // Call back for all listeners
166 std::lock_guard lock(mutex_);
167 auto iter = listenerMap_.find(devicestatusData.type);
168 if (iter == listenerMap_.end()) {
169 DEV_HILOGI(SERVICE, "type:%{public}d is not exist", devicestatusData.type);
170 return;
171 }
172 for (const auto& item : iter->second) {
173 if (item == nullptr) {
174 DEV_HILOGW(SERVICE, "listener is nullptr");
175 continue;
176 }
177 item->OnDevicestatusChanged(devicestatusData);
178 }
179 }
180
Subscribe(const DevicestatusDataUtils::DevicestatusType & type,const sptr<IdevicestatusCallback> & callback)181 void DevicestatusManager::Subscribe(const DevicestatusDataUtils::DevicestatusType& type,
182 const sptr<IdevicestatusCallback>& callback)
183 {
184 DEV_HILOGI(SERVICE, "Enter");
185 if (!EnableMock(type)) {
186 DEV_HILOGE(SERVICE, "Enable failed!");
187 return;
188 }
189 std::lock_guard lock(mutex_);
190 if (clientDeathObserver_ == nullptr) {
191 clientDeathObserver_ = new (std::nothrow) DeathRecipient(*const_cast<DevicestatusManager *>(this));
192 if (clientDeathObserver_ == nullptr) {
193 DEV_HILOGE(SERVICE, "clientDeathObserver_ is nullptr");
194 return;
195 }
196 }
197 DEVICESTATUS_RETURN_IF(callback == nullptr);
198 auto object = callback->AsObject();
199 DEVICESTATUS_RETURN_IF(object == nullptr);
200 object->AddDeathRecipient(clientDeathObserver_);
201 std::set<const sptr<IdevicestatusCallback>, classcomp> listeners;
202 auto dtTypeIter = listenerMap_.find(type);
203 if (dtTypeIter == listenerMap_.end()) {
204 if (!listeners.insert(callback).second) {
205 DEV_HILOGW(SERVICE, "callback is duplicated");
206 return;
207 }
208 listenerMap_.insert(std::make_pair(type, listeners));
209 } else {
210 DEV_HILOGD(SERVICE, "callbacklist.size:%{public}zu", listenerMap_[dtTypeIter->first].size());
211 auto iter = listenerMap_[dtTypeIter->first].find(callback);
212 if (iter != listenerMap_[dtTypeIter->first].end()) {
213 DEV_HILOGW(SERVICE, "Failed to find type");
214 return;
215 }
216 if (!listenerMap_[dtTypeIter->first].insert(callback).second) {
217 DEV_HILOGE(SERVICE, "callback is duplicated");
218 return;
219 }
220 }
221 DEV_HILOGI(SERVICE, "listenerMap_.size:%{public}zu", listenerMap_.size());
222 DEV_HILOGI(SERVICE, "Subscribe success,Exit");
223 }
224
UnSubscribe(const DevicestatusDataUtils::DevicestatusType & type,const sptr<IdevicestatusCallback> & callback)225 void DevicestatusManager::UnSubscribe(const DevicestatusDataUtils::DevicestatusType& type,
226 const sptr<IdevicestatusCallback>& callback)
227 {
228 DEV_HILOGI(SERVICE, "Enter");
229 std::lock_guard lock(mutex_);
230 DEVICESTATUS_RETURN_IF(callback == nullptr);
231 auto object = callback->AsObject();
232 DEVICESTATUS_RETURN_IF(object == nullptr);
233 DEV_HILOGI(SERVICE, "listenerMap_.size=%{public}zu", listenerMap_.size());
234 if (clientDeathObserver_ != nullptr) {
235 object->RemoveDeathRecipient(clientDeathObserver_);
236 }
237 auto dtTypeIter = listenerMap_.find(type);
238 if (dtTypeIter == listenerMap_.end()) {
239 DEV_HILOGE(SERVICE, "Failed to find type");
240 return;
241 }
242 DEV_HILOGI(SERVICE, "callbacklist.size=%{public}zu", listenerMap_[dtTypeIter->first].size());
243 auto iter = listenerMap_[dtTypeIter->first].find(callback);
244 if (iter != listenerMap_[dtTypeIter->first].end()) {
245 if (listenerMap_[dtTypeIter->first].erase(callback) != 0) {
246 if (listenerMap_[dtTypeIter->first].size() == 0) {
247 listenerMap_.erase(dtTypeIter);
248 }
249 }
250 }
251 DEV_HILOGI(SERVICE, "listenerMap_.size = %{public}zu", listenerMap_.size());
252 if (listenerMap_.empty()) {
253 DisableMock(type);
254 } else {
255 DEV_HILOGI(SERVICE, "other subscribe exist");
256 }
257 DEV_HILOGI(SERVICE, "UnSubscribe success,Exit");
258 }
259
LoadAlgorithm()260 int32_t DevicestatusManager::LoadAlgorithm()
261 {
262 DEV_HILOGI(SERVICE, "Enter");
263 if (msdpImpl_ == nullptr) {
264 DEV_HILOGE(SERVICE, "msdpImpl_ is nullptr");
265 return RET_ERR;
266 }
267 if (msdpImpl_->LoadAlgoLib() != RET_OK) {
268 msdpImpl_->LoadAlgorithmLibrary();
269 }
270 return ERR_OK;
271 }
272
UnloadAlgorithm()273 int32_t DevicestatusManager::UnloadAlgorithm()
274 {
275 DEV_HILOGI(SERVICE, "Enter");
276 if (msdpImpl_ == nullptr) {
277 DEV_HILOGE(SERVICE, "msdpImpl_ is nullptr");
278 return RET_ERR;
279 }
280 if (msdpImpl_->UnloadAlgoLib() != RET_OK) {
281 msdpImpl_->UnloadAlgorithmLibrary();
282 }
283 return ERR_OK;
284 }
285
GetPackageName(AccessTokenID tokenId,std::string & packageName)286 void DevicestatusManager::GetPackageName(AccessTokenID tokenId, std::string &packageName)
287 {
288 int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
289 switch (tokenType) {
290 case ATokenTypeEnum::TOKEN_HAP: {
291 HapTokenInfo hapInfo;
292 if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
293 DEV_HILOGE(SERVICE, "get hap token info fail");
294 return;
295 }
296 packageName = hapInfo.bundleName;
297 break;
298 }
299 // Native type and shell type get processname in the same way
300 case ATokenTypeEnum::TOKEN_NATIVE:
301 case ATokenTypeEnum::TOKEN_SHELL: {
302 NativeTokenInfo tokenInfo;
303 if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
304 DEV_HILOGE(SERVICE, "get native token info fail");
305 return;
306 }
307 packageName = tokenInfo.processName;
308 break;
309 }
310 default: {
311 DEV_HILOGE(SERVICE, "token type not match");
312 break;
313 }
314 }
315 }
316 } // namespace Msdp
317 } // namespace OHOS
318