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 #include "devicestatus_define.h"
19 #include "fi_log.h"
20 
21 #undef LOG_TAG
22 #define LOG_TAG "DeviceStatusManager"
23 
24 namespace OHOS {
25 namespace Msdp {
26 namespace DeviceStatus {
27 
OnRemoteDied(const wptr<IRemoteObject> & remote)28 void DeviceStatusManager::DeviceStatusCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
29 {
30     CHKPV(remote);
31     FI_HILOGI("Recv death notice");
32 }
33 
Init()34 bool DeviceStatusManager::Init()
35 {
36     CALL_DEBUG_ENTER;
37     if (devicestatusCBDeathRecipient_ == nullptr) {
38         devicestatusCBDeathRecipient_ = new (std::nothrow) DeviceStatusCallbackDeathRecipient();
39         if (devicestatusCBDeathRecipient_ == nullptr) {
40             FI_HILOGE("devicestatusCBDeathRecipient_ failed");
41             return false;
42         }
43     }
44 
45     msdpImpl_ = std::make_shared<DeviceStatusMsdpClientImpl>();
46     CHKPF(msdpImpl_);
47 
48     FI_HILOGD("Init success");
49     return true;
50 }
51 
GetLatestDeviceStatusData(Type type)52 Data DeviceStatusManager::GetLatestDeviceStatusData(Type type)
53 {
54     CALL_DEBUG_ENTER;
55     Data data = {type, OnChangedValue::VALUE_EXIT};
56     if ((type <= TYPE_INVALID) || (type >= TYPE_MAX)) {
57         FI_HILOGE("GetLatestDeviceStatusData type_:%{public}d is error", type);
58         return data;
59     }
60     if (msdpImpl_ == nullptr) {
61         FI_HILOGE("msdpImpl_ is nullptr");
62         data.value = OnChangedValue::VALUE_INVALID;
63         return data;
64     }
65     msdpData_ = msdpImpl_->GetObserverData();
66     for (auto iter = msdpData_.begin(); iter != msdpData_.end(); ++iter) {
67         if (data.type == iter->first) {
68             data.value = iter->second;
69             return data;
70         }
71     }
72     return {type, OnChangedValue::VALUE_INVALID};
73 }
74 
Enable(Type type)75 bool DeviceStatusManager::Enable(Type type)
76 {
77     CALL_DEBUG_ENTER;
78     if ((type <= TYPE_INVALID) || (type >= TYPE_MAX)) {
79         FI_HILOGE("Check type is invalid");
80         return false;
81     }
82     InitAlgoMngrInterface(type);
83     InitDataCallback();
84     return true;
85 }
86 
Disable(Type type)87 bool DeviceStatusManager::Disable(Type type)
88 {
89     CALL_DEBUG_ENTER;
90     CHKPF(msdpImpl_);
91 
92     if (msdpImpl_->Disable(type) != RET_OK) {
93         FI_HILOGE("Disable msdp impl failed");
94         return false;
95     }
96 
97     return true;
98 }
99 
InitAlgoMngrInterface(Type type)100 bool DeviceStatusManager::InitAlgoMngrInterface(Type type)
101 {
102     CALL_DEBUG_ENTER;
103     CHKPF(msdpImpl_);
104 
105     if (msdpImpl_->InitMsdpImpl(type) != RET_OK) {
106         FI_HILOGE("Init msdp impl failed");
107         return false;
108     };
109     return true;
110 }
111 
InitDataCallback()112 int32_t DeviceStatusManager::InitDataCallback()
113 {
114     CALL_DEBUG_ENTER;
115     CHKPF(msdpImpl_);
116     DeviceStatusMsdpClientImpl::CallbackManager callback = [this](const Data &data) {
117         return this->MsdpDataCallback(data);
118     };
119     if (msdpImpl_->RegisterImpl(callback) == RET_ERR) {
120         FI_HILOGE("Register impl failed");
121     }
122     return true;
123 }
124 
MsdpDataCallback(const Data & data)125 int32_t DeviceStatusManager::MsdpDataCallback(const Data &data)
126 {
127     NotifyDeviceStatusChange(data);
128     return RET_OK;
129 }
130 
NotifyDeviceStatusChange(const Data & devicestatusData)131 int32_t DeviceStatusManager::NotifyDeviceStatusChange(const Data &devicestatusData)
132 {
133     CALL_DEBUG_ENTER;
134     FI_HILOGI("type:%{public}d, value:%{public}d", devicestatusData.type, devicestatusData.value);
135     std::set<const sptr<IRemoteDevStaCallback>, classcomp> listeners;
136     std::lock_guard lock(mutex_);
137     auto iter = listeners_.find(devicestatusData.type);
138     if (iter == listeners_.end()) {
139         FI_HILOGE("type:%{public}d is not exits", devicestatusData.type);
140         return false;
141     }
142     if ((devicestatusData.type <= TYPE_INVALID) || (devicestatusData.type >= TYPE_MAX)) {
143         FI_HILOGE("Check devicestatusData.type is invalid");
144         return false;
145     }
146     listeners = (std::set<const sptr<IRemoteDevStaCallback>, classcomp>)(iter->second);
147     for (const auto &listener : listeners) {
148         if (listener == nullptr) {
149             FI_HILOGE("listener is nullptr");
150             return false;
151         }
152         FI_HILOGI("type:%{public}d, arrs_:%{public}d", devicestatusData.type, arrs_[devicestatusData.type]);
153         switch (arrs_[devicestatusData.type]) {
154             case ENTER: {
155                 if (devicestatusData.value == VALUE_ENTER) {
156                     listener->OnDeviceStatusChanged(devicestatusData);
157                 }
158                 break;
159             }
160             case EXIT: {
161                 if (devicestatusData.value == VALUE_EXIT) {
162                     listener->OnDeviceStatusChanged(devicestatusData);
163                 }
164                 break;
165             }
166             case ENTER_EXIT: {
167                 listener->OnDeviceStatusChanged(devicestatusData);
168                 break;
169             }
170             default: {
171                 FI_HILOGE("OnChangedValue is unknown");
172                 break;
173             }
174         }
175     }
176     return RET_OK;
177 }
178 
Subscribe(Type type,ActivityEvent event,ReportLatencyNs latency,sptr<IRemoteDevStaCallback> callback)179 void DeviceStatusManager::Subscribe(Type type, ActivityEvent event, ReportLatencyNs latency,
180     sptr<IRemoteDevStaCallback> callback)
181 {
182     CALL_DEBUG_ENTER;
183     CHKPV(callback);
184     if ((type <= TYPE_INVALID) || (type >= TYPE_MAX)) {
185         FI_HILOGE("Subscribe type_:%{public}d is error", type_);
186         return;
187     }
188     if ((event < ENTER) || (event > ENTER_EXIT)) {
189         FI_HILOGE("Subscribe event_:%{public}d is error", event_);
190         return;
191     }
192     event_ = event;
193     type_ = type;
194     std::lock_guard lock(mutex_);
195     arrs_ [type_] = event_;
196     FI_HILOGI("type_:%{public}d, event:%{public}d", type_, event);
197     std::set<const sptr<IRemoteDevStaCallback>, classcomp> listeners;
198     auto object = callback->AsObject();
199     CHKPV(object);
200     FI_HILOGI("listeners_.size:%{public}zu", listeners_.size());
201     auto dtTypeIter = listeners_.find(type);
202     if (dtTypeIter == listeners_.end()) {
203         if (listeners.insert(callback).second) {
204             FI_HILOGI("No found set list of type, insert success");
205             object->AddDeathRecipient(devicestatusCBDeathRecipient_);
206         }
207         auto [_, ret] = listeners_.insert(std::make_pair(type, listeners));
208         if (!ret) {
209             FI_HILOGW("type is duplicated");
210         }
211     } else {
212         FI_HILOGI("callbacklist.size:%{public}zu", listeners_[dtTypeIter->first].size());
213         auto iter = listeners_[dtTypeIter->first].find(callback);
214         if (iter != listeners_[dtTypeIter->first].end()) {
215             return;
216         }
217         if (listeners_[dtTypeIter->first].insert(callback).second) {
218             FI_HILOGI("Find set list of type, insert success");
219             object->AddDeathRecipient(devicestatusCBDeathRecipient_);
220         }
221     }
222     if (!Enable(type)) {
223         FI_HILOGE("Enable failed");
224         return;
225     }
226 }
227 
Unsubscribe(Type type,ActivityEvent event,sptr<IRemoteDevStaCallback> callback)228 void DeviceStatusManager::Unsubscribe(Type type, ActivityEvent event, sptr<IRemoteDevStaCallback> callback)
229 {
230     CALL_DEBUG_ENTER;
231     CHKPV(callback);
232     if ((type <= TYPE_INVALID) || (type >= TYPE_MAX)) {
233         FI_HILOGE("Unsubscribe type_:%{public}d is error", type);
234         return;
235     }
236     if ((event < ENTER) || (event > ENTER_EXIT)) {
237         FI_HILOGE("Unsubscribe event_:%{public}d is error", event);
238         return;
239     }
240     auto object = callback->AsObject();
241     CHKPV(object);
242     std::lock_guard lock(mutex_);
243     FI_HILOGI("listeners_.size:%{public}zu, type:%{public}d event:%{public}d", listeners_.size(),
244         static_cast<int32_t>(type), event);
245     auto dtTypeIter = listeners_.find(type);
246     if (dtTypeIter == listeners_.end()) {
247         FI_HILOGE("Failed to find listener for type");
248         return;
249     }
250     FI_HILOGI("callbacklist.size:%{public}zu", listeners_[dtTypeIter->first].size());
251     auto iter = listeners_[dtTypeIter->first].find(callback);
252     if (iter != listeners_[dtTypeIter->first].end()) {
253         if (listeners_[dtTypeIter->first].erase(callback) != 0) {
254             object->RemoveDeathRecipient(devicestatusCBDeathRecipient_);
255             if (listeners_[dtTypeIter->first].empty()) {
256                 listeners_.erase(dtTypeIter);
257             }
258         }
259     }
260     FI_HILOGI("listeners_.size:%{public}zu", listeners_.size());
261     if (listeners_.empty()) {
262         Disable(type);
263     } else {
264         FI_HILOGI("Other subscribe exist");
265     }
266 }
267 
LoadAlgorithm()268 int32_t DeviceStatusManager::LoadAlgorithm()
269 {
270     CALL_DEBUG_ENTER;
271     if (msdpImpl_ != nullptr) {
272         msdpImpl_->LoadAlgoLibrary();
273     }
274     return RET_OK;
275 }
276 
UnloadAlgorithm()277 int32_t DeviceStatusManager::UnloadAlgorithm()
278 {
279     CALL_DEBUG_ENTER;
280     if (msdpImpl_ != nullptr) {
281         msdpImpl_->UnloadAlgoLibrary();
282     }
283     return RET_OK;
284 }
285 
GetPackageName(AccessTokenID tokenId,std::string & packageName)286 int32_t 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                 FI_HILOGE("Get hap token info failed");
294                 return RET_ERR;
295             }
296             packageName = hapInfo.bundleName;
297             break;
298         }
299         case ATokenTypeEnum::TOKEN_NATIVE:
300         case ATokenTypeEnum::TOKEN_SHELL: {
301             NativeTokenInfo tokenInfo;
302             if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
303                 FI_HILOGE("Get native token info failed");
304                 return RET_ERR;
305             }
306             packageName = tokenInfo.processName;
307             break;
308         }
309         default: {
310             FI_HILOGE("token type not match");
311             break;
312         }
313     }
314     return RET_OK;
315 }
316 } // namespace DeviceStatus
317 } // namespace Msdp
318 } // namespace OHOS
319