• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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