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 namespace OHOS {
22 namespace Msdp {
23 namespace DeviceStatus {
24 namespace {
25 constexpr ::OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MSDP_DOMAIN_ID, "DeviceStatusManager" };
26 } // namespace
27
OnRemoteDied(const wptr<IRemoteObject> & remote)28 void DeviceStatusManager::DeviceStatusCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
29 {
30 CHKPV(remote);
31 FI_HILOGD("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("GetObserverData func is nullptr, return default");
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::TYPE_INVALID) {
79 FI_HILOGE("enable is failed");
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 =
117 std::bind(&DeviceStatusManager::MsdpDataCallback, this, std::placeholders::_1);
118 if (msdpImpl_->RegisterImpl(callback) == RET_ERR) {
119 FI_HILOGE("register impl failed");
120 }
121 return true;
122 }
123
MsdpDataCallback(const Data & data)124 int32_t DeviceStatusManager::MsdpDataCallback(const Data& data)
125 {
126 NotifyDeviceStatusChange(data);
127 return RET_OK;
128 }
129
NotifyDeviceStatusChange(const Data & devicestatusData)130 int32_t DeviceStatusManager::NotifyDeviceStatusChange(const Data& devicestatusData)
131 {
132 CALL_DEBUG_ENTER;
133 FI_HILOGI("type:%{public}d, value:%{public}d", devicestatusData.type, devicestatusData.value);
134 std::set<const sptr<IRemoteDevStaCallback>, classcomp> listeners;
135 auto iter = listenerMap_.find(devicestatusData.type);
136 if (iter == listenerMap_.end()) {
137 FI_HILOGI("type:%{public}d", devicestatusData.type);
138 return false;
139 }
140 listeners = (std::set<const sptr<IRemoteDevStaCallback>, classcomp>)(iter->second);
141 for (const auto &listener : listeners) {
142 if (listener == nullptr) {
143 FI_HILOGE("Listener is nullptr");
144 return false;
145 }
146 FI_HILOGI("type:%{public}d, arrs_:%{public}d", devicestatusData.type, arrs_[devicestatusData.type]);
147 switch (arrs_[devicestatusData.type]) {
148 case ENTER: {
149 if (devicestatusData.value == VALUE_ENTER) {
150 listener->OnDeviceStatusChanged(devicestatusData);
151 }
152 break;
153 }
154 case EXIT: {
155 if (devicestatusData.value == VALUE_EXIT) {
156 listener->OnDeviceStatusChanged(devicestatusData);
157 }
158 break;
159 }
160 case ENTER_EXIT: {
161 listener->OnDeviceStatusChanged(devicestatusData);
162 break;
163 }
164 default: {
165 FI_HILOGE("Exit");
166 break;
167 }
168 }
169 }
170 return RET_OK;
171 }
172
Subscribe(Type type,ActivityEvent event,ReportLatencyNs latency,sptr<IRemoteDevStaCallback> callback)173 void DeviceStatusManager::Subscribe(Type type, ActivityEvent event, ReportLatencyNs latency,
174 sptr<IRemoteDevStaCallback> callback)
175 {
176 CALL_DEBUG_ENTER;
177 CHKPV(callback);
178 event_ = event;
179 type_ = type;
180 if ((type_ <= TYPE_INVALID) || (type_ >= TYPE_MAX)) {
181 FI_HILOGE("Subscribe type_:%{public}d is error", type_);
182 return;
183 }
184 if ((event_ < ENTER) || (event_ > ENTER_EXIT)) {
185 FI_HILOGE("Subscribe event_:%{public}d is error", event_);
186 return;
187 }
188 arrs_ [type_] = event_;
189 FI_HILOGI("type_:%{public}d, event:%{public}d", type_, event);
190 std::set<const sptr<IRemoteDevStaCallback>, classcomp> listeners;
191 FI_HILOGI("listenerMap_.size:%{public}zu", listenerMap_.size());
192 auto object = callback->AsObject();
193 CHKPV(object);
194 std::lock_guard lock(mutex_);
195 auto dtTypeIter = listenerMap_.find(type);
196 if (dtTypeIter == listenerMap_.end()) {
197 if (listeners.insert(callback).second) {
198 FI_HILOGI("No found set list of type, insert success");
199 object->AddDeathRecipient(devicestatusCBDeathRecipient_);
200 }
201 auto [_, ret] = listenerMap_.insert(std::make_pair(type, listeners));
202 if (!ret) {
203 FI_HILOGW("type is duplicated");
204 }
205 } else {
206 FI_HILOGI("callbacklist.size:%{public}zu", listenerMap_[dtTypeIter->first].size());
207 auto iter = listenerMap_[dtTypeIter->first].find(callback);
208 if (iter != listenerMap_[dtTypeIter->first].end()) {
209 return;
210 }
211 if (listenerMap_[dtTypeIter->first].insert(callback).second) {
212 FI_HILOGI("Find set list of type, insert success");
213 object->AddDeathRecipient(devicestatusCBDeathRecipient_);
214 }
215 }
216 if (!Enable(type)) {
217 FI_HILOGE("Enable failed");
218 return;
219 }
220 }
221
Unsubscribe(Type type,ActivityEvent event,sptr<IRemoteDevStaCallback> callback)222 void DeviceStatusManager::Unsubscribe(Type type, ActivityEvent event, sptr<IRemoteDevStaCallback> callback)
223 {
224 CALL_DEBUG_ENTER;
225 CHKPV(callback);
226 if ((type <= TYPE_INVALID) || (type >= TYPE_MAX)) {
227 FI_HILOGE("Unsubscribe type_:%{public}d is error", type);
228 return;
229 }
230 if ((event < ENTER) || (event > ENTER_EXIT)) {
231 FI_HILOGE("Unsubscribe event_:%{public}d is error", event);
232 return;
233 }
234 auto object = callback->AsObject();
235 CHKPV(object);
236 FI_HILOGE("listenerMap_.size:%{public}zu, arrs_:%{public}d", listenerMap_.size(), arrs_ [type_]);
237 FI_HILOGE("UNevent:%{public}d", event);
238 std::lock_guard lock(mutex_);
239 auto dtTypeIter = listenerMap_.find(type);
240 if (dtTypeIter == listenerMap_.end()) {
241 FI_HILOGE("Failed to find listener for type");
242 return;
243 }
244 FI_HILOGI("callbacklist.size:%{public}zu", listenerMap_[dtTypeIter->first].size());
245 auto iter = listenerMap_[dtTypeIter->first].find(callback);
246 if (iter != listenerMap_[dtTypeIter->first].end()) {
247 if (listenerMap_[dtTypeIter->first].erase(callback) != 0) {
248 object->RemoveDeathRecipient(devicestatusCBDeathRecipient_);
249 if (listenerMap_[dtTypeIter->first].empty()) {
250 listenerMap_.erase(dtTypeIter);
251 }
252 }
253 }
254 FI_HILOGI("listenerMap_.size:%{public}zu", listenerMap_.size());
255 if (listenerMap_.empty()) {
256 Disable(type);
257 } else {
258 FI_HILOGI("Other subscribe exist");
259 }
260 }
261
LoadAlgorithm()262 int32_t DeviceStatusManager::LoadAlgorithm()
263 {
264 CALL_DEBUG_ENTER;
265 if (msdpImpl_ != nullptr) {
266 msdpImpl_->LoadAlgoLibrary();
267 }
268 return RET_OK;
269 }
270
UnloadAlgorithm()271 int32_t DeviceStatusManager::UnloadAlgorithm()
272 {
273 CALL_DEBUG_ENTER;
274 if (msdpImpl_ != nullptr) {
275 msdpImpl_->UnloadAlgoLibrary();
276 }
277 return RET_OK;
278 }
279
GetPackageName(AccessTokenID tokenId,std::string & packageName)280 int32_t DeviceStatusManager::GetPackageName(AccessTokenID tokenId, std::string &packageName)
281 {
282 int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
283 switch (tokenType) {
284 case ATokenTypeEnum::TOKEN_HAP: {
285 HapTokenInfo hapInfo;
286 if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
287 FI_HILOGE("Get hap token info fail");
288 return RET_ERR;
289 }
290 packageName = hapInfo.bundleName;
291 break;
292 }
293 case ATokenTypeEnum::TOKEN_NATIVE:
294 case ATokenTypeEnum::TOKEN_SHELL: {
295 NativeTokenInfo tokenInfo;
296 if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
297 FI_HILOGE("Get native token info fail");
298 return RET_ERR;
299 }
300 packageName = tokenInfo.processName;
301 break;
302 }
303 default: {
304 FI_HILOGE("token type not match");
305 break;
306 }
307 }
308 return RET_OK;
309 }
310 } // namespace DeviceStatus
311 } // namespace Msdp
312 } // namespace OHOS
313