1 /*
2 * Copyright (c) 2024 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 "mission/dms_continue_recv_manager.h"
17
18 #include "adapter/dnetwork_adapter.h"
19 #include "datetime_ex.h"
20 #include "distributed_sched_adapter.h"
21 #include "dtbschedmgr_device_info_storage.h"
22 #include "dtbschedmgr_log.h"
23 #include "parcel_helper.h"
24 #include "softbus_adapter/softbus_adapter.h"
25 #include <sys/prctl.h>
26
27 namespace OHOS {
28 namespace DistributedSchedule {
29 namespace {
30 constexpr int32_t ON_CALLBACK = 0;
31 constexpr int32_t ACTIVE = 0;
32 constexpr int32_t INACTIVE = 1;
33 constexpr int32_t INDEX_2 = 2;
34 constexpr int32_t INDEX_3 = 3;
35 constexpr int32_t INDEX_4 = 4;
36 const std::string TAG = "DMSContinueRecvMgr";
37 const std::string CANCEL_FOCUSED_TASK = "cancel_mission_focused_task";
38 const std::u16string DESCRIPTOR = u"ohos.aafwk.RemoteOnListener";
39 }
40
41 IMPLEMENT_SINGLE_INSTANCE(DMSContinueRecvMgr);
42
Init()43 void DMSContinueRecvMgr::Init()
44 {
45 HILOGI("Init start");
46 {
47 std::shared_ptr<SoftbusAdapterListener> missionBroadcastListener =
48 std::make_shared<DistributedMissionBroadcastListener>();
49 int32_t ret = SoftbusAdapter::GetInstance().RegisterSoftbusEventListener(missionBroadcastListener);
50 if (ret != ERR_OK) {
51 HILOGE("get RegisterSoftbusEventListener failed, ret: %{public}d", ret);
52 return;
53 }
54 missionDiedListener_ = new DistributedMissionDiedListener();
55 eventThread_ = std::thread(&DMSContinueRecvMgr::StartEvent, this);
56 std::unique_lock<std::mutex> lock(eventMutex_);
57 eventCon_.wait(lock, [this] {
58 return eventHandler_ != nullptr;
59 });
60 }
61 HILOGI("Init end");
62 }
63
UnInit()64 void DMSContinueRecvMgr::UnInit()
65 {
66 HILOGI("UnInit start");
67 if (eventHandler_ != nullptr) {
68 eventHandler_->GetEventRunner()->Stop();
69 eventThread_.join();
70 eventHandler_ = nullptr;
71 } else {
72 HILOGE("eventHandler_ is nullptr");
73 }
74 HILOGI("UnInit end");
75 }
76
NotifyDataRecv(std::string & senderNetworkId,uint8_t * payload,uint32_t dataLen)77 void DMSContinueRecvMgr::NotifyDataRecv(std::string& senderNetworkId,
78 uint8_t* payload, uint32_t dataLen)
79 {
80 HILOGI("NotifyDataRecv start, senderNetworkId: %{public}s, dataLen: %{public}u",
81 DnetworkAdapter::AnonymizeNetworkId(senderNetworkId).c_str(), dataLen);
82 if (dataLen != DMS_SEND_LEN) {
83 HILOGE("dataLen error, dataLen: %{public}u", dataLen);
84 return;
85 }
86 uint8_t type = (payload[0] & DMS_0XF0) >> CONTINUE_SHIFT_04;
87 uint8_t len = payload[0] & DMS_0X0F;
88 if (len != sizeof(uint32_t) || (type != DMS_UNFOCUSED_TYPE && type != DMS_FOCUSED_TYPE)) {
89 HILOGE("len or type error, len: %{public}u, type: %{public}u", len, type);
90 return;
91 }
92 uint32_t accessTokenId = payload[1] << CONTINUE_SHIFT_24 | payload[INDEX_2] << CONTINUE_SHIFT_16 |
93 payload[INDEX_3] << CONTINUE_SHIFT_08 | payload[INDEX_4];
94 int32_t state = ACTIVE;
95 if (type == DMS_UNFOCUSED_TYPE) {
96 state = INACTIVE;
97 }
98 auto feedfunc = [this, senderNetworkId, accessTokenId, state]() mutable {
99 DealOnBroadcastBusiness(senderNetworkId, accessTokenId, state);
100 };
101 if (eventHandler_ != nullptr) {
102 eventHandler_->PostTask(feedfunc);
103 } else {
104 HILOGE("eventHandler_ is nullptr");
105 }
106 HILOGI("NotifyDataRecv end");
107 }
108
RegisterOnListener(const std::string & type,const sptr<IRemoteObject> & obj)109 int32_t DMSContinueRecvMgr::RegisterOnListener(const std::string& type, const sptr<IRemoteObject>& obj)
110 {
111 HILOGI("RegisterOnListener start, type: %{public}s", type.c_str());
112 if (obj == nullptr) {
113 HILOGE("obj is null, type: %{public}s", type.c_str());
114 return INVALID_PARAMETERS_ERR;
115 }
116 onType_ = type;
117 std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
118 auto iterItem = registerOnListener_.find(type);
119 if (iterItem == registerOnListener_.end()) {
120 HILOGD("The itemItem does not exist in the registerOnListener_, adding, type: %{public}s", type.c_str());
121 std::vector<sptr<IRemoteObject>> objs;
122 obj->AddDeathRecipient(missionDiedListener_);
123 objs.emplace_back(obj);
124 registerOnListener_[type] = objs;
125 HILOGI("RegisterOnListener end");
126 return ERR_OK;
127 }
128 for (auto iter : iterItem->second) {
129 if (iter == obj) {
130 HILOGI("already have obj");
131 return NO_MISSION_INFO_FOR_MISSION_ID;
132 }
133 }
134 obj->AddDeathRecipient(missionDiedListener_);
135 iterItem->second.emplace_back(obj);
136 HILOGI("RegisterOnListener end");
137 return ERR_OK;
138 }
139
RegisterOffListener(const std::string & type,const sptr<IRemoteObject> & obj)140 int32_t DMSContinueRecvMgr::RegisterOffListener(const std::string& type,
141 const sptr<IRemoteObject>& obj)
142 {
143 HILOGI("RegisterOffListener start, type: %{public}s", type.c_str());
144 if (obj == nullptr) {
145 HILOGE("obj is null, type: %{public}s", type.c_str());
146 return INVALID_PARAMETERS_ERR;
147 }
148 for (auto iterItem = registerOnListener_.begin(); iterItem != registerOnListener_.end();) {
149 for (auto iter = iterItem->second.begin(); iter != iterItem->second.end();) {
150 if (*iter == obj) {
151 std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
152 iter = iterItem->second.erase(iter);
153 obj->RemoveDeathRecipient(missionDiedListener_);
154 break;
155 } else {
156 iter++;
157 }
158 }
159 if (iterItem->second.empty()) {
160 std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
161 iterItem = registerOnListener_.erase(iterItem);
162 } else {
163 iterItem++;
164 }
165 }
166 HILOGI("RegisterOffListener end");
167 return ERR_OK;
168 }
169
StartEvent()170 void DMSContinueRecvMgr::StartEvent()
171 {
172 HILOGI("StartEvent start");
173 prctl(PR_SET_NAME, CONTINUE_RECV_MANAGER.c_str());
174 auto runner = AppExecFwk::EventRunner::Create(false);
175 {
176 std::lock_guard<std::mutex> lock(eventMutex_);
177 eventHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
178 }
179 eventCon_.notify_one();
180 runner->Run();
181 HILOGI("StartEvent end");
182 }
183
VerifyBroadcastSource(const std::string & senderNetworkId,const std::string & bundleName,const int32_t state)184 int32_t DMSContinueRecvMgr::VerifyBroadcastSource(const std::string& senderNetworkId,
185 const std::string& bundleName, const int32_t state)
186 {
187 std::lock_guard<std::mutex> currentIconLock(iconMutex_);
188 if (state == ACTIVE) {
189 iconInfo_.senderNetworkId = senderNetworkId;
190 iconInfo_.bundleName = bundleName;
191 } else {
192 if (senderNetworkId != iconInfo_.senderNetworkId) {
193 HILOGW("Sender not match, task abort. senderNetworkId: %{public}s, saved NetworkId: %{public}s",
194 DnetworkAdapter::AnonymizeNetworkId(senderNetworkId).c_str(),
195 DnetworkAdapter::AnonymizeNetworkId(iconInfo_.senderNetworkId).c_str());
196 return INVALID_PARAMETERS_ERR;
197 }
198
199 if (bundleName != iconInfo_.bundleName) {
200 HILOGW("BundleName not match, task abort. bundleName: %{public}s, saved bundleName: %{public}s",
201 bundleName.c_str(), iconInfo_.bundleName.c_str());
202 return INVALID_PARAMETERS_ERR;
203 }
204 iconInfo_.senderNetworkId = "";
205 iconInfo_.bundleName = "";
206 }
207 return ERR_OK;
208 }
209
DealOnBroadcastBusiness(const std::string & senderNetworkId,uint32_t accessTokenId,const int32_t state)210 int32_t DMSContinueRecvMgr::DealOnBroadcastBusiness(const std::string& senderNetworkId,
211 uint32_t accessTokenId, const int32_t state)
212 {
213 HILOGI("DealOnBroadcastBusiness start, senderNetworkId: %{public}s, accessTokenId: %{public}u, state: %{public}d",
214 DnetworkAdapter::AnonymizeNetworkId(senderNetworkId).c_str(), accessTokenId, state);
215 std::string bundleName;
216 int32_t ret = BundleManagerInternal::GetBundleNameFromDbms(senderNetworkId, accessTokenId, bundleName);
217 if (ret != ERR_OK) {
218 HILOGE("get bundleName failed, senderNetworkId: %{public}s, accessTokenId: %{public}u, ret: %{public}d",
219 DnetworkAdapter::AnonymizeNetworkId(senderNetworkId).c_str(), accessTokenId, ret);
220 return ret;
221 }
222 HILOGI("get bundleName, bundleName: %{public}s", bundleName.c_str());
223 AppExecFwk::BundleInfo localBundleInfo;
224 if (BundleManagerInternal::GetLocalBundleInfoV9(bundleName, localBundleInfo) != ERR_OK) {
225 HILOGE("The app is not installed on the local device.");
226 return INVALID_PARAMETERS_ERR;
227 }
228 if (localBundleInfo.applicationInfo.bundleType != AppExecFwk::BundleType::APP) {
229 HILOGE("The bundleType must be app, but it is %{public}d", localBundleInfo.applicationInfo.bundleType);
230 return INVALID_PARAMETERS_ERR;
231 }
232 ret = VerifyBroadcastSource(senderNetworkId, bundleName, state);
233 if (ret != ERR_OK) {
234 return ret;
235 }
236 std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
237 auto iterItem = registerOnListener_.find(onType_);
238 if (iterItem == registerOnListener_.end()) {
239 HILOGE("get iterItem failed from registerOnListener_, accessTokenId: %{public}u", accessTokenId);
240 return INVALID_PARAMETERS_ERR;
241 }
242 std::vector<sptr<IRemoteObject>> objs = iterItem->second;
243 for (auto iter : objs) {
244 NotifyRecvBroadcast(iter, senderNetworkId, bundleName, state);
245 }
246 HILOGI("DealOnBroadcastBusiness end");
247 return ERR_OK;
248 }
249
NotifyRecvBroadcast(const sptr<IRemoteObject> & obj,const std::string & networkId,const std::string & bundleName,const int32_t state)250 void DMSContinueRecvMgr::NotifyRecvBroadcast(const sptr<IRemoteObject>& obj,
251 const std::string& networkId, const std::string& bundleName, const int32_t state)
252 {
253 HILOGI("NotifyRecvBroadcast start");
254 if (obj == nullptr) {
255 HILOGE("obj is null");
256 return;
257 }
258 MessageParcel data;
259 MessageParcel reply;
260 MessageOption option(MessageOption::TF_ASYNC);
261 if (!data.WriteInterfaceToken(DESCRIPTOR)) {
262 HILOGE("NotifyRecvBroadcast write interface token failed");
263 return;
264 }
265 PARCEL_WRITE_HELPER_NORET(data, Int32, state);
266 PARCEL_WRITE_HELPER_NORET(data, String, networkId);
267 PARCEL_WRITE_HELPER_NORET(data, String, bundleName);
268 HILOGI("[PerformanceTest] NotifyRecvBroadcast called, IPC begin = %{public}" PRId64, GetTickCount());
269 int32_t error = obj->SendRequest(ON_CALLBACK, data, reply, option);
270 if (error != ERR_NONE) {
271 HILOGE("NotifyRecvBroadcast fail, error: %{public}d", error);
272 return;
273 }
274 HILOGI("NotifyRecvBroadcast end");
275 }
276
NotifyDied(const sptr<IRemoteObject> & obj)277 void DMSContinueRecvMgr::NotifyDied(const sptr<IRemoteObject>& obj)
278 {
279 HILOGI("NotifyDied start");
280 if (obj == nullptr) {
281 HILOGE("obj is null");
282 return;
283 }
284 for (auto iterItem = registerOnListener_.begin(); iterItem != registerOnListener_.end();) {
285 for (auto iter = iterItem->second.begin(); iter != iterItem->second.end();) {
286 if (*iter == obj) {
287 obj->RemoveDeathRecipient(missionDiedListener_);
288 iter = iterItem->second.erase(iter);
289 } else {
290 iter++;
291 }
292 }
293 if (iterItem->second.empty()) {
294 std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
295 iterItem = registerOnListener_.erase(iterItem);
296 } else {
297 iterItem++;
298 }
299 }
300 HILOGI("NotifyDied end");
301 }
302
303 #ifdef SUPPORT_COMMON_EVENT_SERVICE
OnDeviceScreenOff()304 void DMSContinueRecvMgr::OnDeviceScreenOff()
305 {
306 HILOGI("OnDeviceScreenOff called");
307 auto func = [this]() {
308 std::string senderNetworkId;
309 std::string bundleName;
310 {
311 std::lock_guard<std::mutex> currentIconLock(iconMutex_);
312 if (iconInfo_.isEmpty()) {
313 HILOGW("Saved iconInfo has already been cleared, task abort.");
314 return;
315 }
316 senderNetworkId = iconInfo_.senderNetworkId;
317 bundleName = iconInfo_.bundleName;
318 iconInfo_.senderNetworkId = "";
319 iconInfo_.bundleName = "";
320 }
321 HILOGI("Saved iconInfo cleared, networkId = %{public}s, bundleName = %{public}s",
322 DnetworkAdapter::AnonymizeNetworkId(senderNetworkId).c_str(), bundleName.c_str());
323 {
324 std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
325 auto iterItem = registerOnListener_.find(onType_);
326 if (iterItem == registerOnListener_.end()) {
327 HILOGI("Get iterItem failed from registerOnListener_, nobody registed");
328 return;
329 }
330 std::vector<sptr<IRemoteObject>> objs = iterItem->second;
331 for (auto iter : objs) {
332 NotifyRecvBroadcast(iter, senderNetworkId, bundleName, INACTIVE);
333 }
334 }
335 };
336 if (eventHandler_ == nullptr) {
337 HILOGE("eventHandler_ is nullptr");
338 return;
339 }
340 eventHandler_->PostTask(func);
341 }
342 #endif
343
NotifyDeviceOffline(const std::string & networkId)344 void DMSContinueRecvMgr::NotifyDeviceOffline(const std::string& networkId)
345 {
346 if (networkId.empty()) {
347 HILOGE("NotifyDeviceOffline networkId empty");
348 return;
349 }
350 HILOGI("NotifyDeviceOffline begin. networkId = %{public}s", DnetworkAdapter::AnonymizeNetworkId(networkId).c_str());
351 std::string localNetworkId;
352 if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(localNetworkId)) {
353 HILOGE("Get local networkId failed");
354 return;
355 }
356 std::string senderNetworkId;
357 std::string bundleName;
358 {
359 std::lock_guard<std::mutex> currentIconLock(iconMutex_);
360 if (networkId != iconInfo_.senderNetworkId && networkId != localNetworkId) {
361 HILOGI("NotifyDeviceOffline irrelevant device offline, ignore");
362 return;
363 }
364 senderNetworkId = iconInfo_.senderNetworkId;
365 bundleName = iconInfo_.bundleName;
366 iconInfo_.senderNetworkId = "";
367 iconInfo_.bundleName = "";
368 }
369 HILOGI("Saved iconInfo cleared, networkId = %{public}s, bundleName = %{public}s",
370 DnetworkAdapter::AnonymizeNetworkId(senderNetworkId).c_str(), bundleName.c_str());
371 {
372 std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
373 auto iterItem = registerOnListener_.find(onType_);
374 if (iterItem == registerOnListener_.end()) {
375 HILOGI("Get iterItem failed from registerOnListener_, nobody registed");
376 return;
377 }
378 std::vector<sptr<IRemoteObject>> objs = iterItem->second;
379 for (auto iter : objs) {
380 NotifyRecvBroadcast(iter, senderNetworkId, bundleName, INACTIVE);
381 }
382 }
383 HILOGI("NotifyDeviceOffline end");
384 }
385 } // namespace DistributedSchedule
386 } // namespace OHOS
387