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