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