• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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