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