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