• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "distributed_sched_service.h"
17 
18 #include <cinttypes>
19 #include <unistd.h>
20 
21 #include "ability_connection_wrapper_stub.h"
22 #include "ability_manager_client.h"
23 #include "ability_manager_errors.h"
24 #include "adapter/dnetwork_adapter.h"
25 #include "bool_wrapper.h"
26 #include "bundle/bundle_manager_internal.h"
27 #include "connect_death_recipient.h"
28 #include "datetime_ex.h"
29 #include "distributed_sched_adapter.h"
30 #include "distributed_sched_dumper.h"
31 #include "distributed_sched_permission.h"
32 #include "dms_callback_task.h"
33 #include "dms_free_install_callback.h"
34 #include "dms_token_callback.h"
35 #include "dms_version_manager.h"
36 #include "dtbschedmgr_device_info_storage.h"
37 #include "dtbschedmgr_log.h"
38 #include "element_name.h"
39 #include "file_ex.h"
40 #ifdef SUPPORT_DISTRIBUTED_FORM_SHARE
41 #include "form_mgr_death_recipient.h"
42 #endif
43 #include "ipc_skeleton.h"
44 #include "iservice_registry.h"
45 #ifdef SUPPORT_DISTRIBUTEDCOMPONENT_TO_MEMMGR
46 #include "mem_mgr_client.h"
47 #endif
48 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
49 #include "mission/distributed_mission_info.h"
50 #include "mission/distributed_sched_continue_manager.h"
51 #include "mission/distributed_sched_mission_manager.h"
52 #endif
53 #include "os_account_manager.h"
54 #include "parameters.h"
55 #include "parcel_helper.h"
56 #ifdef EFFICIENCY_MANAGER_ENABLE
57 #include "report_event_type.h"
58 #include "suspend_manager_client.h"
59 #endif
60 #include "string_ex.h"
61 #include "system_ability_definition.h"
62 
63 namespace OHOS {
64 namespace DistributedSchedule {
65 using namespace AAFwk;
66 using namespace AccountSA;
67 using namespace AppExecFwk;
68 
69 namespace {
70 const std::string TAG = "DistributedSchedService";
71 const std::string DMS_SRC_NETWORK_ID = "dmsSrcNetworkId";
72 const int DEFAULT_REQUEST_CODE = -1;
73 const std::u16string CONNECTION_CALLBACK_INTERFACE_TOKEN = u"ohos.abilityshell.DistributedConnection";
74 const std::u16string COMPONENT_CHANGE_INTERFACE_TOKEN = u"ohos.rms.DistributedComponent";
75 const std::u16string ABILITY_MANAGER_SERVICE_TOKEN = u"ohos.aafwk.AbilityManager";
76 const std::u16string ATOMIC_SERVICE_STATUS_CALLBACK_TOKEN = u"ohos.IAtomicServiceStatusCallback";
77 const std::string BUNDLE_NAME_KEY = "bundleName";
78 const std::string VERSION_CODE_KEY = "version";
79 const std::string PID_KEY = "pid";
80 const std::string UID_KEY = "uid";
81 const std::string COMPONENT_TYPE_KEY = "componentType";
82 const std::string DEVICE_TYPE_KEY = "deviceType";
83 const std::string CHANGE_TYPE_KEY = "changeType";
84 const std::string DMS_HIPLAY_ACTION = "ohos.ability.action.deviceSelect";
85 const std::string DMS_VERSION_ID = "dmsVersion";
86 const std::string DMS_CONNECT_TOKEN = "connectToken";
87 const std::string DMS_VERSION = "4.0.0";
88 const std::string DMS_MISSION_ID = "dmsMissionId";
89 const std::string SUPPORT_CONTINUE_PAGE_STACK_KEY = "ohos.extra.param.key.supportContinuePageStack";
90 const std::string SUPPORT_CONTINUE_SOURCE_EXIT_KEY = "ohos.extra.param.key.supportContinueSourceExit";
91 const std::string SUPPORT_CONTINUE_MODULE_NAME_UPDATE_KEY = "ohos.extra.param.key.supportContinueModuleNameUpdate";
92 constexpr int32_t DEFAULT_DMS_MISSION_ID = -1;
93 constexpr int32_t DEFAULT_DMS_CONNECT_TOKEN = -1;
94 constexpr int32_t BIND_CONNECT_RETRY_TIMES = 3;
95 constexpr int32_t BIND_CONNECT_TIMEOUT = 500; // 500ms
96 constexpr int32_t MAX_DISTRIBUTED_CONNECT_NUM = 600;
97 constexpr int32_t INVALID_CALLER_UID = -1;
98 constexpr int32_t IASS_CALLBACK_ON_REMOTE_FREE_INSTALL_DONE = 1;
99 constexpr int32_t DISTRIBUTED_COMPONENT_ADD = 1;
100 constexpr int32_t DISTRIBUTED_COMPONENT_REMOVE = 2;
101 constexpr int32_t START_PERMISSION = 0;
102 constexpr int32_t CALL_PERMISSION = 1;
103 constexpr int32_t SEND_RESULT_PERMISSION = 2;
104 constexpr int64_t CONTINUATION_TIMEOUT = 20000; // 20s
105 // BundleDistributedManager set timeout to 3s, so we set 1s longer
106 constexpr int64_t CHECK_REMOTE_INSTALL_ABILITY = 40000;
107 constexpr int32_t MAX_TOKEN_NUM = 100000000;
108 constexpr uint32_t MAX_MODULENAME_LEN = 2048;
109 }
110 
111 IMPLEMENT_SINGLE_INSTANCE(DistributedSchedService);
112 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(&DistributedSchedService::GetInstance());
113 
DistributedSchedService()114 DistributedSchedService::DistributedSchedService() : SystemAbility(DISTRIBUTED_SCHED_SA_ID, true)
115 {
116 }
117 
OnStart()118 void DistributedSchedService::OnStart()
119 {
120     if (!Init()) {
121         HILOGE("failed to init DistributedSchedService");
122         return;
123     }
124     FuncContinuationCallback continuationCallback = [this] (int32_t missionId) {
125         HILOGW("continuationCallback timeout.");
126         NotifyContinuationCallbackResult(missionId, CONTINUE_ABILITY_TIMEOUT_ERR);
127     };
128 
129     DmsCallbackTaskInitCallbackFunc freeCallback = [this] (int64_t taskId) {
130         HILOGW("DmsCallbackTaskInitCallbackFunc timeout, taskId:%{public}" PRId64 ".", taskId);
131         NotifyCompleteFreeInstallFromRemote(taskId, AAFwk::FREE_INSTALL_TIMEOUT);
132     };
133     dschedContinuation_ = std::make_shared<DSchedContinuation>();
134     dmsCallbackTask_ = std::make_shared<DmsCallbackTask>();
135     dschedContinuation_->Init(continuationCallback);
136     dmsCallbackTask_->Init(freeCallback);
137     HILOGI("OnStart start service success.");
138     Publish(this);
139 }
140 
OnStop()141 void DistributedSchedService::OnStop()
142 {
143 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
144     DistributedSchedContinueManager::GetInstance().UnInit();
145 #endif
146     HILOGD("begin");
147 }
148 
Dump(int32_t fd,const std::vector<std::u16string> & args)149 int32_t DistributedSchedService::Dump(int32_t fd, const std::vector<std::u16string>& args)
150 {
151     std::vector<std::string> argsInStr8;
152     for (const auto& arg : args) {
153         argsInStr8.emplace_back(Str16ToStr8(arg));
154     }
155     std::string result;
156     DistributedSchedDumper::Dump(argsInStr8, result);
157 
158     if (!SaveStringToFd(fd, result)) {
159         HILOGE("save to fd failed");
160         return DMS_WRITE_FILE_FAILED_ERR;
161     }
162     return ERR_OK;
163 }
164 
DeviceOnlineNotify(const std::string & networkId)165 void DistributedSchedService::DeviceOnlineNotify(const std::string& networkId)
166 {
167     DistributedSchedAdapter::GetInstance().DeviceOnline(networkId);
168 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
169     DistributedSchedMissionManager::GetInstance().DeviceOnlineNotify(networkId);
170 #endif
171 }
172 
DeviceOfflineNotify(const std::string & networkId)173 void DistributedSchedService::DeviceOfflineNotify(const std::string& networkId)
174 {
175     DistributedSchedAdapter::GetInstance().DeviceOffline(networkId);
176 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
177     DistributedSchedMissionManager::GetInstance().DeviceOfflineNotify(networkId);
178 #endif
179 }
180 
Init()181 bool DistributedSchedService::Init()
182 {
183     HILOGD("ready to init.");
184     DnetworkAdapter::GetInstance()->Init();
185     if (!DtbschedmgrDeviceInfoStorage::GetInstance().Init()) {
186         HILOGW("DtbschedmgrDeviceInfoStorage init failed.");
187     }
188 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
189     DistributedSchedMissionManager::GetInstance().Init();
190     DistributedSchedMissionManager::GetInstance().InitDataStorage();
191     DistributedSchedContinueManager::GetInstance().Init();
192 #endif
193     DistributedSchedAdapter::GetInstance().Init();
194     HILOGD("init success.");
195     connectDeathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new ConnectDeathRecipient());
196     callerDeathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new CallerDeathRecipient());
197     callerDeathRecipientForLocalDevice_ = sptr<IRemoteObject::DeathRecipient>(
198         new CallerDeathRecipient(IDistributedSched::CALLER));
199     if (componentChangeHandler_ == nullptr) {
200         auto runner = AppExecFwk::EventRunner::Create("DmsComponentChange");
201         componentChangeHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
202     }
203     return true;
204 }
205 
StartRemoteAbility(const OHOS::AAFwk::Want & want,int32_t callerUid,int32_t requestCode,uint32_t accessToken)206 int32_t DistributedSchedService::StartRemoteAbility(const OHOS::AAFwk::Want& want,
207     int32_t callerUid, int32_t requestCode, uint32_t accessToken)
208 {
209     std::string localDeviceId;
210     std::string deviceId = want.GetElement().GetDeviceID();
211     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, deviceId)) {
212         HILOGE("check deviceId failed");
213         return INVALID_PARAMETERS_ERR;
214     }
215     sptr<IDistributedSched> remoteDms = GetRemoteDms(deviceId);
216     if (remoteDms == nullptr) {
217         HILOGE("get remoteDms failed");
218         return INVALID_PARAMETERS_ERR;
219     }
220     AppExecFwk::AbilityInfo abilityInfo;
221     CallerInfo callerInfo;
222     callerInfo.sourceDeviceId = localDeviceId;
223     callerInfo.uid = callerUid;
224     callerInfo.accessToken = accessToken;
225     if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
226         HILOGE("GetCallerAppIdFromBms failed");
227         return INVALID_PARAMETERS_ERR;
228     }
229     if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
230         HILOGE("GetBundleNameListFromBms failed");
231         return INVALID_PARAMETERS_ERR;
232     }
233     callerInfo.extraInfoJson[DMS_VERSION_ID] = DMS_VERSION;
234     AccountInfo accountInfo;
235     int32_t ret = DistributedSchedPermission::GetInstance().GetAccountInfo(deviceId, callerInfo, accountInfo);
236     if (ret != ERR_OK) {
237         HILOGE("GetAccountInfo failed");
238         return ret;
239     }
240     AAFwk::Want* newWant = const_cast<Want*>(&want);
241     newWant->SetParam(DMS_SRC_NETWORK_ID, localDeviceId);
242     HILOGI("[PerformanceTest] StartRemoteAbility transact begin");
243     int32_t result = remoteDms->StartAbilityFromRemote(*newWant, abilityInfo, requestCode, callerInfo, accountInfo);
244     HILOGI("[PerformanceTest] StartRemoteAbility transact end");
245     return result;
246 }
247 
StartAbilityFromRemote(const OHOS::AAFwk::Want & want,const OHOS::AppExecFwk::AbilityInfo & abilityInfo,int32_t requestCode,const CallerInfo & callerInfo,const AccountInfo & accountInfo)248 int32_t DistributedSchedService::StartAbilityFromRemote(const OHOS::AAFwk::Want& want,
249     const OHOS::AppExecFwk::AbilityInfo& abilityInfo, int32_t requestCode,
250     const CallerInfo& callerInfo, const AccountInfo& accountInfo)
251 {
252     std::string localDeviceId;
253     std::string deviceId = want.GetElement().GetDeviceID();
254     if (!GetLocalDeviceId(localDeviceId) ||
255         !CheckDeviceIdFromRemote(localDeviceId, deviceId, callerInfo.sourceDeviceId)) {
256         HILOGE("check deviceId failed");
257         return INVALID_REMOTE_PARAMETERS_ERR;
258     }
259     int32_t result = CheckTargetPermission(want, callerInfo, accountInfo, START_PERMISSION, true);
260     if (result != ERR_OK) {
261         HILOGE("CheckTargetPermission failed!!");
262         return result;
263     }
264     return StartAbility(want, requestCode);
265 }
266 
SendResultFromRemote(OHOS::AAFwk::Want & want,int32_t requestCode,const CallerInfo & callerInfo,const AccountInfo & accountInfo,int32_t resultCode)267 int32_t DistributedSchedService::SendResultFromRemote(OHOS::AAFwk::Want& want, int32_t requestCode,
268     const CallerInfo& callerInfo, const AccountInfo& accountInfo, int32_t resultCode)
269 {
270     std::string localDeviceId;
271     std::string deviceId = want.GetStringParam(DMS_SRC_NETWORK_ID);
272     want.RemoveParam(DMS_SRC_NETWORK_ID);
273     if (!GetLocalDeviceId(localDeviceId) ||
274         !CheckDeviceIdFromRemote(localDeviceId, deviceId, callerInfo.sourceDeviceId)) {
275         HILOGE("check deviceId failed");
276         return INVALID_REMOTE_PARAMETERS_ERR;
277     }
278     if (want.GetElement().GetBundleName().empty() && want.GetElement().GetAbilityName().empty()) {
279         HILOGW("Remote died abnormal");
280         int32_t missionId = want.GetIntParam(DMS_MISSION_ID, DEFAULT_DMS_MISSION_ID);
281         ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->Connect();
282         if (ret != ERR_OK) {
283             HILOGE("connect ability server failed %{public}d", ret);
284             return ret;
285         }
286         MissionInfo missionInfo;
287         ret = AAFwk::AbilityManagerClient::GetInstance()->GetMissionInfo("", missionId, missionInfo);
288         if (ret != ERR_OK) {
289             HILOGE("SendResult failed %{public}d", ret);
290             return ret;
291         }
292         std::string bundleName = missionInfo.want.GetElement().GetBundleName();
293         std::string abilityName = missionInfo.want.GetElement().GetAbilityName();
294         HILOGD("bundlename: %{public}s, ability is %{public}s", bundleName.c_str(), abilityName.c_str());
295         ElementName element{"", bundleName, abilityName};
296         want.SetElement(element);
297     }
298     int32_t result = CheckTargetPermission(want, callerInfo, accountInfo, SEND_RESULT_PERMISSION, false);
299     if (result != ERR_OK) {
300         HILOGE("CheckTargetPermission failed!!");
301         return result;
302     }
303     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->Connect();
304     if (err != ERR_OK) {
305         HILOGE("connect ability server failed %{public}d", err);
306         return err;
307     }
308     err = AAFwk::AbilityManagerClient::GetInstance()->SendResultToAbility(requestCode, resultCode, want);
309     if (err != ERR_OK) {
310         HILOGE("SendResult failed %{public}d", err);
311     }
312     return err;
313 }
314 
RemoveContinuationTimeout(int32_t missionId)315 void DistributedSchedService::RemoveContinuationTimeout(int32_t missionId)
316 {
317     if (dschedContinuation_ == nullptr) {
318         HILOGE("continuation object null!");
319         return;
320     }
321     dschedContinuation_->RemoveTimeOut(missionId);
322 }
323 
SetContinuationTimeout(int32_t missionId,int32_t timeout)324 void DistributedSchedService::SetContinuationTimeout(int32_t missionId, int32_t timeout)
325 {
326     if (dschedContinuation_ == nullptr) {
327         HILOGE("continuation object null!");
328         return;
329     }
330     dschedContinuation_->SetTimeOut(missionId, timeout);
331 }
332 
GetContinuaitonDevice(int32_t missionId)333 std::string DistributedSchedService::GetContinuaitonDevice(int32_t missionId)
334 {
335     if (dschedContinuation_ == nullptr) {
336         HILOGE("continuation object null!");
337         return "";
338     }
339     return dschedContinuation_->GetTargetDevice(missionId);
340 }
341 
PrecheckContinueLocalMission(const std::string & dstDeviceId,int32_t missionId,const sptr<IRemoteObject> & callback)342 int32_t DistributedSchedService::PrecheckContinueLocalMission(const std::string& dstDeviceId, int32_t missionId,
343     const sptr<IRemoteObject>& callback)
344 {
345     if (dschedContinuation_ == nullptr) {
346         HILOGE("continuation object null!");
347         return INVALID_PARAMETERS_ERR;
348     }
349     if (dschedContinuation_->IsInContinuationProgress(missionId)) {
350         HILOGE("ContinueLocalMission already in progress!");
351         return CONTINUE_ALREADY_IN_PROGRESS;
352     }
353     DmsVersion thresholdDmsVersion = {3, 2, 0};
354     if (DmsVersionManager::IsRemoteDmsVersionLower(dstDeviceId, thresholdDmsVersion)) {
355         HILOGI("remote dms is low version");
356         return ContinueAbilityWithTimeout(dstDeviceId, missionId, callback);
357     }
358     return ERR_OK;
359 }
360 
ContinueLocalMission(const std::string & dstDeviceId,int32_t missionId,const sptr<IRemoteObject> & callback,const OHOS::AAFwk::WantParams & wantParams)361 int32_t DistributedSchedService::ContinueLocalMission(const std::string& dstDeviceId, int32_t missionId,
362     const sptr<IRemoteObject>& callback, const OHOS::AAFwk::WantParams& wantParams)
363 {
364     int32_t result = PrecheckContinueLocalMission(dstDeviceId, missionId, callback);
365     if (result != ERR_OK) {
366         HILOGE("continue local mission precheck fail!");
367         return result;
368     }
369 
370     MissionInfo missionInfo;
371     result = AbilityManagerClient::GetInstance()->GetMissionInfo("", missionId, missionInfo);
372     if (result != ERR_OK) {
373         HILOGE("get missionInfo failed");
374         return NO_MISSION_INFO_FOR_MISSION_ID;
375     }
376     if (missionInfo.continueState != AAFwk::ContinueState::CONTINUESTATE_ACTIVE) {
377         HILOGE("Mission continue state set to INACTIVE. Can't continue. Mission id: %{public}d", missionId);
378         return INVALID_PARAMETERS_ERR;
379     }
380     std::string bundleName = missionInfo.want.GetBundle();
381     missionInfo.want.SetParams(wantParams);
382     bool isFreeInstall = false;
383     DistributedBundleInfo remoteBundleInfo;
384     result = BundleManagerInternal::CheckRemoteBundleInfoForContinuation(dstDeviceId,
385         bundleName, remoteBundleInfo);
386     if (result == ERR_OK) {
387         return ContinueAbilityWithTimeout(dstDeviceId, missionId, callback, remoteBundleInfo.versionCode);
388     }
389     if (result == CONTINUE_REMOTE_UNINSTALLED_UNSUPPORT_FREEINSTALL) {
390         HILOGE("remote not installed and app not support free install");
391         return result;
392     }
393 
394     isFreeInstall = missionInfo.want.GetBoolParam("isFreeInstall", false);
395     if (!isFreeInstall) {
396         HILOGE("remote not installed but support freeInstall, try again with freeInstall flag");
397         return CONTINUE_REMOTE_UNINSTALLED_SUPPORT_FREEINSTALL;
398     }
399 
400     dschedContinuation_->PushCallback(missionId, callback, dstDeviceId, true);
401     SetContinuationTimeout(missionId, CHECK_REMOTE_INSTALL_ABILITY);
402 
403     missionInfo.want.SetDeviceId(dstDeviceId);
404     if (!BundleManagerInternal::CheckIfRemoteCanInstall(missionInfo.want, missionId)) {
405         HILOGE("call CheckIfRemoteCanInstall failed");
406         RemoveContinuationTimeout(missionId);
407         dschedContinuation_->PopCallback(missionId);
408         return INVALID_PARAMETERS_ERR;
409     }
410     return ERR_OK;
411 }
412 
ContinueAbilityWithTimeout(const std::string & dstDeviceId,int32_t missionId,const sptr<IRemoteObject> & callback,uint32_t remoteBundleVersion)413 int32_t DistributedSchedService::ContinueAbilityWithTimeout(const std::string& dstDeviceId, int32_t missionId,
414     const sptr<IRemoteObject>& callback, uint32_t remoteBundleVersion)
415 {
416     dschedContinuation_->PushCallback(missionId, callback, dstDeviceId, false);
417     SetContinuationTimeout(missionId, CONTINUATION_TIMEOUT);
418     int32_t result = AbilityManagerClient::GetInstance()->ContinueAbility(dstDeviceId, missionId, remoteBundleVersion);
419     HILOGI("result: %{public}d!", result);
420     if (result == ERR_INVALID_VALUE) {
421         return MISSION_FOR_CONTINUING_IS_NOT_ALIVE;
422     }
423     return result;
424 }
425 
ContinueRemoteMission(const std::string & srcDeviceId,const std::string & dstDeviceId,int32_t missionId,const sptr<IRemoteObject> & callback,const OHOS::AAFwk::WantParams & wantParams)426 int32_t DistributedSchedService::ContinueRemoteMission(const std::string& srcDeviceId, const std::string& dstDeviceId,
427     int32_t missionId, const sptr<IRemoteObject>& callback, const OHOS::AAFwk::WantParams& wantParams)
428 {
429     sptr<IDistributedSched> remoteDms = GetRemoteDms(srcDeviceId);
430     if (remoteDms == nullptr) {
431         HILOGE("get remote dms null!");
432         return INVALID_REMOTE_PARAMETERS_ERR;
433     }
434     int32_t result = remoteDms->ContinueMission(srcDeviceId, dstDeviceId, missionId, callback, wantParams);
435     HILOGI("ContinueRemoteMission result: %{public}d!", result);
436     return result;
437 }
438 
ContinueRemoteMission(const std::string & srcDeviceId,const std::string & dstDeviceId,const std::string & bundleName,const sptr<IRemoteObject> & callback,const OHOS::AAFwk::WantParams & wantParams)439 int32_t DistributedSchedService::ContinueRemoteMission(const std::string& srcDeviceId, const std::string& dstDeviceId,
440     const std::string& bundleName, const sptr<IRemoteObject>& callback, const OHOS::AAFwk::WantParams& wantParams)
441 {
442     HILOGI("%{public}s. srcDeviceId: %{public}s. dstDeviceId: %{public}s. bundleName: %{public}s.", __func__,
443         DnetworkAdapter::AnonymizeNetworkId(srcDeviceId).c_str(),
444         DnetworkAdapter::AnonymizeNetworkId(dstDeviceId).c_str(), bundleName.c_str());
445     sptr<IDistributedSched> remoteDms = GetRemoteDms(srcDeviceId);
446     if (remoteDms == nullptr) {
447         HILOGE("get remote dms null!");
448         return INVALID_REMOTE_PARAMETERS_ERR;
449     }
450     int32_t result = remoteDms->ContinueMission(srcDeviceId, dstDeviceId, bundleName, callback, wantParams);
451     HILOGI("ContinueRemoteMission result: %{public}d!", result);
452     return result;
453 }
454 
ContinueMission(const std::string & srcDeviceId,const std::string & dstDeviceId,int32_t missionId,const sptr<IRemoteObject> & callback,const OHOS::AAFwk::WantParams & wantParams)455 int32_t DistributedSchedService::ContinueMission(const std::string& srcDeviceId, const std::string& dstDeviceId,
456     int32_t missionId, const sptr<IRemoteObject>& callback, const OHOS::AAFwk::WantParams& wantParams)
457 {
458     if (srcDeviceId.empty() || dstDeviceId.empty() || callback == nullptr) {
459         HILOGE("srcDeviceId or dstDeviceId or callback is null!");
460         return INVALID_PARAMETERS_ERR;
461     }
462     std::string localDevId;
463     if (!GetLocalDeviceId(localDevId)) {
464         HILOGE("get local deviceId failed!");
465         return INVALID_PARAMETERS_ERR;
466     }
467 
468     if (srcDeviceId == localDevId) {
469         if (DtbschedmgrDeviceInfoStorage::GetInstance().GetDeviceInfoById(dstDeviceId) == nullptr) {
470             return INVALID_REMOTE_PARAMETERS_ERR;
471         }
472         return ContinueLocalMission(dstDeviceId, missionId, callback, wantParams);
473     } else if (dstDeviceId == localDevId) {
474         if (DtbschedmgrDeviceInfoStorage::GetInstance().GetDeviceInfoById(srcDeviceId) == nullptr) {
475             return INVALID_REMOTE_PARAMETERS_ERR;
476         }
477         return ContinueRemoteMission(srcDeviceId, dstDeviceId, missionId, callback, wantParams);
478     } else {
479         HILOGE("source or target device must be local!");
480         return OPERATION_DEVICE_NOT_INITIATOR_OR_TARGET;
481     }
482 }
483 
ContinueMission(const std::string & srcDeviceId,const std::string & dstDeviceId,const std::string & bundleName,const sptr<IRemoteObject> & callback,const OHOS::AAFwk::WantParams & wantParams)484 int32_t DistributedSchedService::ContinueMission(const std::string& srcDeviceId, const std::string& dstDeviceId,
485     const std::string& bundleName, const sptr<IRemoteObject>& callback, const OHOS::AAFwk::WantParams& wantParams)
486 {
487     HILOGI("%{public}s. srcDeviceId: %{public}s. dstDeviceId: %{public}s. bundleName: %{public}s.", __func__,
488         DnetworkAdapter::AnonymizeNetworkId(srcDeviceId).c_str(),
489         DnetworkAdapter::AnonymizeNetworkId(dstDeviceId).c_str(), bundleName.c_str());
490     if (srcDeviceId.empty() || dstDeviceId.empty() || callback == nullptr) {
491         HILOGE("srcDeviceId or dstDeviceId or callback is null!");
492         return INVALID_PARAMETERS_ERR;
493     }
494     std::string localDevId;
495     if (!GetLocalDeviceId(localDevId)) {
496         HILOGE("get local deviceId failed!");
497         return INVALID_PARAMETERS_ERR;
498     }
499 
500     if (srcDeviceId == localDevId) {
501         if (DtbschedmgrDeviceInfoStorage::GetInstance().GetDeviceInfoById(dstDeviceId) == nullptr) {
502             return INVALID_REMOTE_PARAMETERS_ERR;
503         }
504         int32_t missionId = 1;
505         #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
506         int32_t ret = DistributedSchedContinueManager::GetInstance().GetMissionId(bundleName, missionId);
507         if (ret != ERR_OK) {
508             HILOGE("get missionId failed");
509             return ret;
510         }
511         #endif
512         return ContinueLocalMission(dstDeviceId, missionId, callback, wantParams);
513     } else if (dstDeviceId == localDevId) {
514         if (DtbschedmgrDeviceInfoStorage::GetInstance().GetDeviceInfoById(srcDeviceId) == nullptr) {
515             return INVALID_REMOTE_PARAMETERS_ERR;
516         }
517         return ContinueRemoteMission(srcDeviceId, dstDeviceId, bundleName, callback, wantParams);
518     } else {
519         HILOGE("source or target device must be local!");
520         return OPERATION_DEVICE_NOT_INITIATOR_OR_TARGET;
521     }
522 }
523 
SetWantForContinuation(AAFwk::Want & newWant,int32_t missionId)524 int32_t DistributedSchedService::SetWantForContinuation(AAFwk::Want& newWant, int32_t missionId)
525 {
526     std::string devId;
527     if (!GetLocalDeviceId(devId)) {
528         HILOGE("StartContinuation get local deviceId failed!");
529         return INVALID_REMOTE_PARAMETERS_ERR;
530     }
531 
532     newWant.SetParam("sessionId", missionId);
533     newWant.SetParam("deviceId", devId);
534     BundleInfo localBundleInfo;
535     if (BundleManagerInternal::GetLocalBundleInfo(newWant.GetBundle(), localBundleInfo) != ERR_OK) {
536         HILOGE("get local bundle info failed");
537         return INVALID_PARAMETERS_ERR;
538     }
539     newWant.SetParam(VERSION_CODE_KEY, static_cast<int32_t>(localBundleInfo.versionCode));
540 
541     bool isPageStackContinue = newWant.GetBoolParam(SUPPORT_CONTINUE_PAGE_STACK_KEY, true);
542     std::string moduleName = newWant.GetStringParam(SUPPORT_CONTINUE_MODULE_NAME_UPDATE_KEY);
543     if (!isPageStackContinue && !moduleName.empty() && moduleName.length() <= MAX_MODULENAME_LEN) {
544         HILOGD("set application moduleName = %{private}s!", moduleName.c_str());
545         OHOS::AppExecFwk::ElementName element = newWant.GetElement();
546         newWant.SetElementName(element.GetDeviceID(), element.GetBundleName(), element.GetAbilityName(), moduleName);
547     }
548     HILOGD("local version = %{public}u!", localBundleInfo.versionCode);
549     return ERR_OK;
550 }
551 
StartContinuation(const OHOS::AAFwk::Want & want,int32_t missionId,int32_t callerUid,int32_t status,uint32_t accessToken)552 int32_t DistributedSchedService::StartContinuation(const OHOS::AAFwk::Want& want, int32_t missionId,
553     int32_t callerUid, int32_t status, uint32_t accessToken)
554 {
555     HILOGD("[PerformanceTest] StartContinuation begin");
556     if (status != ERR_OK) {
557         HILOGE("continuation has been rejected, status: %{public}d", status);
558         NotifyContinuationCallbackResult(missionId, status);
559         return INVALID_REMOTE_PARAMETERS_ERR;
560     }
561     auto flags = want.GetFlags();
562     if ((flags & AAFwk::Want::FLAG_ABILITY_CONTINUATION) == 0) {
563         HILOGE("StartContinuation want continuation flags invalid!");
564         return INVALID_REMOTE_PARAMETERS_ERR;
565     }
566     HILOGD("StartContinuation: devId = %{private}s, bundleName = %{private}s, abilityName = %{private}s",
567         want.GetElement().GetDeviceID().c_str(), want.GetElement().GetBundleName().c_str(),
568         want.GetElement().GetAbilityName().c_str());
569 
570     if (dschedContinuation_ == nullptr) {
571         HILOGE("StartContinuation continuation object null!");
572         return INVALID_REMOTE_PARAMETERS_ERR;
573     }
574     if (!dschedContinuation_->IsInContinuationProgress(missionId)) {
575         dschedContinuation_->SetTimeOut(missionId, CONTINUATION_TIMEOUT);
576     }
577 
578     AAFwk::Want newWant = want;
579     int result = SetWantForContinuation(newWant, missionId);
580     if (result != ERR_OK) {
581         HILOGE("set new want failed");
582         return result;
583     }
584     bool flag = dschedContinuation_->IsFreeInstall(missionId);
585     SetCleanMissionFlag(want, missionId);
586     if (flag) {
587         result = StartRemoteFreeInstall(newWant, callerUid, DEFAULT_REQUEST_CODE, accessToken, nullptr);
588         if (result != ERR_OK) {
589             HILOGE("continue free install failed, result = %{public}d", result);
590             return result;
591         }
592     } else {
593         result = StartRemoteAbility(newWant, callerUid, DEFAULT_REQUEST_CODE, accessToken);
594         if (result != ERR_OK) {
595             HILOGE("continue ability failed, errorCode = %{public}d", result);
596             return result;
597         }
598     }
599 
600     HILOGD("[PerformanceTest] StartContinuation end");
601     return result;
602 }
603 
NotifyCompleteContinuation(const std::u16string & devId,int32_t sessionId,bool isSuccess)604 void DistributedSchedService::NotifyCompleteContinuation(const std::u16string& devId,
605     int32_t sessionId, bool isSuccess)
606 {
607     if (!isSuccess) {
608         HILOGE("NotifyCompleteContinuation failed!");
609     }
610     if (sessionId <= 0) {
611         HILOGE("NotifyCompleteContinuation sessionId invalid!");
612         return;
613     }
614     std::string deviceId = Str16ToStr8(devId);
615     sptr<IDistributedSched> remoteDms = GetRemoteDms(deviceId);
616     if (remoteDms == nullptr) {
617         HILOGE("NotifyCompleteContinuation get remote dms null!");
618         return;
619     }
620     remoteDms->NotifyContinuationResultFromRemote(sessionId, isSuccess);
621 }
622 
NotifyContinuationResultFromRemote(int32_t sessionId,bool isSuccess)623 int32_t DistributedSchedService::NotifyContinuationResultFromRemote(int32_t sessionId, bool isSuccess)
624 {
625     if (sessionId <= 0) {
626         HILOGE("NotifyContinuationResultFromRemote sessionId:%{public}d invalid!", sessionId);
627         return INVALID_REMOTE_PARAMETERS_ERR;
628     }
629 
630     int32_t missionId = sessionId;
631     NotifyContinuationCallbackResult(missionId, isSuccess ? 0 : NOTIFYCOMPLETECONTINUATION_FAILED);
632     return ERR_OK;
633 }
634 
635 #ifdef SUPPORT_DISTRIBUTED_FORM_SHARE
GetFormMgrProxy()636 sptr<IFormMgr> DistributedSchedService::GetFormMgrProxy()
637 {
638     HILOGD("%{public}s begin.", __func__);
639     std::lock_guard<std::mutex> lock(formMgrLock_);
640     if (formMgrProxy_ != nullptr) {
641         HILOGD("get fms proxy success.");
642         return formMgrProxy_;
643     }
644 
645     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
646     if (systemAbilityMgr == nullptr) {
647         HILOGE("system ability manager is nullptr.");
648         return nullptr;
649     }
650 
651     auto remoteObj = systemAbilityMgr->GetSystemAbility(FORM_MGR_SERVICE_ID);
652     if (remoteObj == nullptr) {
653         HILOGE("failed to get form manager service");
654         return nullptr;
655     }
656 
657     formMgrDeathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new FormMgrDeathRecipient());
658     if (formMgrDeathRecipient_ == nullptr) {
659         HILOGE("failed to create FormMgrDeathRecipient!");
660         return nullptr;
661     }
662 
663     if ((remoteObj->IsProxyObject()) && (!remoteObj->AddDeathRecipient(formMgrDeathRecipient_))) {
664         HILOGE("add death recipient to FormMgrService failed.");
665         return nullptr;
666     }
667 
668     formMgrProxy_ = iface_cast<IFormMgr>(remoteObj);
669     return formMgrProxy_;
670 }
671 
ProcessFormMgrDied(const wptr<IRemoteObject> & remote)672 void DistributedSchedService::ProcessFormMgrDied(const wptr<IRemoteObject>& remote)
673 {
674     std::lock_guard<std::mutex> lock(formMgrLock_);
675     if (formMgrProxy_ == nullptr) {
676         return;
677     }
678 
679     auto serviceRemote = formMgrProxy_->AsObject();
680     if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
681         serviceRemote->RemoveDeathRecipient(formMgrDeathRecipient_);
682         formMgrProxy_ = nullptr;
683     }
684 }
685 #endif
686 
NotifyContinuationCallbackResult(int32_t missionId,int32_t resultCode)687 void DistributedSchedService::NotifyContinuationCallbackResult(int32_t missionId, int32_t resultCode)
688 {
689     HILOGD("Continuation result is: %{public}d", resultCode);
690 
691     if (dschedContinuation_ == nullptr) {
692         HILOGE("continuation object null!");
693         return;
694     }
695 
696     int32_t result = 0;
697     if (dschedContinuation_->IsInContinuationProgress(missionId)) {
698         if (resultCode == ERR_OK && dschedContinuation_->IsCleanMission(missionId)) {
699             result = AbilityManagerClient::GetInstance()->CleanMission(missionId);
700             HILOGD("clean mission result:%{public}d", result);
701         }
702         result = dschedContinuation_->NotifyMissionCenterResult(missionId, resultCode);
703     } else {
704         result = AbilityManagerClient::GetInstance()->NotifyContinuationResult(missionId, resultCode);
705         dschedContinuation_->RemoveTimeOut(missionId);
706     }
707     HILOGD("NotifyContinuationCallbackResult result:%{public}d", result);
708 }
709 
RemoteConnectAbilityMappingLocked(const sptr<IRemoteObject> & connect,const std::string & localDeviceId,const std::string & remoteDeviceId,const AppExecFwk::ElementName & element,const CallerInfo & callerInfo,TargetComponent targetComponent)710 void DistributedSchedService::RemoteConnectAbilityMappingLocked(const sptr<IRemoteObject>& connect,
711     const std::string& localDeviceId, const std::string& remoteDeviceId, const AppExecFwk::ElementName& element,
712     const CallerInfo& callerInfo, TargetComponent targetComponent)
713 {
714     if (connect == nullptr) {
715         return;
716     }
717     auto itConnect = distributedConnectAbilityMap_.find(connect);
718     if (itConnect == distributedConnectAbilityMap_.end()) {
719         // add uid's connect number
720         uint32_t number = ++trackingUidMap_[callerInfo.uid];
721         HILOGD("uid %d has %u connection(s), targetComponent:%d", callerInfo.uid, number, targetComponent);
722         // new connect, add death recipient
723         connect->AddDeathRecipient(connectDeathRecipient_);
724         ReportDistributedComponentChange(callerInfo, DISTRIBUTED_COMPONENT_ADD, IDistributedSched::CONNECT,
725             IDistributedSched::CALLER);
726     }
727     auto& sessionsList = distributedConnectAbilityMap_[connect];
728     for (auto& session : sessionsList) {
729         if (remoteDeviceId == session.GetDestinationDeviceId()) {
730             session.AddElement(element);
731             // already added session for remote device
732             return;
733         }
734     }
735     // connect to another remote device, add a new session to list
736     auto& session = sessionsList.emplace_back(localDeviceId, remoteDeviceId, callerInfo, targetComponent);
737     session.AddElement(element);
738     HILOGD("add connection success");
739 }
740 
CheckDistributedConnectLocked(const CallerInfo & callerInfo) const741 int32_t DistributedSchedService::CheckDistributedConnectLocked(const CallerInfo& callerInfo) const
742 {
743     if (callerInfo.uid < 0) {
744         HILOGE("uid %d is invalid", callerInfo.uid);
745         return BIND_ABILITY_UID_INVALID_ERR;
746     }
747     auto it = trackingUidMap_.find(callerInfo.uid);
748     if (it != trackingUidMap_.end() && it->second >= MAX_DISTRIBUTED_CONNECT_NUM) {
749         HILOGE("uid %{public}d connected too much abilities, it maybe leak", callerInfo.uid);
750         return BIND_ABILITY_LEAK_ERR;
751     }
752     return ERR_OK;
753 }
754 
DecreaseConnectLocked(int32_t uid)755 void DistributedSchedService::DecreaseConnectLocked(int32_t uid)
756 {
757     if (uid < 0) {
758         HILOGE("DecreaseConnectLocked invalid uid %{public}d", uid);
759         return;
760     }
761     auto it = trackingUidMap_.find(uid);
762     if (it != trackingUidMap_.end()) {
763         auto& conns = it->second;
764         if (conns > 0) {
765             conns--;
766         }
767         if (conns == 0) {
768             HILOGD("DecreaseConnectLocked uid %{public}d connection(s) is 0", uid);
769             trackingUidMap_.erase(it);
770         }
771     }
772 }
773 
GetUidLocked(const std::list<ConnectAbilitySession> & sessionsList)774 int32_t DistributedSchedService::GetUidLocked(const std::list<ConnectAbilitySession>& sessionsList)
775 {
776     if (!sessionsList.empty()) {
777         return sessionsList.front().GetCallerInfo().uid;
778     }
779     return INVALID_CALLER_UID;
780 }
781 
ConnectRemoteAbility(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,int32_t callerUid,int32_t callerPid,uint32_t accessToken)782 int32_t DistributedSchedService::ConnectRemoteAbility(const OHOS::AAFwk::Want& want,
783     const sptr<IRemoteObject>& connect, int32_t callerUid, int32_t callerPid, uint32_t accessToken)
784 {
785     std::string localDeviceId;
786     std::string remoteDeviceId = want.GetElement().GetDeviceID();
787     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, remoteDeviceId)) {
788         HILOGE("ConnectRemoteAbility check deviceId failed");
789         return INVALID_PARAMETERS_ERR;
790     }
791     CallerInfo callerInfo = { callerUid, callerPid, CALLER_TYPE_HARMONY, localDeviceId };
792     callerInfo.accessToken = accessToken;
793     {
794         std::lock_guard<std::mutex> autoLock(distributedLock_);
795         int32_t checkResult = CheckDistributedConnectLocked(callerInfo);
796         if (checkResult != ERR_OK) {
797             return checkResult;
798         }
799     }
800     if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
801         HILOGE("GetCallerAppIdFromBms failed");
802         return INVALID_PARAMETERS_ERR;
803     }
804     if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
805         HILOGE("GetBundleNameListFromBms failed");
806         return INVALID_PARAMETERS_ERR;
807     }
808     callerInfo.extraInfoJson[DMS_VERSION_ID] = DMS_VERSION;
809     HILOGD("[PerformanceTest] ConnectRemoteAbility begin");
810     int32_t result = TryConnectRemoteAbility(want, connect, callerInfo);
811     if (result != ERR_OK) {
812         HILOGE("ConnectRemoteAbility result is %{public}d", result);
813     }
814     HILOGD("[PerformanceTest] ConnectRemoteAbility end");
815     return result;
816 }
817 
TryConnectRemoteAbility(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,const CallerInfo & callerInfo)818 int32_t DistributedSchedService::TryConnectRemoteAbility(const OHOS::AAFwk::Want& want,
819     const sptr<IRemoteObject>& connect, const CallerInfo& callerInfo)
820 {
821     AppExecFwk::AbilityInfo abilityInfo;
822     AccountInfo accountInfo;
823     std::string remoteDeviceId = want.GetElement().GetDeviceID();
824     sptr<IDistributedSched> remoteDms = GetRemoteDms(remoteDeviceId);
825     if (remoteDms == nullptr || connect == nullptr) {
826         HILOGE("TryConnectRemoteAbility invalid parameters");
827         return INVALID_PARAMETERS_ERR;
828     }
829     int32_t ret = DistributedSchedPermission::GetInstance().GetAccountInfo(remoteDeviceId, callerInfo, accountInfo);
830     if (ret != ERR_OK) {
831         HILOGE("GetAccountInfo failed");
832         return ret;
833     }
834     int32_t retryTimes = BIND_CONNECT_RETRY_TIMES;
835     int32_t result = REMOTE_DEVICE_BIND_ABILITY_ERR;
836     while (retryTimes--) {
837         int64_t start = GetTickCount();
838         HILOGD("[PerformanceTest] ConnectRemoteAbility begin");
839         result = remoteDms->ConnectAbilityFromRemote(want, abilityInfo, connect, callerInfo, accountInfo);
840         HILOGD("[PerformanceTest] ConnectRemoteAbility end");
841         if (result == ERR_OK) {
842             std::lock_guard<std::mutex> autoLock(distributedLock_);
843             RemoteConnectAbilityMappingLocked(connect, callerInfo.sourceDeviceId, remoteDeviceId,
844                 want.GetElement(), callerInfo, TargetComponent::HARMONY_COMPONENT);
845             break;
846         }
847         if (result == INVALID_REMOTE_PARAMETERS_ERR || result == REMOTE_DEVICE_BIND_ABILITY_ERR) {
848             break;
849         }
850         int64_t elapsedTime = GetTickCount() - start;
851         if (elapsedTime > BIND_CONNECT_TIMEOUT) {
852             HILOGW("ConnectRemoteAbility timeout, elapsedTime is %{public}" PRId64 " ms", elapsedTime);
853             break;
854         }
855     }
856     return result;
857 }
858 
ProcessCallerDied(const sptr<IRemoteObject> & connect,int32_t deviceType)859 void DistributedSchedService::ProcessCallerDied(const sptr<IRemoteObject>& connect, int32_t deviceType)
860 {
861     if (connect == nullptr) {
862         HILOGE("ProcessCallerDied connect is null");
863         return;
864     }
865     HILOGI("Caller Died DeviceType : %{public}d", deviceType);
866     if (deviceType == IDistributedSched::CALLER) {
867         HandleLocalCallerDied(connect);
868         return;
869     }
870     sptr<IRemoteObject> callbackWrapper = connect;
871     AppExecFwk::ElementName element;
872     {
873         std::lock_guard<std::mutex> autoLock(calleeLock_);
874         auto itConnect = calleeMap_.find(connect);
875         if (itConnect != calleeMap_.end()) {
876             callbackWrapper = itConnect->second.callbackWrapper;
877             element = itConnect->second.element;
878             ReportDistributedComponentChange(itConnect->second, DISTRIBUTED_COMPONENT_REMOVE,
879                 IDistributedSched::CALL, IDistributedSched::CALLEE);
880             calleeMap_.erase(itConnect);
881         } else {
882             HILOGW("ProcessCallerDied connect not found");
883         }
884     }
885     UnregisterAppStateObserver(callbackWrapper);
886     int32_t result = DistributedSchedAdapter::GetInstance().ReleaseAbility(callbackWrapper, element);
887     if (result != ERR_OK) {
888         HILOGW("ProcessCallerDied failed, error: %{public}d", result);
889     }
890 }
891 
HandleLocalCallerDied(const sptr<IRemoteObject> & connect)892 void DistributedSchedService::HandleLocalCallerDied(const sptr<IRemoteObject>& connect)
893 {
894     {
895         std::lock_guard<std::mutex> autoLock(callerLock_);
896         auto it = callerMap_.find(connect);
897         if (it != callerMap_.end()) {
898             std::list<ConnectAbilitySession> sessionsList = it->second;
899             if (!sessionsList.empty()) {
900                 ReportDistributedComponentChange(sessionsList.front().GetCallerInfo(), DISTRIBUTED_COMPONENT_REMOVE,
901                     IDistributedSched::CALL, IDistributedSched::CALLER);
902             }
903             callerMap_.erase(it);
904             HILOGI("remove connection success");
905         } else {
906             HILOGW("HandleLocalCallerDied connect not found");
907         }
908     }
909     {
910         std::lock_guard<std::mutex> autoLock(callLock_);
911         for (auto iter = callMap_.begin(); iter != callMap_.end(); iter++) {
912             if (iter->first == connect) {
913                 callMap_.erase(iter);
914                 HILOGI("remove callMap_ connect success");
915                 break;
916             }
917         }
918     }
919 }
920 
ProcessCalleeDied(const sptr<IRemoteObject> & connect)921 void DistributedSchedService::ProcessCalleeDied(const sptr<IRemoteObject>& connect)
922 {
923     if (connect == nullptr) {
924         HILOGE("ProcessCalleeDied connect is null");
925         return;
926     }
927     sptr<IRemoteObject> callbackWrapper;
928     {
929         std::lock_guard<std::mutex> autoLock(calleeLock_);
930         auto itConnect = calleeMap_.find(connect);
931         if (itConnect != calleeMap_.end()) {
932             ReportDistributedComponentChange(itConnect->second, DISTRIBUTED_COMPONENT_REMOVE,
933                 IDistributedSched::CALL, IDistributedSched::CALLEE);
934             callbackWrapper = itConnect->second.callbackWrapper;
935             calleeMap_.erase(itConnect);
936         } else {
937             HILOGW("ProcessCalleeDied connect not found");
938             return;
939         }
940     }
941     UnregisterAppStateObserver(callbackWrapper);
942 }
943 
ProcessCallResult(const sptr<IRemoteObject> & calleeConnect,const sptr<IRemoteObject> & callerConnect)944 void DistributedSchedService::ProcessCallResult(const sptr<IRemoteObject>& calleeConnect,
945     const sptr<IRemoteObject>& callerConnect)
946 {
947     sptr<IRemoteObject> token;
948     AbilityManagerClient::GetInstance()->GetAbilityTokenByCalleeObj(calleeConnect, token);
949     if (token == nullptr) {
950         return;
951     }
952     std::lock_guard<std::mutex> autoLock(observerLock_);
953     for (auto iter = observerMap_.begin(); iter != observerMap_.end(); iter++) {
954         if (iter->second.srcConnect == callerConnect) {
955             iter->second.token = token;
956             return;
957         }
958     }
959     HILOGE("observerMap can not find callerConnect");
960 }
961 
TryStartRemoteAbilityByCall(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,const CallerInfo & callerInfo)962 int32_t DistributedSchedService::TryStartRemoteAbilityByCall(const OHOS::AAFwk::Want& want,
963     const sptr<IRemoteObject>& connect, const CallerInfo& callerInfo)
964 {
965     std::string remoteDeviceId = want.GetElement().GetDeviceID();
966     HILOGD("[PerformanceTest] TryStartRemoteAbilityByCall get remote DMS");
967     sptr<IDistributedSched> remoteDms = GetRemoteDms(remoteDeviceId);
968     if (remoteDms == nullptr) {
969         HILOGE("TryStartRemoteAbilityByCall get remote DMS failed, remoteDeviceId : %{public}s",
970             DnetworkAdapter::AnonymizeNetworkId(remoteDeviceId).c_str());
971         return INVALID_PARAMETERS_ERR;
972     }
973     HILOGD("[PerformanceTest] TryStartRemoteAbilityByCall RPC begin");
974     AccountInfo accountInfo;
975     int32_t ret = DistributedSchedPermission::GetInstance().GetAccountInfo(remoteDeviceId, callerInfo, accountInfo);
976     if (ret != ERR_OK) {
977         HILOGE("GetAccountInfo failed");
978         return ret;
979     }
980     AAFwk::Want remoteWant = want;
981     int32_t connectToken = SaveConnectToken(want, connect);
982     remoteWant.SetParam(DMS_CONNECT_TOKEN, connectToken);
983     HILOGD("connectToken is %{public}d", connectToken);
984     int32_t result = remoteDms->StartAbilityByCallFromRemote(remoteWant, connect, callerInfo, accountInfo);
985     HILOGD("[PerformanceTest] TryStartRemoteAbilityByCall RPC end");
986     if (result == ERR_OK) {
987         SaveCallerComponent(want, connect, callerInfo);
988     } else {
989         HILOGE("TryStartRemoteAbilityByCall failed, result : %{public}d", result);
990     }
991     return result;
992 }
993 
SaveCallerComponent(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,const CallerInfo & callerInfo)994 void DistributedSchedService::SaveCallerComponent(const OHOS::AAFwk::Want& want,
995     const sptr<IRemoteObject>& connect, const CallerInfo& callerInfo)
996 {
997     std::lock_guard<std::mutex> autoLock(callerLock_);
998     auto itConnect = callerMap_.find(connect);
999     if (itConnect == callerMap_.end()) {
1000         connect->AddDeathRecipient(callerDeathRecipientForLocalDevice_);
1001         ReportDistributedComponentChange(callerInfo, DISTRIBUTED_COMPONENT_ADD, IDistributedSched::CALL,
1002             IDistributedSched::CALLER);
1003     }
1004     auto& sessionsList = callerMap_[connect];
1005     std::string remoteDeviceId = want.GetElement().GetDeviceID();
1006     for (auto& session : sessionsList) {
1007         if (remoteDeviceId == session.GetDestinationDeviceId()) {
1008             session.AddElement(want.GetElement());
1009             // already added session for remote device
1010             return;
1011         }
1012     }
1013     // connect to another remote device, add a new session to list
1014     auto& session = sessionsList.emplace_back(callerInfo.sourceDeviceId, remoteDeviceId, callerInfo);
1015     session.AddElement(want.GetElement());
1016     HILOGD("add connection success");
1017 }
1018 
RemoveCallerComponent(const sptr<IRemoteObject> & connect)1019 void DistributedSchedService::RemoveCallerComponent(const sptr<IRemoteObject>& connect)
1020 {
1021     {
1022         std::lock_guard<std::mutex> autoLock(callerLock_);
1023         auto it = callerMap_.find(connect);
1024         if (it != callerMap_.end()) {
1025             connect->RemoveDeathRecipient(callerDeathRecipientForLocalDevice_);
1026             std::list<ConnectAbilitySession> sessionsList = it->second;
1027             if (!sessionsList.empty()) {
1028                 ReportDistributedComponentChange(sessionsList.front().GetCallerInfo(), DISTRIBUTED_COMPONENT_REMOVE,
1029                     IDistributedSched::CALL, IDistributedSched::CALLER);
1030             }
1031             callerMap_.erase(it);
1032             HILOGI("remove connection success");
1033         } else {
1034             HILOGW("RemoveCallerComponent connect not found");
1035         }
1036     }
1037     {
1038         std::lock_guard<std::mutex> autoLock(callLock_);
1039         for (auto iter = callMap_.begin(); iter != callMap_.end(); iter++) {
1040             if (iter->first == connect) {
1041                 callMap_.erase(iter);
1042                 HILOGI("remove callMap_ connect success");
1043                 break;
1044             }
1045         }
1046     }
1047 }
1048 
ProcessCalleeOffline(const std::string & deviceId)1049 void DistributedSchedService::ProcessCalleeOffline(const std::string& deviceId)
1050 {
1051     {
1052         std::lock_guard<std::mutex> autoLock(callerLock_);
1053         for (auto iter = callerMap_.begin(); iter != callerMap_.end();) {
1054             std::list<ConnectAbilitySession>& sessionsList = iter->second;
1055             auto itSession = std::find_if(sessionsList.begin(), sessionsList.end(), [&deviceId](const auto& session) {
1056                 return session.GetDestinationDeviceId() == deviceId;
1057             });
1058             CallerInfo callerInfo;
1059             if (itSession != sessionsList.end()) {
1060                 callerInfo = itSession->GetCallerInfo();
1061                 sessionsList.erase(itSession);
1062             }
1063 
1064             if (sessionsList.empty()) {
1065                 if (iter->first != nullptr) {
1066                     iter->first->RemoveDeathRecipient(callerDeathRecipientForLocalDevice_);
1067                 }
1068                 ReportDistributedComponentChange(callerInfo, DISTRIBUTED_COMPONENT_REMOVE,
1069                     IDistributedSched::CALL, IDistributedSched::CALLER);
1070                 callerMap_.erase(iter++);
1071             } else {
1072                 iter++;
1073             }
1074         }
1075     }
1076     {
1077         std::lock_guard<std::mutex> autoLock(callLock_);
1078         for (auto iter = callMap_.begin(); iter != callMap_.end();) {
1079             if (iter->second.remoteDeviceId == deviceId) {
1080                 iter = callMap_.erase(iter);
1081                 HILOGI("remove callMap_ connect success");
1082             } else {
1083                 iter++;
1084             }
1085         }
1086     }
1087 }
1088 
SaveConnectToken(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect)1089 int32_t DistributedSchedService::SaveConnectToken(const OHOS::AAFwk::Want& want, const sptr<IRemoteObject>& connect)
1090 {
1091     int32_t tToken = -1;
1092     {
1093         std::lock_guard<std::mutex> tokenLock(tokenMutex_);
1094         tToken = token_.load();
1095         if (++tToken > MAX_TOKEN_NUM) {
1096             tToken = 1;
1097         }
1098         token_.store(tToken);
1099     }
1100     {
1101         std::lock_guard<std::mutex> autoLock(callLock_);
1102         callMap_[connect] = {tToken, want.GetElement().GetDeviceID()};
1103         HILOGI("add connect success");
1104     }
1105     return tToken;
1106 }
1107 
StartRemoteAbilityByCall(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,int32_t callerUid,int32_t callerPid,uint32_t accessToken)1108 int32_t DistributedSchedService::StartRemoteAbilityByCall(const OHOS::AAFwk::Want& want,
1109     const sptr<IRemoteObject>& connect, int32_t callerUid, int32_t callerPid, uint32_t accessToken)
1110 {
1111     if (connect == nullptr) {
1112         HILOGE("StartRemoteAbilityByCall connect is null");
1113         return INVALID_PARAMETERS_ERR;
1114     }
1115     std::string localDeviceId;
1116     std::string remoteDeviceId = want.GetElement().GetDeviceID();
1117     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, remoteDeviceId)) {
1118         HILOGE("StartRemoteAbilityByCall check deviceId failed");
1119         return INVALID_PARAMETERS_ERR;
1120     }
1121     CallerInfo callerInfo = { callerUid, callerPid };
1122     callerInfo.sourceDeviceId = localDeviceId;
1123     callerInfo.accessToken = accessToken;
1124     if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
1125         HILOGE("GetCallerAppIdFromBms failed");
1126         return INVALID_PARAMETERS_ERR;
1127     }
1128     if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
1129         HILOGE("GetBundleNameListFromBms failed");
1130         return INVALID_PARAMETERS_ERR;
1131     }
1132     callerInfo.extraInfoJson[DMS_VERSION_ID] = DMS_VERSION;
1133     int32_t ret = TryStartRemoteAbilityByCall(want, connect, callerInfo);
1134     if (ret != ERR_OK) {
1135         {
1136             std::lock_guard<std::mutex> autoLock(callLock_);
1137             callMap_.erase(connect);
1138         }
1139         HILOGE("StartRemoteAbilityByCall result is %{public}d", ret);
1140     }
1141     return ret;
1142 }
1143 
ReleaseRemoteAbility(const sptr<IRemoteObject> & connect,const AppExecFwk::ElementName & element)1144 int32_t DistributedSchedService::ReleaseRemoteAbility(const sptr<IRemoteObject>& connect,
1145     const AppExecFwk::ElementName &element)
1146 {
1147     if (connect == nullptr) {
1148         HILOGE("ReleaseRemoteAbility connect is null");
1149         return INVALID_PARAMETERS_ERR;
1150     }
1151     if (element.GetDeviceID().empty()) {
1152         HILOGE("ReleaseRemoteAbility remote deviceId empty");
1153         return INVALID_PARAMETERS_ERR;
1154     }
1155     sptr<IDistributedSched> remoteDms = GetRemoteDms(element.GetDeviceID());
1156     if (remoteDms == nullptr) {
1157         HILOGE("ReleaseRemoteAbility get remote dms failed, devId : %{public}s",
1158             DnetworkAdapter::AnonymizeNetworkId(element.GetDeviceID()).c_str());
1159         return INVALID_PARAMETERS_ERR;
1160     }
1161     CallerInfo callerInfo;
1162     if (!GetLocalDeviceId(callerInfo.sourceDeviceId)) {
1163         HILOGE("ReleaseRemoteAbility get local deviceId failed");
1164         return INVALID_PARAMETERS_ERR;
1165     }
1166     int32_t result = remoteDms->ReleaseAbilityFromRemote(connect, element, callerInfo);
1167     if (result == ERR_OK) {
1168         RemoveCallerComponent(connect);
1169     } else {
1170         HILOGE("ReleaseRemoteAbility result is %{public}d", result);
1171     }
1172     return result;
1173 }
1174 
StartAbilityByCallFromRemote(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,const CallerInfo & callerInfo,const AccountInfo & accountInfo)1175 int32_t DistributedSchedService::StartAbilityByCallFromRemote(const OHOS::AAFwk::Want& want,
1176     const sptr<IRemoteObject>& connect, const CallerInfo& callerInfo, const AccountInfo& accountInfo)
1177 {
1178     HILOGD("[PerformanceTest] DistributedSchedService StartAbilityByCallFromRemote begin");
1179     if (connect == nullptr) {
1180         HILOGE("StartAbilityByCallFromRemote connect is null");
1181         return INVALID_REMOTE_PARAMETERS_ERR;
1182     }
1183     std::string localDeviceId;
1184     std::string destinationDeviceId = want.GetElement().GetDeviceID();
1185     if (!GetLocalDeviceId(localDeviceId) ||
1186         !CheckDeviceIdFromRemote(localDeviceId, destinationDeviceId, callerInfo.sourceDeviceId)) {
1187         HILOGE("StartAbilityByCallFromRemote check deviceId failed");
1188         return INVALID_REMOTE_PARAMETERS_ERR;
1189     }
1190     int32_t result = CheckTargetPermission(want, callerInfo, accountInfo, CALL_PERMISSION, false);
1191     if (result != ERR_OK) {
1192         HILOGE("CheckTargetPermission failed!!");
1193         return result;
1194     }
1195 
1196     sptr<IRemoteObject> callbackWrapper;
1197     {
1198         std::lock_guard<std::mutex> autoLock(calleeLock_);
1199         auto itConnect = calleeMap_.find(connect);
1200         if (itConnect != calleeMap_.end()) {
1201             callbackWrapper = itConnect->second.callbackWrapper;
1202         } else {
1203             callbackWrapper = new AbilityConnectionWrapperStub(connect, localDeviceId);
1204         }
1205     }
1206     int32_t errCode = DistributedSchedAdapter::GetInstance().StartAbilityByCall(want, callbackWrapper, this);
1207     HILOGD("[PerformanceTest] StartAbilityByCallFromRemote end");
1208     if (errCode == ERR_OK) {
1209         {
1210             std::lock_guard<std::mutex> autoLock(calleeLock_);
1211             ConnectInfo connectInfo {callerInfo, callbackWrapper, want.GetElement()};
1212             ReportDistributedComponentChange(connectInfo, DISTRIBUTED_COMPONENT_ADD,
1213                 IDistributedSched::CALL, IDistributedSched::CALLEE);
1214             calleeMap_.emplace(connect, connectInfo);
1215         }
1216         connect->AddDeathRecipient(callerDeathRecipient_);
1217         if (!RegisterAppStateObserver(want, callerInfo, connect, callbackWrapper)) {
1218             HILOGE("RegisterAppStateObserver failed");
1219         }
1220     }
1221     return errCode;
1222 }
1223 
ReleaseAbilityFromRemote(const sptr<IRemoteObject> & connect,const AppExecFwk::ElementName & element,const CallerInfo & callerInfo)1224 int32_t DistributedSchedService::ReleaseAbilityFromRemote(const sptr<IRemoteObject>& connect,
1225     const AppExecFwk::ElementName &element, const CallerInfo& callerInfo)
1226 {
1227     if (connect == nullptr) {
1228         HILOGE("ReleaseAbilityFromRemote connect is null");
1229         return INVALID_REMOTE_PARAMETERS_ERR;
1230     }
1231 
1232     HILOGD("[PerformanceTest] ReleaseAbilityFromRemote begin");
1233     std::string localDeviceId;
1234     if (!GetLocalDeviceId(localDeviceId) || localDeviceId.empty() ||
1235         callerInfo.sourceDeviceId.empty() || localDeviceId == callerInfo.sourceDeviceId) {
1236         HILOGE("ReleaseAbilityFromRemote check deviceId failed");
1237         return INVALID_REMOTE_PARAMETERS_ERR;
1238     }
1239 
1240     sptr<IRemoteObject> callbackWrapper;
1241     {
1242         std::lock_guard<std::mutex> autoLock(calleeLock_);
1243         auto itConnect = calleeMap_.find(connect);
1244         if (itConnect == calleeMap_.end()) {
1245             HILOGE("ReleaseAbilityFromRemote callee not found");
1246             return INVALID_REMOTE_PARAMETERS_ERR;
1247         }
1248         callbackWrapper = itConnect->second.callbackWrapper;
1249         ReportDistributedComponentChange(itConnect->second, DISTRIBUTED_COMPONENT_REMOVE,
1250             IDistributedSched::CALL, IDistributedSched::CALLEE);
1251         calleeMap_.erase(itConnect);
1252         connect->RemoveDeathRecipient(callerDeathRecipient_);
1253     }
1254     UnregisterAppStateObserver(callbackWrapper);
1255     int32_t result = DistributedSchedAdapter::GetInstance().ReleaseAbility(callbackWrapper, element);
1256     HILOGD("[PerformanceTest] ReleaseAbilityFromRemote end");
1257     if (result != ERR_OK) {
1258         HILOGE("ReleaseAbilityFromRemote failed, error: %{public}d", result);
1259     }
1260     return result;
1261 }
1262 
1263 #ifdef SUPPORT_DISTRIBUTED_FORM_SHARE
StartRemoteShareForm(const std::string & remoteDeviceId,const OHOS::AppExecFwk::FormShareInfo & formShareInfo)1264 int32_t DistributedSchedService::StartRemoteShareForm(const std::string& remoteDeviceId,
1265     const OHOS::AppExecFwk::FormShareInfo& formShareInfo)
1266 {
1267     HILOGD("SHAREFORM:: func call");
1268 
1269     if (remoteDeviceId.empty()) {
1270         HILOGE("StartRemoteShareForm input params error");
1271         return INVALID_PARAMETERS_ERR;
1272     }
1273 
1274     sptr<IDistributedSched> remoteDms = GetRemoteDms(remoteDeviceId);
1275     if (remoteDms == nullptr) {
1276         HILOGE("StartRemoteShareForm get remote DMS failed, remoteDeviceId : %{public}s",
1277             DnetworkAdapter::AnonymizeNetworkId(remoteDeviceId).c_str());
1278         return GET_REMOTE_DMS_FAIL;
1279     }
1280     std::string localDeviceId = "";
1281     GetLocalDeviceId(localDeviceId);
1282     OHOS::AppExecFwk::FormShareInfo formShareInfoCopy;
1283     formShareInfoCopy.formId = formShareInfo.formId;
1284     formShareInfoCopy.formName = formShareInfo.formName;
1285     formShareInfoCopy.bundleName = formShareInfo.bundleName;
1286     formShareInfoCopy.moduleName = formShareInfo.moduleName;
1287     formShareInfoCopy.abilityName = formShareInfo.abilityName;
1288     formShareInfoCopy.formTempFlag = formShareInfo.formTempFlag;
1289     formShareInfoCopy.dimensionId = formShareInfo.dimensionId;
1290     formShareInfoCopy.providerShareData = formShareInfo.providerShareData;
1291     formShareInfoCopy.deviceId = localDeviceId;
1292     int32_t result = remoteDms->StartShareFormFromRemote(remoteDeviceId, formShareInfoCopy);
1293     HILOGD("[PerformanceTest] StartRemoteShareForm RPC end");
1294     if (result != ERR_OK) {
1295         HILOGE("StartRemoteShareForm failed, result : %{public}d", result);
1296     }
1297     return result;
1298 }
1299 
StartShareFormFromRemote(const std::string & remoteDeviceId,const OHOS::AppExecFwk::FormShareInfo & formShareInfo)1300 int32_t DistributedSchedService::StartShareFormFromRemote(
1301     const std::string& remoteDeviceId, const OHOS::AppExecFwk::FormShareInfo& formShareInfo)
1302 {
1303     HILOGD("SHAREFORM:: func call begin");
1304     std::string localDeviceId = "";
1305     GetLocalDeviceId(localDeviceId);
1306     if (CheckDeviceId(localDeviceId, remoteDeviceId)) {
1307         HILOGE("localId is %{public}s != %{public}s",
1308             DnetworkAdapter::AnonymizeNetworkId(localDeviceId).c_str(),
1309             DnetworkAdapter::AnonymizeNetworkId(remoteDeviceId).c_str());
1310         return INVALID_REMOTE_PARAMETERS_ERR;
1311     }
1312 
1313     auto formMgr = GetFormMgrProxy();
1314     if (formMgr == nullptr) {
1315         HILOGE("get form mgr proxy failed.");
1316         return NOT_FIND_SERVICE_PROXY;
1317     }
1318 
1319     auto result = formMgr->RecvFormShareInfoFromRemote(formShareInfo);
1320     HILOGD("SHAREFORM:: func call end");
1321     return result;
1322 }
1323 #endif
1324 
GetDistributedComponentList(std::vector<std::string> & distributedComponents)1325 int32_t DistributedSchedService::GetDistributedComponentList(std::vector<std::string>& distributedComponents)
1326 {
1327     GetConnectComponentList(distributedComponents);
1328     GetCallComponentList(distributedComponents);
1329     return ERR_OK;
1330 }
1331 
GetConnectComponentList(std::vector<std::string> & distributedComponents)1332 void DistributedSchedService::GetConnectComponentList(std::vector<std::string>& distributedComponents)
1333 {
1334     {
1335         std::lock_guard<std::mutex> autoLock(distributedLock_);
1336         for (const auto& iter : distributedConnectAbilityMap_) {
1337             if (iter.second.empty()) {
1338                 continue;
1339             }
1340             CallerInfo callerInfo = iter.second.front().GetCallerInfo();
1341             nlohmann::json componentInfoJson;
1342             componentInfoJson[PID_KEY] = callerInfo.pid;
1343             componentInfoJson[UID_KEY] = callerInfo.uid;
1344             componentInfoJson[BUNDLE_NAME_KEY] =
1345                 callerInfo.bundleNames.empty() ? std::string() : callerInfo.bundleNames.front();
1346             componentInfoJson[COMPONENT_TYPE_KEY] = IDistributedSched::CONNECT;
1347             componentInfoJson[DEVICE_TYPE_KEY] = IDistributedSched::CALLER;
1348             std::string componentInfo = componentInfoJson.dump();
1349             distributedComponents.emplace_back(componentInfo);
1350         }
1351     }
1352     {
1353         std::lock_guard<std::mutex> autoLock(connectLock_);
1354         for (const auto& iter : connectAbilityMap_) {
1355             ConnectInfo connectInfo = iter.second;
1356             nlohmann::json componentInfoJson;
1357             componentInfoJson[UID_KEY] = BundleManagerInternal::GetUidFromBms(connectInfo.element.GetBundleName());
1358             componentInfoJson[BUNDLE_NAME_KEY] = connectInfo.element.GetBundleName();
1359             componentInfoJson[COMPONENT_TYPE_KEY] = IDistributedSched::CONNECT;
1360             componentInfoJson[DEVICE_TYPE_KEY] = IDistributedSched::CALLEE;
1361             std::string componentInfo = componentInfoJson.dump();
1362             distributedComponents.emplace_back(componentInfo);
1363         }
1364     }
1365 }
1366 
GetCallComponentList(std::vector<std::string> & distributedComponents)1367 void DistributedSchedService::GetCallComponentList(std::vector<std::string>& distributedComponents)
1368 {
1369     {
1370         std::lock_guard<std::mutex> autoLock(callerLock_);
1371         for (const auto& iter : callerMap_) {
1372             if (iter.second.empty()) {
1373                 continue;
1374             }
1375             CallerInfo callerInfo = iter.second.front().GetCallerInfo();
1376             nlohmann::json componentInfoJson;
1377             componentInfoJson[PID_KEY] = callerInfo.pid;
1378             componentInfoJson[UID_KEY] = callerInfo.uid;
1379             componentInfoJson[BUNDLE_NAME_KEY] =
1380                 callerInfo.bundleNames.empty() ? std::string() : callerInfo.bundleNames.front();
1381             componentInfoJson[COMPONENT_TYPE_KEY] = IDistributedSched::CALL;
1382             componentInfoJson[DEVICE_TYPE_KEY] = IDistributedSched::CALLER;
1383             std::string componentInfo = componentInfoJson.dump();
1384             distributedComponents.emplace_back(componentInfo);
1385         }
1386     }
1387     {
1388         std::lock_guard<std::mutex> autoLock(calleeLock_);
1389         for (const auto& iter : calleeMap_) {
1390             ConnectInfo connectInfo = iter.second;
1391             nlohmann::json componentInfoJson;
1392             componentInfoJson[UID_KEY] = BundleManagerInternal::GetUidFromBms(connectInfo.element.GetBundleName());
1393             componentInfoJson[BUNDLE_NAME_KEY] = connectInfo.element.GetBundleName();
1394             componentInfoJson[COMPONENT_TYPE_KEY] = IDistributedSched::CALL;
1395             componentInfoJson[DEVICE_TYPE_KEY] = IDistributedSched::CALLEE;
1396             std::string componentInfo = componentInfoJson.dump();
1397             distributedComponents.emplace_back(componentInfo);
1398         }
1399     }
1400 }
1401 
ReportDistributedComponentChange(const CallerInfo & callerInfo,int32_t changeType,int32_t componentType,int32_t deviceType)1402 void DistributedSchedService::ReportDistributedComponentChange(const CallerInfo& callerInfo, int32_t changeType,
1403     int32_t componentType, int32_t deviceType)
1404 {
1405 #if defined(EFFICIENCY_MANAGER_ENABLE) || defined(SUPPORT_DISTRIBUTEDCOMPONENT_TO_MEMMGR)
1406     HILOGI("caller report");
1407     auto func = [this, callerInfo, changeType, componentType, deviceType]() {
1408 #ifdef EFFICIENCY_MANAGER_ENABLE
1409         nlohmann::json componentInfoJson;
1410         componentInfoJson[PID_KEY] = callerInfo.pid;
1411         componentInfoJson[UID_KEY] = callerInfo.uid;
1412         componentInfoJson[BUNDLE_NAME_KEY] =
1413             callerInfo.bundleNames.empty() ? std::string() : callerInfo.bundleNames.front();
1414         componentInfoJson[COMPONENT_TYPE_KEY] = componentType;
1415         componentInfoJson[DEVICE_TYPE_KEY] = deviceType;
1416         componentInfoJson[CHANGE_TYPE_KEY] = changeType;
1417         std::string componentInfo = componentInfoJson.dump();
1418         SuspendManager::SuspendManagerClient::GetInstance().ReportStateChangeEvent(
1419             SuspendManager::ReportEventType::DIS_COMP_CHANGE, componentInfo);
1420 #endif
1421 #ifdef SUPPORT_DISTRIBUTEDCOMPONENT_TO_MEMMGR
1422         Memory::MemMgrClient::GetInstance().NotifyDistDevStatus(callerInfo.pid, callerInfo.uid,
1423             callerInfo.bundleNames.empty() ? std::string() : callerInfo.bundleNames.front(),
1424             changeType == DISTRIBUTED_COMPONENT_ADD);
1425 #endif
1426     };
1427     if (componentChangeHandler_ != nullptr) {
1428         componentChangeHandler_->PostTask(func);
1429         return;
1430     }
1431     HILOGE("HandleDistributedComponentChange handler postTask failed");
1432 #endif
1433 }
1434 
ReportDistributedComponentChange(const ConnectInfo & connectInfo,int32_t changeType,int32_t componentType,int32_t deviceType)1435 void DistributedSchedService::ReportDistributedComponentChange(const ConnectInfo& connectInfo, int32_t changeType,
1436     int32_t componentType, int32_t deviceType)
1437 {
1438 #ifdef EFFICIENCY_MANAGER_ENABLE
1439     HILOGI("callee report");
1440     auto func = [this, connectInfo, changeType, componentType, deviceType]() {
1441         nlohmann::json componentInfoJson;
1442         componentInfoJson[UID_KEY] = BundleManagerInternal::GetUidFromBms(connectInfo.element.GetBundleName());
1443         componentInfoJson[BUNDLE_NAME_KEY] = connectInfo.element.GetBundleName();
1444         componentInfoJson[COMPONENT_TYPE_KEY] = componentType;
1445         componentInfoJson[DEVICE_TYPE_KEY] = deviceType;
1446         componentInfoJson[CHANGE_TYPE_KEY] = changeType;
1447         std::string componentInfo = componentInfoJson.dump();
1448         SuspendManager::SuspendManagerClient::GetInstance().ReportStateChangeEvent(
1449             SuspendManager::ReportEventType::DIS_COMP_CHANGE, componentInfo);
1450     };
1451     if (componentChangeHandler_ != nullptr) {
1452         componentChangeHandler_->PostTask(func);
1453         return;
1454     }
1455     HILOGE("HandleDistributedComponentChange handler postTask failed");
1456 #endif
1457 }
1458 
GetRemoteDms(const std::string & remoteDeviceId)1459 sptr<IDistributedSched> DistributedSchedService::GetRemoteDms(const std::string& remoteDeviceId)
1460 {
1461     if (remoteDeviceId.empty()) {
1462         HILOGE("GetRemoteDms remoteDeviceId is empty");
1463         return nullptr;
1464     }
1465     HILOGD("GetRemoteDms connect deviceid is %s", remoteDeviceId.c_str());
1466     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1467     if (samgr == nullptr) {
1468         HILOGE("GetRemoteDms failed to connect to systemAbilityMgr!");
1469         return nullptr;
1470     }
1471     HILOGD("[PerformanceTest] GetRemoteDms begin");
1472     auto object = samgr->CheckSystemAbility(DISTRIBUTED_SCHED_SA_ID, remoteDeviceId);
1473     HILOGD("[PerformanceTest] GetRemoteDms end");
1474     if (object == nullptr) {
1475         HILOGE("GetRemoteDms failed to get remote DistributedSched %{private}s", remoteDeviceId.c_str());
1476         return nullptr;
1477     }
1478     return iface_cast<IDistributedSched>(object);
1479 }
1480 
GetLocalDeviceId(std::string & localDeviceId)1481 bool DistributedSchedService::GetLocalDeviceId(std::string& localDeviceId)
1482 {
1483     if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(localDeviceId)) {
1484         HILOGE("GetLocalDeviceId failed");
1485         return false;
1486     }
1487     return true;
1488 }
1489 
CheckDeviceId(const std::string & localDeviceId,const std::string & remoteDeviceId)1490 bool DistributedSchedService::CheckDeviceId(const std::string& localDeviceId, const std::string& remoteDeviceId)
1491 {
1492     // remoteDeviceId must not same with localDeviceId
1493     if (localDeviceId.empty() || remoteDeviceId.empty() || localDeviceId == remoteDeviceId) {
1494         HILOGE("check deviceId failed");
1495         return false;
1496     }
1497     return true;
1498 }
1499 
CheckDeviceIdFromRemote(const std::string & localDeviceId,const std::string & destinationDeviceId,const std::string & sourceDeviceId)1500 bool DistributedSchedService::CheckDeviceIdFromRemote(const std::string& localDeviceId,
1501     const std::string& destinationDeviceId, const std::string& sourceDeviceId)
1502 {
1503     if (localDeviceId.empty() || destinationDeviceId.empty() || sourceDeviceId.empty()) {
1504         HILOGE("CheckDeviceIdFromRemote failed");
1505         return false;
1506     }
1507     // destinationDeviceId set by remote must be same with localDeviceId
1508     if (localDeviceId != destinationDeviceId) {
1509         HILOGE("destinationDeviceId is not same with localDeviceId");
1510         return false;
1511     }
1512     HILOGD("CheckDeviceIdFromRemote sourceDeviceId %s", sourceDeviceId.c_str());
1513     HILOGD("CheckDeviceIdFromRemote localDeviceId %s", localDeviceId.c_str());
1514     HILOGD("CheckDeviceIdFromRemote destinationDeviceId %s", destinationDeviceId.c_str());
1515 
1516     if (sourceDeviceId == destinationDeviceId || sourceDeviceId == localDeviceId) {
1517         HILOGE("destinationDeviceId is different with localDeviceId and destinationDeviceId");
1518         return false;
1519     }
1520 
1521     if (sourceDeviceId != IPCSkeleton::GetCallingDeviceID()) {
1522         HILOGE("sourceDeviceId is not correct");
1523         return false;
1524     }
1525     return true;
1526 }
1527 
ConnectAbilityFromRemote(const OHOS::AAFwk::Want & want,const AppExecFwk::AbilityInfo & abilityInfo,const sptr<IRemoteObject> & connect,const CallerInfo & callerInfo,const AccountInfo & accountInfo)1528 int32_t DistributedSchedService::ConnectAbilityFromRemote(const OHOS::AAFwk::Want& want,
1529     const AppExecFwk::AbilityInfo& abilityInfo, const sptr<IRemoteObject>& connect,
1530     const CallerInfo& callerInfo, const AccountInfo& accountInfo)
1531 {
1532     HILOGD("[PerformanceTest] DistributedSchedService ConnectAbilityFromRemote begin");
1533     if (connect == nullptr) {
1534         HILOGE("ConnectAbilityFromRemote connect is null");
1535         return INVALID_REMOTE_PARAMETERS_ERR;
1536     }
1537     HILOGD("ConnectAbilityFromRemote uid is %{public}d, pid is %{public}d, AccessTokenID is %{public}u",
1538         callerInfo.uid, callerInfo.pid, callerInfo.accessToken);
1539     std::string localDeviceId;
1540     std::string destinationDeviceId = want.GetElement().GetDeviceID();
1541     if (!GetLocalDeviceId(localDeviceId) ||
1542         !CheckDeviceIdFromRemote(localDeviceId, destinationDeviceId, callerInfo.sourceDeviceId)) {
1543         HILOGE("ConnectAbilityFromRemote check deviceId failed");
1544         return INVALID_REMOTE_PARAMETERS_ERR;
1545     }
1546     int32_t result = CheckTargetPermission(want, callerInfo, accountInfo, START_PERMISSION, true);
1547     if (result != ERR_OK) {
1548         HILOGE("CheckTargetPermission failed!!");
1549         return result;
1550     }
1551 
1552     HILOGD("ConnectAbilityFromRemote callerType is %{public}d", callerInfo.callerType);
1553     sptr<IRemoteObject> callbackWrapper = connect;
1554     std::map<sptr<IRemoteObject>, ConnectInfo>::iterator itConnect;
1555     if (callerInfo.callerType == CALLER_TYPE_HARMONY) {
1556         std::lock_guard<std::mutex> autoLock(connectLock_);
1557         itConnect = connectAbilityMap_.find(connect);
1558         if (itConnect != connectAbilityMap_.end()) {
1559             callbackWrapper = itConnect->second.callbackWrapper;
1560         } else {
1561             callbackWrapper = new AbilityConnectionWrapperStub(connect);
1562         }
1563     }
1564     int32_t errCode = DistributedSchedAdapter::GetInstance().ConnectAbility(want, callbackWrapper, this);
1565     HILOGD("[PerformanceTest] ConnectAbilityFromRemote end");
1566     if (errCode == ERR_OK) {
1567         std::lock_guard<std::mutex> autoLock(connectLock_);
1568         if (itConnect == connectAbilityMap_.end()) {
1569             ConnectInfo connectInfo {callerInfo, callbackWrapper, want.GetElement()};
1570             ReportDistributedComponentChange(connectInfo, DISTRIBUTED_COMPONENT_ADD,
1571                 IDistributedSched::CONNECT, IDistributedSched::CALLEE);
1572             connectAbilityMap_.emplace(connect, connectInfo);
1573         }
1574     }
1575     return errCode;
1576 }
1577 
DisconnectEachRemoteAbilityLocked(const std::string & localDeviceId,const std::string & remoteDeviceId,const sptr<IRemoteObject> & connect)1578 int32_t DistributedSchedService::DisconnectEachRemoteAbilityLocked(const std::string& localDeviceId,
1579     const std::string& remoteDeviceId, const sptr<IRemoteObject>& connect)
1580 {
1581     sptr<IDistributedSched> remoteDms = GetRemoteDms(remoteDeviceId);
1582     if (remoteDms == nullptr) {
1583         HILOGE("DisconnectRemoteAbility get remote dms failed");
1584         return INVALID_PARAMETERS_ERR;
1585     }
1586     int32_t result = remoteDms->DisconnectAbilityFromRemote(connect, IPCSkeleton::GetCallingUid(), localDeviceId);
1587     if (result != ERR_OK) {
1588         HILOGE("DisconnectEachRemoteAbilityLocked result is %{public}d", result);
1589     }
1590     return result;
1591 }
1592 
DisconnectRemoteAbility(const sptr<IRemoteObject> & connect,int32_t callerUid,uint32_t accessToken)1593 int32_t DistributedSchedService::DisconnectRemoteAbility(const sptr<IRemoteObject>& connect, int32_t callerUid,
1594     uint32_t accessToken)
1595 {
1596     if (connect == nullptr) {
1597         HILOGE("DisconnectRemoteAbility connect is null");
1598         return INVALID_PARAMETERS_ERR;
1599     }
1600     std::list<ConnectAbilitySession> sessionsList;
1601     {
1602         std::lock_guard<std::mutex> autoLock(distributedLock_);
1603         auto it = distributedConnectAbilityMap_.find(connect);
1604         if (it != distributedConnectAbilityMap_.end()) {
1605             sessionsList = it->second;
1606             int32_t uid = GetUidLocked(sessionsList);
1607             // also decrease number when erase connect
1608             DecreaseConnectLocked(uid);
1609             connect->RemoveDeathRecipient(connectDeathRecipient_);
1610             if (!sessionsList.empty()) {
1611                 ReportDistributedComponentChange(sessionsList.front().GetCallerInfo(), DISTRIBUTED_COMPONENT_REMOVE,
1612                     IDistributedSched::CONNECT, IDistributedSched::CALLER);
1613             }
1614             distributedConnectAbilityMap_.erase(it);
1615             HILOGI("remove connection success");
1616         }
1617     }
1618     if (!sessionsList.empty()) {
1619         for (const auto& session : sessionsList) {
1620             if (session.GetTargetComponent() == TargetComponent::HARMONY_COMPONENT) {
1621                 DisconnectEachRemoteAbilityLocked(session.GetSourceDeviceId(),
1622                     session.GetDestinationDeviceId(), connect);
1623             } else {
1624                 HILOGW("DisconnectRemoteAbility non-harmony component");
1625             }
1626         }
1627         return ERR_OK;
1628     }
1629     return NO_CONNECT_CALLBACK_ERR;
1630 }
1631 
DisconnectAbilityFromRemote(const sptr<IRemoteObject> & connect,int32_t uid,const std::string & sourceDeviceId)1632 int32_t DistributedSchedService::DisconnectAbilityFromRemote(const sptr<IRemoteObject>& connect,
1633     int32_t uid, const std::string& sourceDeviceId)
1634 {
1635     if (connect == nullptr) {
1636         HILOGE("DisconnectAbilityFromRemote connect is null");
1637         return INVALID_REMOTE_PARAMETERS_ERR;
1638     }
1639 
1640     HILOGD("[PerformanceTest] DisconnectAbilityFromRemote begin");
1641     std::string localDeviceId;
1642     AppExecFwk::AbilityInfo abilityInfo;
1643     if (!GetLocalDeviceId(localDeviceId) || localDeviceId.empty() ||
1644         sourceDeviceId.empty() || localDeviceId == sourceDeviceId) {
1645         HILOGE("DisconnectAbilityFromRemote check deviceId failed");
1646         return INVALID_REMOTE_PARAMETERS_ERR;
1647     }
1648 
1649     sptr<IRemoteObject> callbackWrapper = connect;
1650     {
1651         std::lock_guard<std::mutex> autoLock(connectLock_);
1652         auto itConnect = connectAbilityMap_.find(connect);
1653         if (itConnect != connectAbilityMap_.end()) {
1654             callbackWrapper = itConnect->second.callbackWrapper;
1655             ReportDistributedComponentChange(itConnect->second, DISTRIBUTED_COMPONENT_REMOVE,
1656                 IDistributedSched::CONNECT, IDistributedSched::CALLEE);
1657             connectAbilityMap_.erase(itConnect);
1658         } else {
1659             if (!IPCSkeleton::IsLocalCalling()) {
1660                 HILOGE("DisconnectAbilityFromRemote connect not found");
1661                 return INVALID_REMOTE_PARAMETERS_ERR;
1662             }
1663         }
1664     }
1665     int32_t result = DistributedSchedAdapter::GetInstance().DisconnectAbility(callbackWrapper);
1666     HILOGD("[PerformanceTest] DisconnectAbilityFromRemote end");
1667     return result;
1668 }
1669 
NotifyProcessDiedFromRemote(const CallerInfo & callerInfo)1670 int32_t DistributedSchedService::NotifyProcessDiedFromRemote(const CallerInfo& callerInfo)
1671 {
1672     HILOGI("NotifyProcessDiedFromRemote called");
1673     int32_t errCode = ERR_OK;
1674     {
1675         std::lock_guard<std::mutex> autoLock(connectLock_);
1676         for (auto iter = connectAbilityMap_.begin(); iter != connectAbilityMap_.end();) {
1677             ConnectInfo& connectInfo = iter->second;
1678             if (callerInfo.sourceDeviceId == connectInfo.callerInfo.sourceDeviceId
1679                 && callerInfo.uid == connectInfo.callerInfo.uid
1680                 && callerInfo.pid == connectInfo.callerInfo.pid
1681                 && callerInfo.callerType == connectInfo.callerInfo.callerType) {
1682                 HILOGI("NotifyProcessDiedFromRemote erase connection success");
1683                 int32_t ret = DistributedSchedAdapter::GetInstance().DisconnectAbility(connectInfo.callbackWrapper);
1684                 if (ret != ERR_OK) {
1685                     errCode = ret;
1686                 }
1687                 ReportDistributedComponentChange(connectInfo, DISTRIBUTED_COMPONENT_REMOVE,
1688                     IDistributedSched::CONNECT, IDistributedSched::CALLEE);
1689                 connectAbilityMap_.erase(iter++);
1690             } else {
1691                 iter++;
1692             }
1693         }
1694     }
1695     return errCode;
1696 }
1697 
ProcessDeviceOffline(const std::string & deviceId)1698 void DistributedSchedService::ProcessDeviceOffline(const std::string& deviceId)
1699 {
1700     HILOGI("ProcessDeviceOffline called");
1701     std::string localDeviceId;
1702     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, deviceId)) {
1703         HILOGE("ProcessDeviceOffline check deviceId failed");
1704         return;
1705     }
1706 
1707     {
1708         std::lock_guard<std::mutex> autoLock(distributedLock_);
1709         for (auto iter = distributedConnectAbilityMap_.begin(); iter != distributedConnectAbilityMap_.end();) {
1710             std::list<ConnectAbilitySession>& sessionsList = iter->second;
1711             int32_t uid = GetUidLocked(sessionsList);
1712             auto itSession = std::find_if(sessionsList.begin(), sessionsList.end(), [&deviceId](const auto& session) {
1713                 return session.GetDestinationDeviceId() == deviceId;
1714             });
1715             CallerInfo callerInfo;
1716             if (itSession != sessionsList.end()) {
1717                 NotifyDeviceOfflineToAppLocked(iter->first, *itSession);
1718                 callerInfo = itSession->GetCallerInfo();
1719                 sessionsList.erase(itSession);
1720             }
1721 
1722             if (sessionsList.empty()) {
1723                 if (iter->first != nullptr) {
1724                     iter->first->RemoveDeathRecipient(connectDeathRecipient_);
1725                 }
1726                 DecreaseConnectLocked(uid);
1727                 ReportDistributedComponentChange(callerInfo, DISTRIBUTED_COMPONENT_REMOVE,
1728                     IDistributedSched::CONNECT, IDistributedSched::CALLER);
1729                 distributedConnectAbilityMap_.erase(iter++);
1730             } else {
1731                 iter++;
1732             }
1733         }
1734     }
1735 
1736     {
1737         std::lock_guard<std::mutex> autoLock(connectLock_);
1738         for (auto iter = connectAbilityMap_.begin(); iter != connectAbilityMap_.end();) {
1739             ConnectInfo& connectInfo = iter->second;
1740             if (deviceId == connectInfo.callerInfo.sourceDeviceId) {
1741                 DistributedSchedAdapter::GetInstance().DisconnectAbility(connectInfo.callbackWrapper);
1742                 ReportDistributedComponentChange(connectInfo, DISTRIBUTED_COMPONENT_REMOVE,
1743                     IDistributedSched::CONNECT, IDistributedSched::CALLEE);
1744                 connectAbilityMap_.erase(iter++);
1745                 HILOGI("ProcessDeviceOffline erase connection success");
1746             } else {
1747                 iter++;
1748             }
1749         }
1750     }
1751     ProcessCalleeOffline(deviceId);
1752     ProcessFreeInstallOffline(deviceId);
1753 }
1754 
ProcessFreeInstallOffline(const std::string & deviceId)1755 void DistributedSchedService::ProcessFreeInstallOffline(const std::string& deviceId)
1756 {
1757     if (dmsCallbackTask_ == nullptr) {
1758         HILOGE("callbackTask object null!");
1759         return;
1760     }
1761     dmsCallbackTask_->NotifyDeviceOffline(deviceId);
1762 }
1763 
NotifyDeviceOfflineToAppLocked(const sptr<IRemoteObject> & connect,const ConnectAbilitySession & session)1764 void DistributedSchedService::NotifyDeviceOfflineToAppLocked(const sptr<IRemoteObject>& connect,
1765     const ConnectAbilitySession& session)
1766 {
1767     std::list<AppExecFwk::ElementName> elementsList = session.GetElementsList();
1768     for (const auto& element : elementsList) {
1769         int32_t errCode = NotifyApp(connect, element, DEVICE_OFFLINE_ERR);
1770         if (errCode != ERR_NONE) {
1771             HILOGW("ProcessDeviceOffline notify failed, errCode = %{public}d", errCode);
1772         }
1773     }
1774 }
1775 
NotifyApp(const sptr<IRemoteObject> & connect,const AppExecFwk::ElementName & element,int32_t errCode)1776 int32_t DistributedSchedService::NotifyApp(const sptr<IRemoteObject>& connect,
1777     const AppExecFwk::ElementName& element, int32_t errCode)
1778 {
1779     if (connect == nullptr) {
1780         return OBJECT_NULL;
1781     }
1782     MessageParcel data;
1783     if (!data.WriteInterfaceToken(CONNECTION_CALLBACK_INTERFACE_TOKEN)) {
1784         return ERR_FLATTEN_OBJECT;
1785     }
1786     PARCEL_WRITE_HELPER(data, Parcelable, &element);
1787     PARCEL_WRITE_HELPER(data, Int32, errCode);
1788     MessageParcel reply;
1789     MessageOption option;
1790     return connect->SendRequest(IAbilityConnection::ON_ABILITY_DISCONNECT_DONE, data, reply, option);
1791 }
1792 
ProcessConnectDied(const sptr<IRemoteObject> & connect)1793 void DistributedSchedService::ProcessConnectDied(const sptr<IRemoteObject>& connect)
1794 {
1795     if (connect == nullptr) {
1796         HILOGE("ProcessConnectDied connect is null");
1797         return;
1798     }
1799 
1800     std::list<ProcessDiedNotifyInfo> notifyList;
1801     {
1802         std::lock_guard<std::mutex> autoLock(distributedLock_);
1803         auto it = distributedConnectAbilityMap_.find(connect);
1804         if (it == distributedConnectAbilityMap_.end()) {
1805             return;
1806         }
1807         std::list<ConnectAbilitySession>& connectSessionsList = it->second;
1808         if (connectSessionsList.empty()) {
1809             return;
1810         }
1811         CallerInfo callerInfo = connectSessionsList.front().GetCallerInfo();
1812         std::set<std::string> processedDeviceSet;
1813         // to reduce the number of communications between devices, clean all the died process's connections
1814         for (auto iter = distributedConnectAbilityMap_.begin(); iter != distributedConnectAbilityMap_.end();) {
1815             std::list<ConnectAbilitySession>& sessionsList = iter->second;
1816             if (!sessionsList.empty() && sessionsList.front().IsSameCaller(callerInfo)) {
1817                 for (const auto& session : sessionsList) {
1818                     std::string remoteDeviceId = session.GetDestinationDeviceId();
1819                     TargetComponent targetComponent = session.GetTargetComponent();
1820                     // the same session can connect different types component on the same device
1821                     std::string key = remoteDeviceId + std::to_string(static_cast<int32_t>(targetComponent));
1822                     // just notify one time for same remote device
1823                     auto [_, isSuccess] = processedDeviceSet.emplace(key);
1824                     if (isSuccess) {
1825                         ProcessDiedNotifyInfo notifyInfo = { remoteDeviceId, callerInfo, targetComponent };
1826                         notifyList.push_back(notifyInfo);
1827                     }
1828                 }
1829                 DecreaseConnectLocked(callerInfo.uid);
1830                 if (iter->first != nullptr) {
1831                     iter->first->RemoveDeathRecipient(connectDeathRecipient_);
1832                 }
1833                 ReportDistributedComponentChange(callerInfo, DISTRIBUTED_COMPONENT_REMOVE,
1834                     IDistributedSched::CONNECT, IDistributedSched::CALLER);
1835                 distributedConnectAbilityMap_.erase(iter++);
1836             } else {
1837                 iter++;
1838             }
1839         }
1840     }
1841     NotifyProcessDiedAll(notifyList);
1842 }
1843 
NotifyProcessDiedAll(const std::list<ProcessDiedNotifyInfo> & notifyList)1844 void DistributedSchedService::NotifyProcessDiedAll(const std::list<ProcessDiedNotifyInfo>& notifyList)
1845 {
1846     for (auto it = notifyList.begin(); it != notifyList.end(); ++it) {
1847         NotifyProcessDied(it->remoteDeviceId, it->callerInfo, it->targetComponent);
1848     }
1849 }
1850 
NotifyProcessDied(const std::string & remoteDeviceId,const CallerInfo & callerInfo,TargetComponent targetComponent)1851 void DistributedSchedService::NotifyProcessDied(const std::string& remoteDeviceId,
1852     const CallerInfo& callerInfo, TargetComponent targetComponent)
1853 {
1854     if (targetComponent != TargetComponent::HARMONY_COMPONENT) {
1855         HILOGD("NotifyProcessDied not harmony component, no need to notify");
1856         return;
1857     }
1858 
1859     sptr<IDistributedSched> remoteDms = GetRemoteDms(remoteDeviceId);
1860     if (remoteDms == nullptr) {
1861         HILOGE("NotifyProcessDied get remote dms failed");
1862         return;
1863     }
1864     int32_t result = remoteDms->NotifyProcessDiedFromRemote(callerInfo);
1865     HILOGI("NotifyProcessDied result is %{public}d", result);
1866 }
1867 
ConnectAbilitySession(const std::string & sourceDeviceId,const std::string & destinationDeviceId,const CallerInfo & callerInfo,TargetComponent targetComponent)1868 ConnectAbilitySession::ConnectAbilitySession(const std::string& sourceDeviceId, const std::string& destinationDeviceId,
1869     const CallerInfo& callerInfo, TargetComponent targetComponent)
1870     : sourceDeviceId_(sourceDeviceId),
1871       destinationDeviceId_(destinationDeviceId),
1872       callerInfo_(callerInfo),
1873       targetComponent_(targetComponent)
1874 {
1875 }
1876 
AddElement(const AppExecFwk::ElementName & element)1877 void ConnectAbilitySession::AddElement(const AppExecFwk::ElementName& element)
1878 {
1879     for (const auto& elementName : elementsList_) {
1880         if (elementName == element) {
1881             return;
1882         }
1883     }
1884     elementsList_.emplace_back(element);
1885 }
1886 
IsSameCaller(const CallerInfo & callerInfo)1887 bool ConnectAbilitySession::IsSameCaller(const CallerInfo& callerInfo)
1888 {
1889     return (callerInfo.uid == callerInfo_.uid &&
1890             callerInfo.pid == callerInfo_.pid &&
1891             callerInfo.sourceDeviceId == callerInfo_.sourceDeviceId &&
1892             callerInfo.callerType == callerInfo_.callerType);
1893 }
1894 
DumpConnectInfo(std::string & info)1895 void DistributedSchedService::DumpConnectInfo(std::string& info)
1896 {
1897     std::lock_guard<std::mutex> autoLock(distributedLock_);
1898     info += "connected remote abilities:\n";
1899     if (!distributedConnectAbilityMap_.empty()) {
1900         for (const auto& distributedConnect : distributedConnectAbilityMap_) {
1901             const std::list<ConnectAbilitySession> sessionsList = distributedConnect.second;
1902             DumpSessionsLocked(sessionsList, info);
1903         }
1904     } else {
1905         info += "  <none info>\n";
1906     }
1907 }
1908 
DumpSessionsLocked(const std::list<ConnectAbilitySession> & sessionsList,std::string & info)1909 void DistributedSchedService::DumpSessionsLocked(const std::list<ConnectAbilitySession>& sessionsList,
1910     std::string& info)
1911 {
1912     for (const auto& session : sessionsList) {
1913         info += "  ";
1914         info += "SourceDeviceId: ";
1915         info += session.GetSourceDeviceId();
1916         info += ", ";
1917         info += "DestinationDeviceId: ";
1918         info += session.GetDestinationDeviceId();
1919         info += ", ";
1920         info += "CallerUid: ";
1921         info += std::to_string(session.GetCallerInfo().uid);
1922         info += ", ";
1923         info += "CallerPid: ";
1924         info += std::to_string(session.GetCallerInfo().pid);
1925         info += ", ";
1926         info += "CallerType: ";
1927         info += std::to_string(session.GetCallerInfo().callerType);
1928         DumpElementLocked(session.GetElementsList(), info);
1929         info += "\n";
1930     }
1931 }
1932 
DumpElementLocked(const std::list<AppExecFwk::ElementName> & elementsList,std::string & info)1933 void DistributedSchedService::DumpElementLocked(const std::list<AppExecFwk::ElementName>& elementsList,
1934     std::string& info)
1935 {
1936     for (const auto& element : elementsList) {
1937         info += ", ";
1938         info += "BundleName: ";
1939         info += element.GetBundleName();
1940         info += ", ";
1941         info += "AbilityName: ";
1942         info += element.GetAbilityName();
1943     }
1944 }
1945 
1946 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
GetMissionInfos(const std::string & deviceId,int32_t numMissions,std::vector<MissionInfo> & missionInfos)1947 int32_t DistributedSchedService::GetMissionInfos(const std::string& deviceId, int32_t numMissions,
1948     std::vector<MissionInfo>& missionInfos)
1949 {
1950     return DistributedSchedMissionManager::GetInstance().GetMissionInfos(deviceId, numMissions, missionInfos);
1951 }
1952 
NotifyMissionsChangedFromRemote(const std::vector<DstbMissionInfo> & missionInfos,const CallerInfo & callerInfo)1953 int32_t DistributedSchedService::NotifyMissionsChangedFromRemote(const std::vector<DstbMissionInfo>& missionInfos,
1954     const CallerInfo& callerInfo)
1955 {
1956     return DistributedSchedMissionManager::GetInstance()
1957         .NotifyMissionsChangedFromRemote(callerInfo, missionInfos);
1958 }
1959 
GetRemoteMissionSnapshotInfo(const std::string & networkId,int32_t missionId,std::unique_ptr<MissionSnapshot> & missionSnapshot)1960 int32_t DistributedSchedService::GetRemoteMissionSnapshotInfo(const std::string& networkId, int32_t missionId,
1961     std::unique_ptr<MissionSnapshot>& missionSnapshot)
1962 {
1963     return DistributedSchedMissionManager::GetInstance()
1964         .GetRemoteMissionSnapshotInfo(networkId, missionId, missionSnapshot);
1965 }
1966 
RegisterMissionListener(const std::u16string & devId,const sptr<IRemoteObject> & obj)1967 int32_t DistributedSchedService::RegisterMissionListener(const std::u16string& devId,
1968     const sptr<IRemoteObject>& obj)
1969 {
1970     return DistributedSchedMissionManager::GetInstance().RegisterMissionListener(devId, obj);
1971 }
1972 
RegisterOnListener(const std::string & type,const sptr<IRemoteObject> & obj)1973 int32_t DistributedSchedService::RegisterOnListener(const std::string& type,
1974     const sptr<IRemoteObject>& obj)
1975 {
1976     return DistributedSchedContinueManager::GetInstance().RegisterOnListener(type, obj);
1977 }
1978 
RegisterOffListener(const std::string & type,const sptr<IRemoteObject> & obj)1979 int32_t DistributedSchedService::RegisterOffListener(const std::string& type,
1980     const sptr<IRemoteObject>& obj)
1981 {
1982     return DistributedSchedContinueManager::GetInstance().RegisterOffListener(type, obj);
1983 }
1984 
UnRegisterMissionListener(const std::u16string & devId,const sptr<IRemoteObject> & obj)1985 int32_t DistributedSchedService::UnRegisterMissionListener(const std::u16string& devId,
1986     const sptr<IRemoteObject>& obj)
1987 {
1988     return DistributedSchedMissionManager::GetInstance().UnRegisterMissionListener(devId, obj);
1989 }
1990 
StartSyncRemoteMissions(const std::string & devId,bool fixConflict,int64_t tag)1991 int32_t DistributedSchedService::StartSyncRemoteMissions(const std::string& devId, bool fixConflict, int64_t tag)
1992 {
1993     return DistributedSchedMissionManager::GetInstance().StartSyncRemoteMissions(devId, fixConflict, tag);
1994 }
1995 
StopSyncRemoteMissions(const std::string & devId)1996 int32_t DistributedSchedService::StopSyncRemoteMissions(const std::string& devId)
1997 {
1998     return DistributedSchedMissionManager::GetInstance().StopSyncRemoteMissions(devId, false, true);
1999 }
2000 
StartSyncMissionsFromRemote(const CallerInfo & callerInfo,std::vector<DstbMissionInfo> & missionInfos)2001 int32_t DistributedSchedService::StartSyncMissionsFromRemote(const CallerInfo& callerInfo,
2002     std::vector<DstbMissionInfo>& missionInfos)
2003 {
2004     return DistributedSchedMissionManager::GetInstance().StartSyncMissionsFromRemote(callerInfo, missionInfos);
2005 }
2006 
StopSyncMissionsFromRemote(const CallerInfo & callerInfo)2007 int32_t DistributedSchedService::StopSyncMissionsFromRemote(const CallerInfo& callerInfo)
2008 {
2009     DistributedSchedMissionManager::GetInstance().StopSyncMissionsFromRemote(callerInfo.sourceDeviceId);
2010     return ERR_NONE;
2011 }
2012 
SetMissionContinueState(int32_t missionId,const AAFwk::ContinueState & state)2013 int32_t DistributedSchedService::SetMissionContinueState(int32_t missionId, const AAFwk::ContinueState &state)
2014 {
2015     return DistributedSchedContinueManager::GetInstance().SetMissionContinueState(missionId, state);
2016 }
2017 #endif
2018 
OnRemoteDied(const wptr<IRemoteObject> & remote)2019 void CallerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
2020 {
2021     HILOGI("CallerDeathRecipient OnRemoteDied called");
2022     DistributedSchedAdapter::GetInstance().ProcessCallerDied(remote.promote(), deviceType_);
2023 }
2024 
SetCallerInfo(int32_t callerUid,std::string localDeviceId,uint32_t accessToken,CallerInfo & callerInfo)2025 int32_t DistributedSchedService::SetCallerInfo(
2026     int32_t callerUid, std::string localDeviceId, uint32_t accessToken, CallerInfo& callerInfo)
2027 {
2028     callerInfo.uid = callerUid;
2029     callerInfo.callerType = CALLER_TYPE_HARMONY;
2030     callerInfo.sourceDeviceId = localDeviceId;
2031     callerInfo.accessToken = accessToken;
2032     if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
2033         HILOGE("GetCallerAppIdFromBms failed");
2034         return INVALID_PARAMETERS_ERR;
2035     }
2036     if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
2037         HILOGE("GetBundleNameListFromBms failed");
2038         return INVALID_PARAMETERS_ERR;
2039     }
2040     callerInfo.extraInfoJson[DMS_VERSION_ID] = DMS_VERSION;
2041     return ERR_OK;
2042 }
2043 
StartRemoteFreeInstall(const OHOS::AAFwk::Want & want,int32_t callerUid,int32_t requestCode,uint32_t accessToken,const sptr<IRemoteObject> & callback)2044 int32_t DistributedSchedService::StartRemoteFreeInstall(const OHOS::AAFwk::Want& want, int32_t callerUid,
2045     int32_t requestCode, uint32_t accessToken, const sptr<IRemoteObject>& callback)
2046 {
2047     HILOGI("called");
2048     std::string localDeviceId;
2049     std::string deviceId = want.GetElement().GetDeviceID();
2050     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, deviceId)) {
2051         HILOGE("check deviceId failed");
2052         return INVALID_PARAMETERS_ERR;
2053     }
2054 
2055     sptr<IDistributedSched> remoteDms = GetRemoteDms(deviceId);
2056     if (remoteDms == nullptr) {
2057         HILOGE("get remoteDms failed");
2058         return INVALID_PARAMETERS_ERR;
2059     }
2060 
2061     if (dmsCallbackTask_ == nullptr) {
2062         HILOGE("callbackTask object null!");
2063         return INVALID_REMOTE_PARAMETERS_ERR;
2064     }
2065     int64_t taskId = dmsCallbackTask_->GenerateTaskId();
2066     LaunchType launchType = LaunchType::FREEINSTALL_START;
2067     if (((want.GetFlags() & AAFwk::Want::FLAG_ABILITY_CONTINUATION) != 0)) {
2068         launchType = LaunchType::FREEINSTALL_CONTINUE;
2069     }
2070     if (dmsCallbackTask_->PushCallback(taskId, callback, deviceId, launchType, want) != ERR_OK) {
2071         HILOGE("Push callback failed!");
2072         return INVALID_REMOTE_PARAMETERS_ERR;
2073     }
2074     if (launchType == LaunchType::FREEINSTALL_CONTINUE) {
2075         dmsCallbackTask_->SetContinuationMissionMap(taskId, want.GetIntParam("sessionId", -1));
2076     }
2077 
2078     CallerInfo callerInfo;
2079     if (SetCallerInfo(callerUid, localDeviceId, accessToken, callerInfo) != ERR_OK) {
2080         HILOGE("SetCallerInfo failed");
2081         return INVALID_PARAMETERS_ERR;
2082     }
2083     AccountInfo accountInfo = {};
2084     if ((DistributedSchedPermission::GetInstance().GetAccountInfo(deviceId, callerInfo, accountInfo)) != ERR_OK) {
2085         HILOGE("GetAccountInfo failed");
2086         return INVALID_PARAMETERS_ERR;
2087     }
2088     AAFwk::Want* newWant = const_cast<Want*>(&want);
2089     newWant->SetParam(DMS_SRC_NETWORK_ID, localDeviceId);
2090     FreeInstallInfo info = {.want = *newWant, .requestCode = requestCode, .callerInfo = callerInfo,
2091         .accountInfo = accountInfo};
2092     int32_t result = remoteDms->StartFreeInstallFromRemote(info, taskId);
2093     if (result != ERR_OK) {
2094         HILOGE("result = %{public}d", result);
2095         CallbackTaskItem item = dmsCallbackTask_->PopCallback(taskId);
2096         NotifyFreeInstallResult(item, result);
2097     }
2098     return result;
2099 }
2100 
StartFreeInstallFromRemote(const FreeInstallInfo & info,int64_t taskId)2101 int32_t DistributedSchedService::StartFreeInstallFromRemote(const FreeInstallInfo& info, int64_t taskId)
2102 {
2103     HILOGI("begin taskId : %{public} " PRId64 ". ", taskId);
2104     std::string localDeviceId;
2105     std::string deviceId = info.want.GetElement().GetDeviceID();
2106     if (!GetLocalDeviceId(localDeviceId) ||
2107         !CheckDeviceIdFromRemote(localDeviceId, deviceId, info.callerInfo.sourceDeviceId)) {
2108         HILOGE("check deviceId failed");
2109         return INVALID_REMOTE_PARAMETERS_ERR;
2110     }
2111 
2112     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->Connect();
2113     if (err != ERR_OK) {
2114         HILOGE("connect ability server failed %{public}d", err);
2115         return err;
2116     }
2117     std::vector<int32_t> ids;
2118     err = OsAccountManager::QueryActiveOsAccountIds(ids);
2119     if (err != ERR_OK || ids.empty()) {
2120         HILOGE("QueryActiveOsAccountIds passing param invalid or return error!, err : %{public}d", err);
2121         return INVALID_PARAMETERS_ERR;
2122     }
2123 
2124     sptr<DmsFreeInstallCallback> callback = new DmsFreeInstallCallback(taskId, info);
2125     err = AAFwk::AbilityManagerClient::GetInstance()->FreeInstallAbilityFromRemote(
2126         info.want, callback, ids[0], info.requestCode);
2127     if (err != ERR_OK) {
2128         HILOGE("FreeInstallAbilityFromRemote failed %{public}d", err);
2129     }
2130     return err;
2131 }
2132 
NotifyCompleteFreeInstall(const FreeInstallInfo & info,int64_t taskId,int32_t resultCode)2133 int32_t DistributedSchedService::NotifyCompleteFreeInstall(
2134     const FreeInstallInfo& info, int64_t taskId, int32_t resultCode)
2135 {
2136     HILOGI("taskId = %{public}" PRId64 ".", taskId);
2137     if (taskId <= 0) {
2138         HILOGE("taskId invalid!");
2139         return INVALID_PARAMETERS_ERR;
2140     }
2141     if (resultCode != ERR_OK) {
2142         HILOGE("free install failed, resultCode : %{public}d", resultCode);
2143         return HandleRemoteNotify(info, taskId, resultCode);
2144     }
2145     int32_t result = StartLocalAbility(info, taskId, resultCode);
2146     return HandleRemoteNotify(info, taskId, result);
2147 }
2148 
StartLocalAbility(const FreeInstallInfo & info,int64_t taskId,int32_t resultCode)2149 int32_t DistributedSchedService::StartLocalAbility(const FreeInstallInfo& info, int64_t taskId, int32_t resultCode)
2150 {
2151     std::string localDeviceId;
2152     if (!GetLocalDeviceId(localDeviceId)) {
2153         HILOGE("get local deviceId failed");
2154         return INVALID_REMOTE_PARAMETERS_ERR;
2155     }
2156     int32_t result = CheckTargetPermission(info.want, info.callerInfo, info.accountInfo, START_PERMISSION, true);
2157     if (result != ERR_OK) {
2158         HILOGE("CheckTargetPermission failed!!");
2159         return result;
2160     }
2161 
2162     AAFwk::Want* want = const_cast<Want*>(&info.want);
2163     want->RemoveFlags(OHOS::AAFwk::Want::FLAG_INSTALL_ON_DEMAND);
2164     return StartAbility(*want, info.requestCode);
2165 }
2166 
StartAbility(const OHOS::AAFwk::Want & want,int32_t requestCode)2167 int32_t DistributedSchedService::StartAbility(const OHOS::AAFwk::Want& want, int32_t requestCode)
2168 {
2169     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->Connect();
2170     if (err != ERR_OK) {
2171         HILOGE("connect ability server failed %{public}d", err);
2172         return err;
2173     }
2174     std::vector<int> ids;
2175     ErrCode ret = OsAccountManager::QueryActiveOsAccountIds(ids);
2176     if (ret != ERR_OK || ids.empty()) {
2177         return INVALID_PARAMETERS_ERR;
2178     }
2179     if (want.GetBoolParam(Want::PARAM_RESV_FOR_RESULT, false)) {
2180         HILOGI("StartAbilityForResult start");
2181         sptr<IRemoteObject> dmsTokenCallback = new DmsTokenCallback();
2182         err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, dmsTokenCallback, requestCode, ids[0]);
2183     } else {
2184         HILOGI("StartAbility start");
2185         err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, requestCode, ids[0]);
2186     }
2187     if (err != ERR_OK) {
2188         HILOGE("StartAbility failed %{public}d", err);
2189     }
2190     return err;
2191 }
2192 
HandleRemoteNotify(const FreeInstallInfo & info,int64_t taskId,int32_t resultCode)2193 int32_t DistributedSchedService::HandleRemoteNotify(const FreeInstallInfo& info, int64_t taskId, int32_t resultCode)
2194 {
2195     HILOGI("begin taskId = %{public}" PRId64 ", resultCode = %{public}d", taskId, resultCode);
2196     sptr<IDistributedSched> remoteDms = GetRemoteDms(info.callerInfo.sourceDeviceId);
2197     if (remoteDms == nullptr) {
2198         HILOGE("get remote dms null!");
2199         return INVALID_PARAMETERS_ERR;
2200     }
2201     if (taskId <= 0) {
2202         HILOGE("taskId invalid!");
2203         return INVALID_PARAMETERS_ERR;
2204     }
2205     return remoteDms->NotifyCompleteFreeInstallFromRemote(taskId, resultCode);
2206 }
2207 
NotifyCompleteFreeInstallFromRemote(int64_t taskId,int32_t resultCode)2208 int32_t DistributedSchedService::NotifyCompleteFreeInstallFromRemote(int64_t taskId, int32_t resultCode)
2209 {
2210     HILOGI("begin taskId = %{public}" PRId64 ", resultCode = %{public}d", taskId, resultCode);
2211     if (dmsCallbackTask_ == nullptr || dschedContinuation_ == nullptr) {
2212         HILOGE("callbackTask object null!");
2213         return INVALID_REMOTE_PARAMETERS_ERR;
2214     }
2215 
2216     LaunchType launchType = dmsCallbackTask_->GetLaunchType(taskId);
2217     CallbackTaskItem item = dmsCallbackTask_->PopCallback(taskId);
2218     if (launchType == LaunchType::FREEINSTALL_START) {
2219         return NotifyFreeInstallResult(item, resultCode);
2220     }
2221 
2222     if (resultCode == ERR_OK) {
2223         HILOGD("continue free install success, waiting for continue result callback.");
2224         dmsCallbackTask_->PopContinuationMissionMap(taskId);
2225         return ERR_OK;
2226     }
2227 
2228     int32_t missionId = dmsCallbackTask_->GetContinuaionMissionId(taskId);
2229     NotifyContinuationCallbackResult(missionId, CONTINUE_FREE_INSTALL_FAILED);
2230     dmsCallbackTask_->PopContinuationMissionMap(taskId);
2231     return ERR_OK;
2232 }
2233 
NotifyFreeInstallResult(const CallbackTaskItem item,int32_t resultCode)2234 int32_t DistributedSchedService::NotifyFreeInstallResult(const CallbackTaskItem item, int32_t resultCode)
2235 {
2236     HILOGI("taskId : %{public} " PRId64 ". ", item.taskId);
2237     if (item.callback == nullptr) {
2238         HILOGE("item callback null!");
2239         return INVALID_REMOTE_PARAMETERS_ERR;
2240     }
2241     MessageParcel data;
2242     if (!data.WriteInterfaceToken(ATOMIC_SERVICE_STATUS_CALLBACK_TOKEN)) {
2243         HILOGE("Write interface token failed.");
2244         return INVALID_REMOTE_PARAMETERS_ERR;
2245     }
2246 
2247     if (!data.WriteInt32(resultCode)) {
2248         HILOGE("Write resultCode error.");
2249         return INVALID_REMOTE_PARAMETERS_ERR;
2250     }
2251 
2252     if (!data.WriteParcelable(&item.want)) {
2253         HILOGE("Write want error.");
2254         return INVALID_REMOTE_PARAMETERS_ERR;
2255     }
2256 
2257     int32_t userId = 0;
2258     if (!data.WriteInt32(userId)) {
2259         HILOGE("Write userId error.");
2260         return INVALID_REMOTE_PARAMETERS_ERR;
2261     }
2262 
2263     MessageParcel reply;
2264     MessageOption option;
2265     return item.callback->SendRequest(IASS_CALLBACK_ON_REMOTE_FREE_INSTALL_DONE, data, reply, option);
2266 }
2267 
RegisterAppStateObserver(const OHOS::AAFwk::Want & want,const CallerInfo & callerInfo,const sptr<IRemoteObject> & srcConnect,const sptr<IRemoteObject> & callbackWrapper)2268 bool DistributedSchedService::RegisterAppStateObserver(const OHOS::AAFwk::Want& want, const CallerInfo& callerInfo,
2269     const sptr<IRemoteObject>& srcConnect, const sptr<IRemoteObject>& callbackWrapper)
2270 {
2271     HILOGD("register app state observer called");
2272     int32_t connectToken = want.GetIntParam(DMS_CONNECT_TOKEN, DEFAULT_DMS_CONNECT_TOKEN);
2273     HILOGD("Get connectToken = %{private}d", connectToken);
2274     if (connectToken == DEFAULT_DMS_CONNECT_TOKEN) {
2275         return false;
2276     }
2277     sptr<AppExecFwk::IAppMgr> appObject = GetAppManager();
2278     if (appObject == nullptr) {
2279         HILOGE("failed to get app manager service");
2280         return false;
2281     }
2282     sptr<AppStateObserver> appStateObserver;
2283     std::string bundleName = want.GetElement().GetBundleName();
2284     {
2285         std::lock_guard<std::mutex> autoLock(registerMutex_);
2286         if (!bundleNameMap_.count(bundleName)) {
2287             std::vector<std::string> bundleNameList = {bundleName};
2288             appStateObserver = sptr<AppStateObserver>(new (std::nothrow) AppStateObserver());
2289             bundleNameMap_[bundleName] = appStateObserver;
2290             int ret = appObject->RegisterApplicationStateObserver(appStateObserver, bundleNameList);
2291             if (ret != ERR_OK) {
2292                 HILOGE("failed to register application state observer, ret = %{public}d", ret);
2293                 return false;
2294             }
2295         }
2296         appStateObserver = bundleNameMap_[bundleName];
2297     }
2298     HILOGI("register application state observer success");
2299     {
2300         std::lock_guard<std::mutex> autoLock(observerLock_);
2301         Want* newWant = const_cast<Want*>(&want);
2302         newWant->RemoveParam(DMS_MISSION_ID);
2303         newWant->RemoveParam(DMS_CONNECT_TOKEN);
2304         observerMap_[callbackWrapper] = {appStateObserver, callerInfo.sourceDeviceId, connectToken,
2305             want.GetElement().GetBundleName(), want.GetElement().GetAbilityName(), srcConnect};
2306         HILOGI("add observerMap_ success");
2307     }
2308     return true;
2309 }
2310 
UnregisterAppStateObserver(const sptr<IRemoteObject> & callbackWrapper)2311 void DistributedSchedService::UnregisterAppStateObserver(const sptr<IRemoteObject>& callbackWrapper)
2312 {
2313     HILOGD("unregister app state observer called");
2314     if (callbackWrapper == nullptr) {
2315         HILOGD("callbackWrapper is nullptr");
2316         return;
2317     }
2318     bool unRegisterFlag = true;
2319     std::string bundleName;
2320     sptr<AppStateObserver> appStateObserver;
2321     {
2322         std::lock_guard<std::mutex> autoLock(observerLock_);
2323         auto it = observerMap_.find(callbackWrapper);
2324         if (it == observerMap_.end()) {
2325             HILOGE("state observer not found");
2326             return;
2327         }
2328         appStateObserver = it->second.appStateObserver;
2329         bundleName = it->second.dstBundleName;
2330         observerMap_.erase(it);
2331         for (auto iter = observerMap_.begin(); iter != observerMap_.end(); iter++) {
2332             if (iter->second.dstBundleName == bundleName) {
2333                 unRegisterFlag = false;
2334                 break;
2335             }
2336         }
2337         HILOGI("remove app state observer success");
2338     }
2339     if (unRegisterFlag) {
2340         {
2341             std::lock_guard<std::mutex> autoLock(registerMutex_);
2342             bundleNameMap_.erase(bundleName);
2343         }
2344         sptr<AppExecFwk::IAppMgr> appObject = GetAppManager();
2345         if (appObject == nullptr) {
2346             HILOGE("failed to get app manager service");
2347             return;
2348         }
2349         int ret = appObject->UnregisterApplicationStateObserver(appStateObserver);
2350         if (ret != ERR_OK) {
2351             HILOGE("failed to unregister application state observer, ret = %{public}d", ret);
2352             return;
2353         }
2354     }
2355     HILOGI("unregister application state observer success");
2356 }
2357 
GetAppManager()2358 sptr<AppExecFwk::IAppMgr> DistributedSchedService::GetAppManager()
2359 {
2360     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
2361     if (samgr == nullptr) {
2362         HILOGE("system ability manager is nullptr.");
2363         return nullptr;
2364     }
2365 
2366     sptr<AppExecFwk::IAppMgr> appObject =
2367         iface_cast<AppExecFwk::IAppMgr>(samgr->GetSystemAbility(APP_MGR_SERVICE_ID));
2368     if (appObject == nullptr) {
2369         HILOGE("failed to get app manager service");
2370         return nullptr;
2371     }
2372     return appObject;
2373 }
2374 
NotifyStateChanged(int32_t abilityState,AppExecFwk::ElementName & element,const sptr<IRemoteObject> & token)2375 int32_t DistributedSchedService::NotifyStateChanged(int32_t abilityState, AppExecFwk::ElementName& element,
2376     const sptr<IRemoteObject>& token)
2377 {
2378     std::string srcDeviceId = "";
2379     int32_t connectToken = 0;
2380     {
2381         std::lock_guard<std::mutex> autoLock(observerLock_);
2382         for (auto iter = observerMap_.begin(); iter != observerMap_.end(); iter++) {
2383             if (iter->second.dstBundleName == element.GetBundleName() &&
2384                 iter->second.dstAbilityName == element.GetAbilityName() && token == iter->second.token) {
2385                 srcDeviceId = iter->second.srcDeviceId;
2386                 connectToken = iter->second.connectToken;
2387                 HILOGD("get srcDeviceId and missionId success");
2388                 break;
2389             }
2390         }
2391     }
2392     HILOGD("Get connectToken = %{private}d", connectToken);
2393     std::string localDeviceId;
2394     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, srcDeviceId)) {
2395         HILOGE("check deviceId failed");
2396         return INVALID_PARAMETERS_ERR;
2397     }
2398     sptr<IDistributedSched> remoteDms = GetRemoteDms(srcDeviceId);
2399     if (remoteDms == nullptr) {
2400         HILOGE("get remoteDms failed");
2401         return INVALID_PARAMETERS_ERR;
2402     }
2403     element.SetDeviceID(localDeviceId);
2404     return remoteDms->NotifyStateChangedFromRemote(abilityState, connectToken, element);
2405 }
2406 
NotifyStateChangedFromRemote(int32_t abilityState,int32_t connectToken,const AppExecFwk::ElementName & element)2407 int32_t DistributedSchedService::NotifyStateChangedFromRemote(int32_t abilityState, int32_t connectToken,
2408     const AppExecFwk::ElementName& element)
2409 {
2410     HILOGD("Get connectToken = %{private}d", connectToken);
2411     sptr<IRemoteObject> connect;
2412     {
2413         std::lock_guard<std::mutex> autoLock(callLock_);
2414         for (auto iter = callMap_.begin(); iter != callMap_.end(); iter++) {
2415             if (iter->second.connectToken == connectToken) {
2416                 connect = iter->first;
2417                 break;
2418             }
2419         }
2420         HILOGD("get connect success");
2421     }
2422     if (connect == nullptr) {
2423         HILOGE("NotifyStateChangedFromRemote connect is null");
2424         return INVALID_PARAMETERS_ERR;
2425     }
2426     MessageParcel data;
2427     if (!data.WriteInterfaceToken(CONNECTION_CALLBACK_INTERFACE_TOKEN)) {
2428         HILOGE("Write interface token failed.");
2429         return INVALID_PARAMETERS_ERR;
2430     }
2431     PARCEL_WRITE_HELPER(data, Parcelable, &element);
2432     PARCEL_WRITE_HELPER(data, Int32, abilityState);
2433     MessageParcel reply;
2434     MessageOption option(MessageOption::TF_ASYNC);
2435     HILOGD("ON_REMOTE_STATE_CHANGED start");
2436     int32_t result = connect->SendRequest(IAbilityConnection::ON_REMOTE_STATE_CHANGED, data, reply, option);
2437     HILOGD("ON_REMOTE_STATE_CHANGED end, %{public}d", result);
2438     return ERR_OK;
2439 }
2440 
CheckTargetPermission(const OHOS::AAFwk::Want & want,const CallerInfo & callerInfo,const AccountInfo & accountInfo,int32_t flag,bool needQueryExtension)2441 int32_t DistributedSchedService::CheckTargetPermission(const OHOS::AAFwk::Want& want,
2442     const CallerInfo& callerInfo, const AccountInfo& accountInfo, int32_t flag, bool needQueryExtension)
2443 {
2444     DistributedSchedPermission& permissionInstance = DistributedSchedPermission::GetInstance();
2445     AppExecFwk::AbilityInfo targetAbility;
2446     bool result = permissionInstance.GetTargetAbility(want, targetAbility, needQueryExtension);
2447     if (!result) {
2448         HILOGE("GetTargetAbility can not find the target ability");
2449         return INVALID_PARAMETERS_ERR;
2450     }
2451     HILOGD("target ability info bundleName:%{public}s abilityName:%{public}s visible:%{public}d",
2452         targetAbility.bundleName.c_str(), targetAbility.name.c_str(), targetAbility.visible);
2453     HILOGD("callerType:%{public}d accountType:%{public}d callerUid:%{public}d AccessTokenID:%{public}u",
2454         callerInfo.callerType, accountInfo.accountType, callerInfo.uid, callerInfo.accessToken);
2455     if (flag == START_PERMISSION) {
2456         HILOGD("start CheckStartPermission");
2457         return permissionInstance.CheckStartPermission(want, callerInfo, accountInfo, targetAbility);
2458     } else if (flag == CALL_PERMISSION) {
2459         HILOGD("start CheckGetCallerPermission");
2460         return permissionInstance.CheckGetCallerPermission(want, callerInfo, accountInfo, targetAbility);
2461     } else if (flag == SEND_RESULT_PERMISSION) {
2462         HILOGD("start CheckSendResultPermission");
2463         return permissionInstance.CheckSendResultPermission(want, callerInfo, accountInfo, targetAbility);
2464     }
2465     HILOGE("CheckTargetPermission denied!!");
2466     return DMS_PERMISSION_DENIED;
2467 }
2468 
StopRemoteExtensionAbility(const OHOS::AAFwk::Want & want,int32_t callerUid,uint32_t accessToken,int32_t extensionType)2469 int32_t DistributedSchedService::StopRemoteExtensionAbility(const OHOS::AAFwk::Want& want, int32_t callerUid,
2470     uint32_t accessToken, int32_t extensionType)
2471 {
2472     std::string localDeviceId;
2473     std::string deviceId = want.GetDeviceId();
2474     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, deviceId)) {
2475         HILOGE("CheckDeviceId failed");
2476         return INVALID_PARAMETERS_ERR;
2477     }
2478     sptr<IDistributedSched> remoteDms = GetRemoteDms(deviceId);
2479     if (remoteDms == nullptr) {
2480         HILOGE("GetRemoteDms failed");
2481         return INVALID_PARAMETERS_ERR;
2482     }
2483     CallerInfo callerInfo;
2484     callerInfo.sourceDeviceId = localDeviceId;
2485     callerInfo.uid = callerUid;
2486     callerInfo.accessToken = accessToken;
2487     if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
2488         HILOGE("GetCallerAppIdFromBms failed");
2489         return INVALID_PARAMETERS_ERR;
2490     }
2491     if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
2492         HILOGE("GetBundleNameListFromBms failed");
2493         return INVALID_PARAMETERS_ERR;
2494     }
2495     AccountInfo accountInfo = {};
2496     if ((DistributedSchedPermission::GetInstance().GetAccountInfo(deviceId, callerInfo, accountInfo)) != ERR_OK) {
2497         HILOGE("GetAccountInfo failed");
2498         return INVALID_PARAMETERS_ERR;
2499     }
2500     AAFwk::Want remoteWant = want;
2501     remoteWant.SetParam(DMS_SRC_NETWORK_ID, localDeviceId);
2502     return remoteDms->StopExtensionAbilityFromRemote(remoteWant, callerInfo, accountInfo, extensionType);
2503 }
2504 
StopExtensionAbilityFromRemote(const OHOS::AAFwk::Want & remoteWant,const CallerInfo & callerInfo,const AccountInfo & accountInfo,int32_t extensionType)2505 int32_t DistributedSchedService::StopExtensionAbilityFromRemote(const OHOS::AAFwk::Want& remoteWant,
2506     const CallerInfo& callerInfo, const AccountInfo& accountInfo, int32_t extensionType)
2507 {
2508     std::string localDeviceId;
2509     std::string destinationDeviceId = remoteWant.GetElement().GetDeviceID();
2510     if (!GetLocalDeviceId(localDeviceId) ||
2511         !CheckDeviceIdFromRemote(localDeviceId, destinationDeviceId, callerInfo.sourceDeviceId)) {
2512         HILOGE("check deviceId failed");
2513         return INVALID_REMOTE_PARAMETERS_ERR;
2514     }
2515 
2516     int32_t permissionValid = CheckTargetPermission(remoteWant, callerInfo, accountInfo, START_PERMISSION, true);
2517     if (permissionValid != ERR_OK) {
2518         HILOGE("CheckTargetPermission failed!!");
2519         return DMS_PERMISSION_DENIED;
2520     }
2521     Want want = remoteWant;
2522     want.RemoveParam(DMS_SRC_NETWORK_ID);
2523     sptr<IRemoteObject> callerToken = new DmsTokenCallback();
2524 
2525     std::vector<int> ids;
2526     ErrCode ret = OsAccountManager::QueryActiveOsAccountIds(ids);
2527     if (ret != ERR_OK || ids.empty()) {
2528         HILOGE("QueryActiveOsAccountIds failed!!");
2529         return INVALID_PARAMETERS_ERR;
2530     }
2531 
2532     return AAFwk::AbilityManagerClient::GetInstance()->StopExtensionAbility(
2533         want, callerToken, ids[0], static_cast<AppExecFwk::ExtensionAbilityType>(extensionType));
2534 }
2535 
SetCleanMissionFlag(const OHOS::AAFwk::Want & want,int32_t missionId)2536 void DistributedSchedService::SetCleanMissionFlag(const OHOS::AAFwk::Want& want, int32_t missionId)
2537 {
2538     auto value =  want.GetParams().GetParam(SUPPORT_CONTINUE_SOURCE_EXIT_KEY);
2539     IBoolean *ao = IBoolean::Query(value);
2540     bool isCleanMission = true;
2541     if (ao != nullptr) {
2542         isCleanMission = AAFwk::Boolean::Unbox(ao);
2543     }
2544     dschedContinuation_->SetCleanMissionFlag(missionId, isCleanMission);
2545 }
2546 } // namespace DistributedSchedule
2547 } // namespace OHOS