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 "devicestatus_napi_manager.h"
20 #include "fi_log.h"
21
22 #undef LOG_TAG
23 #define LOG_TAG "DeviceStatusManager"
24
25 namespace OHOS {
26 namespace Msdp {
27 namespace DeviceStatus {
28
OnRemoteDied(const wptr<IRemoteObject> & remote)29 void DeviceStatusManager::DeviceStatusCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
30 {
31 CHKPV(remote);
32 FI_HILOGI("Recv death notice");
33 }
34
OnRemoteDied(const wptr<IRemoteObject> & remote)35 void DeviceStatusManager::BoomerangCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
36 {
37 CHKPV(remote);
38 FI_HILOGI("Recv death notice");
39 if (manager_ == nullptr) {
40 return;
41 }
42 for (auto& entry : manager_->boomerangListeners_) {
43 auto& callbacks = entry.second;
44 auto it = callbacks.begin();
45 if (it == callbacks.end()) {
46 FI_HILOGI("this app is not Subscribe");
47 }
48 while (it != callbacks.end()) {
49 auto callback_remote = (*it)->AsObject();
50 if (callback_remote && callback_remote == remote) {
51 it = callbacks.erase(it);
52 } else {
53 ++it;
54 }
55 }
56 }
57 if (manager_->notityListener_ != nullptr && remote == manager_->notityListener_->AsObject()) {
58 FI_HILOGI("jjy this screenshot app died");
59 manager_->notityListener_ = nullptr;
60 }
61 }
62
Init()63 bool DeviceStatusManager::Init()
64 {
65 CALL_DEBUG_ENTER;
66 if (devicestatusCBDeathRecipient_ == nullptr) {
67 devicestatusCBDeathRecipient_ = new (std::nothrow) DeviceStatusCallbackDeathRecipient();
68 if (devicestatusCBDeathRecipient_ == nullptr) {
69 FI_HILOGE("devicestatusCBDeathRecipient_ failed");
70 return false;
71 }
72 }
73
74 if (boomerangCBDeathRecipient_ == nullptr) {
75 boomerangCBDeathRecipient_ = new (std::nothrow) BoomerangCallbackDeathRecipient(this);
76 if (boomerangCBDeathRecipient_ == nullptr) {
77 FI_HILOGE("boomerangCBDeathRecipient_ failed");
78 return false;
79 }
80 }
81
82 msdpImpl_ = std::make_shared<DeviceStatusMsdpClientImpl>();
83 CHKPF(msdpImpl_);
84
85 FI_HILOGD("Init success");
86 return true;
87 }
88
GetLatestDeviceStatusData(Type type)89 Data DeviceStatusManager::GetLatestDeviceStatusData(Type type)
90 {
91 CALL_DEBUG_ENTER;
92 Data data = {type, OnChangedValue::VALUE_EXIT};
93 if ((type <= TYPE_INVALID) || (type >= TYPE_MAX)) {
94 FI_HILOGE("GetLatestDeviceStatusData type_:%{public}d is error", type);
95 return data;
96 }
97 if (msdpImpl_ == nullptr) {
98 FI_HILOGE("msdpImpl_ is nullptr");
99 data.value = OnChangedValue::VALUE_INVALID;
100 return data;
101 }
102 msdpData_ = msdpImpl_->GetObserverData();
103 for (auto iter = msdpData_.begin(); iter != msdpData_.end(); ++iter) {
104 if (data.type == iter->first) {
105 data.value = iter->second;
106 return data;
107 }
108 }
109 return {type, OnChangedValue::VALUE_INVALID};
110 }
111
Enable(Type type)112 bool DeviceStatusManager::Enable(Type type)
113 {
114 CALL_DEBUG_ENTER;
115 if ((type <= TYPE_INVALID) || (type >= TYPE_MAX)) {
116 FI_HILOGE("Check type is invalid");
117 return false;
118 }
119 InitAlgoMngrInterface(type);
120 InitDataCallback();
121 return true;
122 }
123
Disable(Type type)124 bool DeviceStatusManager::Disable(Type type)
125 {
126 CALL_DEBUG_ENTER;
127 CHKPF(msdpImpl_);
128
129 if (msdpImpl_->Disable(type) != RET_OK) {
130 FI_HILOGE("Disable msdp impl failed");
131 return false;
132 }
133
134 return true;
135 }
136
InitAlgoMngrInterface(Type type)137 bool DeviceStatusManager::InitAlgoMngrInterface(Type type)
138 {
139 CALL_DEBUG_ENTER;
140 CHKPF(msdpImpl_);
141
142 if (msdpImpl_->InitMsdpImpl(type) != RET_OK) {
143 FI_HILOGE("Init msdp impl failed");
144 return false;
145 };
146 return true;
147 }
148
InitDataCallback()149 int32_t DeviceStatusManager::InitDataCallback()
150 {
151 CALL_DEBUG_ENTER;
152 CHKPF(msdpImpl_);
153 DeviceStatusMsdpClientImpl::CallbackManager callback = [this](const Data &data) {
154 return this->MsdpDataCallback(data);
155 };
156 if (msdpImpl_->RegisterImpl(callback) == RET_ERR) {
157 FI_HILOGE("Register impl failed");
158 }
159 return true;
160 }
161
MsdpDataCallback(const Data & data)162 int32_t DeviceStatusManager::MsdpDataCallback(const Data &data)
163 {
164 NotifyDeviceStatusChange(data);
165 return RET_OK;
166 }
167
NotifyDeviceStatusChange(const Data & devicestatusData)168 int32_t DeviceStatusManager::NotifyDeviceStatusChange(const Data &devicestatusData)
169 {
170 CALL_DEBUG_ENTER;
171 FI_HILOGI("type:%{public}d, value:%{public}d", devicestatusData.type, devicestatusData.value);
172 std::set<const sptr<IRemoteDevStaCallback>, classcomp> listeners;
173 std::lock_guard lock(mutex_);
174 auto iter = listeners_.find(devicestatusData.type);
175 if (iter == listeners_.end()) {
176 FI_HILOGE("type:%{public}d is not exits", devicestatusData.type);
177 return false;
178 }
179 if ((devicestatusData.type <= TYPE_INVALID) || (devicestatusData.type >= TYPE_MAX)) {
180 FI_HILOGE("Check devicestatusData.type is invalid");
181 return false;
182 }
183 listeners = (std::set<const sptr<IRemoteDevStaCallback>, classcomp>)(iter->second);
184 for (const auto &listener : listeners) {
185 if (listener == nullptr) {
186 FI_HILOGE("listener is nullptr");
187 return false;
188 }
189 FI_HILOGI("type:%{public}d, arrs_:%{public}d", devicestatusData.type, arrs_[devicestatusData.type]);
190 switch (arrs_[devicestatusData.type]) {
191 case ENTER: {
192 if (devicestatusData.value == VALUE_ENTER) {
193 listener->OnDeviceStatusChanged(devicestatusData);
194 }
195 break;
196 }
197 case EXIT: {
198 if (devicestatusData.value == VALUE_EXIT) {
199 listener->OnDeviceStatusChanged(devicestatusData);
200 }
201 break;
202 }
203 case ENTER_EXIT: {
204 listener->OnDeviceStatusChanged(devicestatusData);
205 break;
206 }
207 default: {
208 FI_HILOGE("OnChangedValue is unknown");
209 break;
210 }
211 }
212 }
213 return RET_OK;
214 }
215
Subscribe(Type type,ActivityEvent event,ReportLatencyNs latency,sptr<IRemoteDevStaCallback> callback)216 void DeviceStatusManager::Subscribe(Type type, ActivityEvent event, ReportLatencyNs latency,
217 sptr<IRemoteDevStaCallback> callback)
218 {
219 CALL_DEBUG_ENTER;
220 CHKPV(callback);
221 if ((type <= TYPE_INVALID) || (type >= TYPE_MAX)) {
222 FI_HILOGE("Subscribe type_:%{public}d is error", type_);
223 return;
224 }
225 if ((event < ENTER) || (event > ENTER_EXIT)) {
226 FI_HILOGE("Subscribe event_:%{public}d is error", event_);
227 return;
228 }
229 event_ = event;
230 type_ = type;
231 std::lock_guard lock(mutex_);
232 arrs_ [type_] = event_;
233 FI_HILOGI("type_:%{public}d, event:%{public}d", type_, event);
234 std::set<const sptr<IRemoteDevStaCallback>, classcomp> listeners;
235 auto object = callback->AsObject();
236 CHKPV(object);
237 FI_HILOGI("listeners_.size:%{public}zu", listeners_.size());
238 auto dtTypeIter = listeners_.find(type);
239 if (dtTypeIter == listeners_.end()) {
240 if (listeners.insert(callback).second) {
241 FI_HILOGI("No found set list of type, insert success");
242 object->AddDeathRecipient(devicestatusCBDeathRecipient_);
243 }
244 auto [_, ret] = listeners_.insert(std::make_pair(type, listeners));
245 if (!ret) {
246 FI_HILOGW("type is duplicated");
247 }
248 } else {
249 FI_HILOGI("callbacklist.size:%{public}zu", listeners_[dtTypeIter->first].size());
250 auto iter = listeners_[dtTypeIter->first].find(callback);
251 if (iter != listeners_[dtTypeIter->first].end()) {
252 return;
253 }
254 if (listeners_[dtTypeIter->first].insert(callback).second) {
255 FI_HILOGI("Find set list of type, insert success");
256 object->AddDeathRecipient(devicestatusCBDeathRecipient_);
257 }
258 }
259 if (!Enable(type)) {
260 FI_HILOGE("Enable failed");
261 return;
262 }
263 }
264
Unsubscribe(Type type,ActivityEvent event,sptr<IRemoteDevStaCallback> callback)265 void DeviceStatusManager::Unsubscribe(Type type, ActivityEvent event, sptr<IRemoteDevStaCallback> callback)
266 {
267 CALL_DEBUG_ENTER;
268 CHKPV(callback);
269 if ((type <= TYPE_INVALID) || (type >= TYPE_MAX)) {
270 FI_HILOGE("Unsubscribe type_:%{public}d is error", type);
271 return;
272 }
273 if ((event < ENTER) || (event > ENTER_EXIT)) {
274 FI_HILOGE("Unsubscribe event_:%{public}d is error", event);
275 return;
276 }
277 auto object = callback->AsObject();
278 CHKPV(object);
279 std::lock_guard lock(mutex_);
280 FI_HILOGI("listeners_.size:%{public}zu, type:%{public}d event:%{public}d", listeners_.size(),
281 static_cast<int32_t>(type), event);
282 auto dtTypeIter = listeners_.find(type);
283 if (dtTypeIter == listeners_.end()) {
284 FI_HILOGE("Failed to find listener for type");
285 return;
286 }
287 FI_HILOGI("callbacklist.size:%{public}zu", listeners_[dtTypeIter->first].size());
288 auto iter = listeners_[dtTypeIter->first].find(callback);
289 if (iter != listeners_[dtTypeIter->first].end()) {
290 if (listeners_[dtTypeIter->first].erase(callback) != 0) {
291 object->RemoveDeathRecipient(devicestatusCBDeathRecipient_);
292 if (listeners_[dtTypeIter->first].empty()) {
293 listeners_.erase(dtTypeIter);
294 }
295 }
296 }
297 FI_HILOGI("listeners_.size:%{public}zu", listeners_.size());
298 if (listeners_.empty()) {
299 Disable(type);
300 } else {
301 FI_HILOGI("Other subscribe exist");
302 }
303 }
304
Subscribe(BoomerangType type,std::string bundleName,sptr<IRemoteBoomerangCallback> callback)305 void DeviceStatusManager::Subscribe(BoomerangType type, std::string bundleName,
306 sptr<IRemoteBoomerangCallback> callback)
307 {
308 CALL_DEBUG_ENTER;
309 CHKPV(callback);
310 if ((type <= BOOMERANG_TYPE_INVALID) || (type >= BOOMERANG_TYPE_MAX)) {
311 FI_HILOGE("Subscribe boomerangType_:%{public}d is error", boomerangType_);
312 return;
313 }
314 boomerangType_ = type;
315 std::lock_guard lock(mutex_);
316 std::set<const sptr<IRemoteBoomerangCallback>, boomerangClasscomp> listeners;
317 auto object = callback->AsObject();
318 CHKPV(object);
319 FI_HILOGI("boomerangListeners_.size:%{public}zu", boomerangListeners_.size());
320 auto dtTypeIter = boomerangListeners_.find(bundleName);
321 if (dtTypeIter == boomerangListeners_.end()) {
322 if (listeners.insert(callback).second) {
323 FI_HILOGI("No found set list of type, insert success");
324 object->AddDeathRecipient(boomerangCBDeathRecipient_);
325 }
326 auto [_, ret] = boomerangListeners_.insert(std::make_pair(bundleName, listeners));
327 if (!ret) {
328 FI_HILOGW("type is duplicated");
329 }
330 } else {
331 FI_HILOGI("callbacklist.size:%{public}zu", boomerangListeners_[dtTypeIter->first].size());
332 auto iter = boomerangListeners_[dtTypeIter->first].find(callback);
333 if (iter != boomerangListeners_[dtTypeIter->first].end()) {
334 return;
335 }
336 if (boomerangListeners_[dtTypeIter->first].insert(callback).second) {
337 FI_HILOGI("Find set list of type, insert success");
338 object->AddDeathRecipient(boomerangCBDeathRecipient_);
339 }
340 }
341 }
342
Unsubscribe(BoomerangType type,std::string bundleName,sptr<IRemoteBoomerangCallback> callback)343 void DeviceStatusManager::Unsubscribe(BoomerangType type, std::string bundleName,
344 sptr<IRemoteBoomerangCallback> callback)
345 {
346 CALL_DEBUG_ENTER;
347 CHKPV(callback);
348 if ((type <= BOOMERANG_TYPE_INVALID) || (type >= BOOMERANG_TYPE_MAX)) {
349 FI_HILOGE("Unsubscribe type_:%{public}d is error", type);
350 return;
351 }
352 auto object = callback->AsObject();
353 CHKPV(object);
354 std::lock_guard lock(mutex_);
355 auto dtTypeIter = boomerangListeners_.find(bundleName);
356 if (dtTypeIter == boomerangListeners_.end()) {
357 FI_HILOGE("Failed to find listener for type");
358 return;
359 }
360 FI_HILOGI("callbacklist.size:%{public}zu", boomerangListeners_[dtTypeIter->first].size());
361 auto iter = boomerangListeners_[dtTypeIter->first].find(callback);
362 if (iter != boomerangListeners_[dtTypeIter->first].end()) {
363 if (boomerangListeners_[dtTypeIter->first].erase(callback) != 0) {
364 object->RemoveDeathRecipient(boomerangCBDeathRecipient_);
365 if (boomerangListeners_[dtTypeIter->first].empty()) {
366 boomerangListeners_.erase(dtTypeIter);
367 }
368 }
369 }
370 FI_HILOGI("listeners_.size:%{public}zu", boomerangListeners_.size());
371 }
372
NotifyMedata(std::string bundleName,sptr<IRemoteBoomerangCallback> callback)373 int32_t DeviceStatusManager::NotifyMedata(std::string bundleName, sptr<IRemoteBoomerangCallback> callback)
374 {
375 CALL_DEBUG_ENTER;
376 if (callback == nullptr) {
377 return RET_ERR;
378 }
379 auto object = callback->AsObject();
380 if (object == nullptr) {
381 return RET_ERR;
382 }
383 std::lock_guard lock(mutex_);
384 auto iter = boomerangListeners_.find(bundleName);
385 if (iter == boomerangListeners_.end()) {
386 FI_HILOGE("bundleName:%{public}s is not exits", bundleName.c_str());
387 return RET_ERR;
388 }
389 auto& callbacks = iter->second;
390 if (callbacks.size() == 0) {
391 FI_HILOGE("this hap is not Subscribe envent");
392 return RET_ERR;
393 }
394
395 for (const auto &listener : callbacks) {
396 if (listener == nullptr) {
397 FI_HILOGE("listener is nullptr");
398 return RET_ERR;
399 }
400 BoomerangData data {};
401 data.type = BoomerangType::BOOMERANG_TYPE_BOOMERANG;
402 data.status = BoomerangStatus::BOOMERANG_STATUS_SCREEN_SHOT;
403 listener->OnScreenshotResult(data);
404 }
405 object->AddDeathRecipient(boomerangCBDeathRecipient_);
406 notityListener_ = callback;
407 return RET_OK;
408 }
409
SubmitMetadata(std::string metadata)410 void DeviceStatusManager::SubmitMetadata(std::string metadata)
411 {
412 CALL_DEBUG_ENTER;
413 CHKPV(notityListener_);
414 std::lock_guard lock(mutex_);
415 notityListener_->OnNotifyMetadata(metadata);
416 }
417
BoomerangEncodeImage(std::shared_ptr<Media::PixelMap> pixelMap,std::string matedata,sptr<IRemoteBoomerangCallback> callback)418 void DeviceStatusManager::BoomerangEncodeImage(std::shared_ptr<Media::PixelMap> pixelMap, std::string matedata,
419 sptr<IRemoteBoomerangCallback> callback)
420 {
421 CALL_DEBUG_ENTER;
422 CHKPV(callback);
423 std::lock_guard lock(mutex_);
424 std::shared_ptr<Media::PixelMap> encodePixelMap;
425 std::shared_ptr<BoomerangAlgoImpl> algo = std::make_shared<BoomerangAlgoImpl>();
426 if (algo == nullptr) {
427 FI_HILOGE("Boomerang Algo init faild");
428 return;
429 }
430 algo->EncodeImage(pixelMap, matedata, encodePixelMap);
431 if (encodePixelMap == nullptr) {
432 FI_HILOGE("encode image is null");
433 return;
434 }
435 callback->OnEncodeImageResult(encodePixelMap);
436 }
437
BoomerangDecodeImage(std::shared_ptr<Media::PixelMap> pixelMap,sptr<IRemoteBoomerangCallback> callback)438 void DeviceStatusManager::BoomerangDecodeImage(std::shared_ptr<Media::PixelMap> pixelMap,
439 sptr<IRemoteBoomerangCallback> callback)
440 {
441 CALL_DEBUG_ENTER;
442 CHKPV(callback);
443 std::lock_guard lock(mutex_);
444 std::string metadata;
445 std::shared_ptr<BoomerangAlgoImpl> algo = std::make_shared<BoomerangAlgoImpl>();
446 if (algo == nullptr) {
447 FI_HILOGE("Boomerang Algo init faild");
448 return;
449 }
450 algo->DecodeImage(pixelMap, metadata);
451 callback->OnNotifyMetadata(metadata);
452 }
453
LoadAlgorithm()454 int32_t DeviceStatusManager::LoadAlgorithm()
455 {
456 CALL_DEBUG_ENTER;
457 if (msdpImpl_ != nullptr) {
458 msdpImpl_->LoadAlgoLibrary();
459 }
460 return RET_OK;
461 }
462
UnloadAlgorithm()463 int32_t DeviceStatusManager::UnloadAlgorithm()
464 {
465 CALL_DEBUG_ENTER;
466 if (msdpImpl_ != nullptr) {
467 msdpImpl_->UnloadAlgoLibrary();
468 }
469 return RET_OK;
470 }
471
GetPackageName(AccessTokenID tokenId,std::string & packageName)472 int32_t DeviceStatusManager::GetPackageName(AccessTokenID tokenId, std::string &packageName)
473 {
474 int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
475 switch (tokenType) {
476 case ATokenTypeEnum::TOKEN_HAP: {
477 HapTokenInfo hapInfo;
478 if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
479 FI_HILOGE("Get hap token info failed");
480 return RET_ERR;
481 }
482 packageName = hapInfo.bundleName;
483 break;
484 }
485 case ATokenTypeEnum::TOKEN_NATIVE:
486 case ATokenTypeEnum::TOKEN_SHELL: {
487 NativeTokenInfo tokenInfo;
488 if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
489 FI_HILOGE("Get native token info failed");
490 return RET_ERR;
491 }
492 packageName = tokenInfo.processName;
493 break;
494 }
495 default: {
496 FI_HILOGE("token type not match");
497 break;
498 }
499 }
500 return RET_OK;
501 }
502 } // namespace DeviceStatus
503 } // namespace Msdp
504 } // namespace OHOS
505