1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "distributed_sched_service.h"
17 
18 #include <algorithm>
19 #include <cinttypes>
20 #include <unistd.h>
21 
22 #include "ability_manager_client.h"
23 #include "ability_manager_errors.h"
24 #include "bool_wrapper.h"
25 #include "datetime_ex.h"
26 #include "element_name.h"
27 #include "file_ex.h"
28 #include "ipc_skeleton.h"
29 #include "iservice_registry.h"
30 #include "os_account_manager.h"
31 #include "parameters.h"
32 #include "string_ex.h"
33 #include "system_ability_definition.h"
34 #ifdef SUPPORT_DISTRIBUTEDCOMPONENT_TO_MEMMGR
35 #include "mem_mgr_client.h"
36 #endif
37 #ifdef EFFICIENCY_MANAGER_ENABLE
38 #include "res_type.h"
39 #include "res_sched_client.h"
40 #endif
41 
42 #include "ability_connection_wrapper_stub.h"
43 #include "adapter/dnetwork_adapter.h"
44 #include "bundle/bundle_manager_internal.h"
45 #include "connect_death_recipient.h"
46 #include "datashare_manager.h"
47 #include "dfx/distributed_radar.h"
48 #include "dfx/distributed_sched_dumper.h"
49 #include "dfx/distributed_ue.h"
50 #include "dfx/dms_continue_time_dumper.h"
51 #include "distributed_sched_adapter.h"
52 #include "distributed_sched_permission.h"
53 #include "distributed_sched_utils.h"
54 #include "dms_callback_task.h"
55 #include "dms_constant.h"
56 #include "dms_free_install_callback.h"
57 #include "dms_token_callback.h"
58 #include "dms_version_manager.h"
59 #include "dsched_continue_manager.h"
60 #include "dtbschedmgr_device_info_storage.h"
61 #include "dtbschedmgr_log.h"
62 #include "parcel_helper.h"
63 #include "switch_status_dependency.h"
64 #ifdef SUPPORT_COMMON_EVENT_SERVICE
65 #include "common_event_listener.h"
66 #endif
67 #ifdef SUPPORT_DISTRIBUTED_FORM_SHARE
68 #include "form_mgr_death_recipient.h"
69 #endif
70 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
71 #include "mission/distributed_bm_storage.h"
72 #include "mission/distributed_mission_info.h"
73 #include "mission/dms_continue_send_manager.h"
74 #include "mission/dms_continue_recv_manager.h"
75 #include "mission/distributed_sched_mission_manager.h"
76 #include "mission/dsched_sync_e2e.h"
77 #include "mission/wifi_state_listener.h"
78 #endif
79 
80 namespace OHOS {
81 namespace DistributedSchedule {
82 using namespace AAFwk;
83 using namespace AccountSA;
84 using namespace AppExecFwk;
85 using namespace Constants;
86 using namespace DistributedHardware;
87 
88 namespace {
89 const std::string TAG = "DistributedSchedService";
90 const std::string DMS_SRC_NETWORK_ID = "dmsSrcNetworkId";
91 const int DEFAULT_REQUEST_CODE = -1;
92 const std::u16string CONNECTION_CALLBACK_INTERFACE_TOKEN = u"ohos.abilityshell.DistributedConnection";
93 const std::u16string COMPONENT_CHANGE_INTERFACE_TOKEN = u"ohos.rms.DistributedComponent";
94 const std::u16string ABILITY_MANAGER_SERVICE_TOKEN = u"ohos.aafwk.AbilityManager";
95 const std::u16string ATOMIC_SERVICE_STATUS_CALLBACK_TOKEN = u"ohos.IAtomicServiceStatusCallback";
96 const std::string BUNDLE_NAME_KEY = "bundleName";
97 const std::string VERSION_CODE_KEY = "version";
98 const std::string PID_KEY = "pid";
99 const std::string UID_KEY = "uid";
100 const std::string COMPONENT_TYPE_KEY = "componentType";
101 const std::string DEVICE_TYPE_KEY = "deviceType";
102 const std::string CHANGE_TYPE_KEY = "changeType";
103 const std::string DMS_HIPLAY_ACTION = "ohos.ability.action.deviceSelect";
104 const std::string DMS_VERSION_ID = "dmsVersion";
105 const std::string DMS_UID_SPEC_BUNDLE_NAME = "dmsCallerUidBundleName";
106 const std::string DMS_CONNECT_TOKEN = "connectToken";
107 const std::string DMS_MISSION_ID = "dmsMissionId";
108 const std::string SUPPORT_CONTINUE_PAGE_STACK_KEY = "ohos.extra.param.key.supportContinuePageStack";
109 const std::string SUPPORT_CONTINUE_SOURCE_EXIT_KEY = "ohos.extra.param.key.supportContinueSourceExit";
110 const std::string SUPPORT_CONTINUE_MODULE_NAME_UPDATE_KEY = "ohos.extra.param.key.supportContinueModuleNameUpdate";
111 const std::string DSCHED_EVENT_KEY = "IDSchedEventListener";
112 const std::string DMSDURATION_SAVETIME = "ohos.dschedule.SaveDataTime";
113 const std::string DMS_CONTINUE_SESSION_ID = "ohos.dms.continueSessionId";
114 const std::string DMS_PERSISTENT_ID = "ohos.dms.persistentId";
115 const std::string PKG_NAME = "DBinderBus_Dms_" + std::to_string(getprocpid());
116 const std::string BOOT_COMPLETED_EVENT = "usual.event.BOOT_COMPLETED";
117 const std::string COMMON_EVENT_WIFI_SEMI_STATE = "usual.event.wifi.SEMI_STATE";
118 constexpr int32_t DEFAULT_DMS_MISSION_ID = -1;
119 constexpr int32_t DEFAULT_DMS_CONNECT_TOKEN = -1;
120 constexpr int32_t BIND_CONNECT_RETRY_TIMES = 3;
121 constexpr int32_t BIND_CONNECT_TIMEOUT = 500; // 500ms
122 constexpr int32_t MAX_DISTRIBUTED_CONNECT_NUM = 600;
123 constexpr int32_t INVALID_CALLER_UID = -1;
124 constexpr int32_t IASS_CALLBACK_ON_REMOTE_FREE_INSTALL_DONE = 1;
125 constexpr int32_t DISTRIBUTED_COMPONENT_ADD = 1;
126 constexpr int32_t DISTRIBUTED_COMPONENT_REMOVE = 2;
127 constexpr int32_t START_PERMISSION = 0;
128 constexpr int32_t CALL_PERMISSION = 1;
129 constexpr int32_t SEND_RESULT_PERMISSION = 2;
130 constexpr int64_t CONTINUATION_TIMEOUT = 20000; // 20s
131 // BundleDistributedManager set timeout to 3s, so we set 1s longer
132 constexpr int64_t CHECK_REMOTE_INSTALL_ABILITY = 40000;
133 constexpr int32_t MAX_TOKEN_NUM = 100000000;
134 constexpr uint32_t MAX_MODULENAME_LEN = 2048;
135 constexpr int32_t DMSDURATION_BEGINTIME = 0;
136 constexpr int32_t DMSDURATION_ENDTIME = 1;
137 constexpr int32_t DMSDURATION_TOTALTIME = 2;
138 constexpr int32_t DMSDURATION_DSTTOSRCRPCTIME = 3;
139 constexpr int32_t DMSDURATION_SRCTODSTRPCTIME = 5;
140 constexpr int32_t DMSDURATION_STARTABILITY = 6;
141 constexpr int32_t HID_HAP = 10000; /* first hap user */
142 constexpr int32_t WINDOW_MANAGER_SERVICE_ID = 4606;
143 constexpr int32_t SEMI_WIFI_ID = 1010;
144 DataShareManager &dataShareManager = DataShareManager::GetInstance();
145 }
146 
147 IMPLEMENT_SINGLE_INSTANCE(DistributedSchedService);
148 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(&DistributedSchedService::GetInstance());
149 
DistributedSchedService()150 DistributedSchedService::DistributedSchedService() : SystemAbility(DISTRIBUTED_SCHED_SA_ID, true)
151 {
152 }
153 
OnStart(const SystemAbilityOnDemandReason & startReason)154 void DistributedSchedService::OnStart(const SystemAbilityOnDemandReason &startReason)
155 {
156     HILOGI("OnStart reason %{public}s, reasonId_:%{public}d", startReason.GetName().c_str(), startReason.GetId());
157     if (!DoStart()) {
158         HILOGI("OnStart dms service failed.");
159         return;
160     }
161     Publish(this);
162     HandleBootStart(startReason);
163 }
164 
OnStop(const SystemAbilityOnDemandReason & stopReason)165 void DistributedSchedService::OnStop(const SystemAbilityOnDemandReason &stopReason)
166 {
167     HILOGI("OnStart reason %{public}s, reasonId_:%{public}d", stopReason.GetName().c_str(), stopReason.GetId());
168 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
169     DMSContinueSendMgr::GetInstance().UnInit();
170     DMSContinueRecvMgr::GetInstance().UnInit();
171     RemoveSystemAbilityListener(WINDOW_MANAGER_SERVICE_ID);
172     DistributedSchedAdapter::GetInstance().UnRegisterMissionListener(missionFocusedListener_);
173 #endif
174     dataShareManager.UnregisterObserver(SwitchStatusDependency::GetInstance().CONTINUE_SWITCH_STATUS_KEY);
175     HILOGI("OnStop dms service end");
176 }
177 
OnActive(const SystemAbilityOnDemandReason & activeReason)178 void DistributedSchedService::OnActive(const SystemAbilityOnDemandReason &activeReason)
179 {
180     HILOGI("OnStart reason %{public}s, reasonId_:%{public}d", activeReason.GetName().c_str(), activeReason.GetId());
181     DoStart();
182 }
183 
HandleBootStart(const SystemAbilityOnDemandReason & startReason)184 void DistributedSchedService::HandleBootStart(const SystemAbilityOnDemandReason &startReason)
185 {
186     std::vector<DistributedHardware::DmDeviceInfo> dmDeviceInfoList;
187     int32_t errCode = DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", dmDeviceInfoList);
188     if (errCode != ERR_OK) {
189         HILOGE("Get device manager trusted device list fail, errCode %{public}d", errCode);
190     }
191     if (startReason.GetName() == BOOT_COMPLETED_EVENT && dmDeviceInfoList.empty()) {
192         HILOGI("UnloadSystemAbility dms");
193         auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
194         if (samgrProxy == nullptr) {
195             HILOGE("get samgr failed");
196             return;
197         }
198         int32_t ret = samgrProxy->UnloadSystemAbility(DISTRIBUTED_SCHED_SA_ID);
199         if (ret != ERR_OK) {
200             HILOGE("remove system ability failed");
201             return;
202         }
203         HILOGI("UnloadSystemAbility dms ok");
204     }
205 }
206 
DoStart()207 bool DistributedSchedService::DoStart()
208 {
209 #ifdef DMS_SERVICE_DISABLE
210     HILOGI("DMS service disabled, exiting.");
211     _exit(0);
212 #endif
213     HILOGI("Dms service DoStart enter.");
214     if (!Init()) {
215         HILOGE("failed to init DistributedSchedService");
216         return false;
217     }
218     FuncContinuationCallback continuationCallback = [this] (int32_t missionId) {
219         HILOGW("continuationCallback timeout.");
220         NotifyContinuationCallbackResult(missionId, CONTINUE_ABILITY_TIMEOUT_ERR);
221     };
222 
223     DmsCallbackTaskInitCallbackFunc freeCallback = [this] (int64_t taskId) {
224         HILOGW("DmsCallbackTaskInitCallbackFunc timeout, taskId:%{public}" PRId64 ".", taskId);
225         NotifyCompleteFreeInstallFromRemote(taskId, AAFwk::FREE_INSTALL_TIMEOUT);
226     };
227     dschedContinuation_ = std::make_shared<DSchedContinuation>();
228     collaborateCbMgr_ = std::make_shared<DSchedCollaborationCallbackMgr>();
229     dmsCallbackTask_ = std::make_shared<DmsCallbackTask>();
230     dschedContinuation_->Init(continuationCallback);
231     collaborateCbMgr_->Init();
232     dmsCallbackTask_->Init(freeCallback);
233 
234 #ifdef DMSFWK_INTERACTIVE_ADAPTER
235     HILOGI("Get dms interactive adapter proxy enter.");
236     int32_t ret = GetDmsInteractiveAdapterProxy();
237     if (ret != ERR_OK) {
238         HILOGE("Get remote dms interactive adapter proxy fail, ret %{public}d.", ret);
239     }
240 #endif
241     HILOGI("OnStart dms service success.");
242     return true;
243 }
244 
Dump(int32_t fd,const std::vector<std::u16string> & args)245 int32_t DistributedSchedService::Dump(int32_t fd, const std::vector<std::u16string>& args)
246 {
247     std::vector<std::string> argsInStr8;
248     for (const auto& arg : args) {
249         argsInStr8.emplace_back(Str16ToStr8(arg));
250     }
251     std::string result;
252     DistributedSchedDumper::Dump(argsInStr8, result);
253 
254     if (!SaveStringToFd(fd, result)) {
255         HILOGE("save to fd failed");
256         return DMS_WRITE_FILE_FAILED_ERR;
257     }
258     return ERR_OK;
259 }
260 
DeviceOnlineNotify(const std::string & networkId)261 void DistributedSchedService::DeviceOnlineNotify(const std::string& networkId)
262 {
263     DistributedSchedAdapter::GetInstance().DeviceOnline(networkId);
264 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
265     DistributedSchedMissionManager::GetInstance().DeviceOnlineNotify(networkId);
266     if (!DMSContinueRecvMgr::GetInstance().CheckRegSoftbusListener() &&
267         DistributedHardware::DeviceManager::GetInstance().IsSameAccount(networkId)) {
268         HILOGI("DMSContinueRecvMgr need init");
269         DMSContinueRecvMgr::GetInstance().Init();
270     }
271 #endif
272 }
273 
DeviceOfflineNotify(const std::string & networkId)274 void DistributedSchedService::DeviceOfflineNotify(const std::string& networkId)
275 {
276     DistributedSchedAdapter::GetInstance().DeviceOffline(networkId);
277 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
278     DMSContinueRecvMgr::GetInstance().NotifyDeviceOffline(networkId);
279     DistributedSchedMissionManager::GetInstance().DeviceOfflineNotify(networkId);
280 #endif
281 }
282 
Init()283 bool DistributedSchedService::Init()
284 {
285     HILOGD("ready to init.");
286     InitDeviceCfg();
287     int32_t ret = LoadContinueConfig();
288     if (ret != ERR_OK) {
289         HILOGE("Load continue config fail, ret %{public}d.", ret);
290     }
291 
292     DmsContinueTime::GetInstance().Init();
293     DnetworkAdapter::GetInstance()->Init();
294     if (!DtbschedmgrDeviceInfoStorage::GetInstance().Init()) {
295         HILOGW("DtbschedmgrDeviceInfoStorage init failed.");
296     }
297     InitDataShareManager();
298     InitMissionManager();
299 
300     DistributedSchedAdapter::GetInstance().Init();
301     if (SwitchStatusDependency::GetInstance().IsContinueSwitchOn()) {
302         DSchedContinueManager::GetInstance().Init();
303     }
304     connectDeathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new ConnectDeathRecipient());
305     callerDeathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new CallerDeathRecipient());
306     callerDeathRecipientForLocalDevice_ = sptr<IRemoteObject::DeathRecipient>(
307         new CallerDeathRecipient(IDistributedSched::CALLER));
308     if (componentChangeHandler_ == nullptr) {
309         auto runner = AppExecFwk::EventRunner::Create("DmsComponentChange");
310         componentChangeHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
311     }
312     return true;
313 }
314 
InitMissionManager()315 void DistributedSchedService::InitMissionManager()
316 {
317 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
318     if (!AddSystemAbilityListener(WINDOW_MANAGER_SERVICE_ID)) {
319         HILOGE("Add System Ability Listener failed!");
320     }
321     DistributedSchedMissionManager::GetInstance().Init();
322     DistributedSchedMissionManager::GetInstance().InitDataStorage();
323     InitCommonEventListener();
324     InitWifiStateListener();
325     InitWifiSemiStateListener();
326     DMSContinueSendMgr::GetInstance().Init();
327     DMSContinueRecvMgr::GetInstance().Init();
328 #endif
329 }
330 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)331 void DistributedSchedService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
332 {
333     HILOGI("OnAddSystemAbility systemAbilityId:%{public}d added!", systemAbilityId);
334     missionFocusedListener_ = sptr<DistributedMissionFocusedListener>(new DistributedMissionFocusedListener());
335     int32_t ret = DistributedSchedAdapter::GetInstance().RegisterMissionListener(missionFocusedListener_);
336     if (ret != ERR_OK) {
337         HILOGE("get RegisterMissionListener failed, ret: %{public}d", ret);
338     }
339 }
340 
InitDataShareManager()341 void DistributedSchedService::InitDataShareManager()
342 {
343     DataShareManager::ObserverCallback observerCallback = [this]() {
344         dataShareManager.SetCurrentContinueSwitch(SwitchStatusDependency::GetInstance().IsContinueSwitchOn());
345         HILOGD("dsMgr IsCurrentContinueSwitchOn : %{public}d", dataShareManager.IsCurrentContinueSwitchOn());
346         int32_t missionId = GetCurrentMissionId();
347         if (missionId <= 0) {
348             HILOGW("GetCurrentMissionId failed, init end. ret: %{public}d", missionId);
349             return;
350         }
351         DmsUE::GetInstance().ChangedSwitchState(dataShareManager.IsCurrentContinueSwitchOn(), ERR_OK);
352         if (dataShareManager.IsCurrentContinueSwitchOn()) {
353             DMSContinueSendMgr::GetInstance().NotifyMissionFocused(missionId, FocusedReason::INIT);
354             DSchedContinueManager::GetInstance().Init();
355         } else {
356             DMSContinueSendMgr::GetInstance().NotifyMissionUnfocused(missionId, UnfocusedReason::NORMAL);
357             DMSContinueRecvMgr::GetInstance().OnContinueSwitchOff();
358             DSchedContinueManager::GetInstance().UnInit();
359         };
360     };
361     dataShareManager.SetCurrentContinueSwitch(SwitchStatusDependency::GetInstance().IsContinueSwitchOn());
362     HILOGD("dsMgr IsCurrentContinueSwitchOn : %{public}d", dataShareManager.IsCurrentContinueSwitchOn());
363     dataShareManager.RegisterObserver(SwitchStatusDependency::GetInstance().CONTINUE_SWITCH_STATUS_KEY,
364         observerCallback);
365     DmsUE::GetInstance().OriginalSwitchState(SwitchStatusDependency::GetInstance().IsContinueSwitchOn(), ERR_OK);
366     HILOGI("Init data share manager, register observer end.");
367 }
368 
InitCommonEventListener()369 void DistributedSchedService::InitCommonEventListener()
370 {
371     HILOGI("InitCommonEventListener called");
372 #ifdef SUPPORT_COMMON_EVENT_SERVICE
373     DmsBmStorage::GetInstance();
374     EventFwk::MatchingSkills matchingSkills;
375     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED);
376     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED);
377     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
378     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON);
379     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
380     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED);
381     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
382     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED);
383     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
384     auto applyMonitor = std::make_shared<CommonEventListener>(subscribeInfo);
385     EventFwk::CommonEventManager::SubscribeCommonEvent(applyMonitor);
386     DmsBmStorage::GetInstance()->UpdateDistributedData();
387     if (DmsKvSyncE2E::GetInstance()->CheckDeviceCfg()) {
388         DmsKvSyncE2E::GetInstance()->PushAndPullData();
389     }
390 #endif
391 }
392 
InitWifiStateListener()393 void DistributedSchedService::InitWifiStateListener()
394 {
395     HILOGI("InitWifiStateListener called");
396     EventFwk::MatchingSkills matchingSkills;
397     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_POWER_STATE);
398     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
399     auto wifiStateListener = std::make_shared<WifiStateListener>(subscribeInfo);
400     wifiStateListener->InitWifiState();
401     if (!EventFwk::CommonEventManager::SubscribeCommonEvent(wifiStateListener)) {
402         HILOGE("SubscribeCommonEvent wifiStateListener failed!");
403     }
404 }
405 
InitWifiSemiStateListener()406 void DistributedSchedService::InitWifiSemiStateListener()
407 {
408     HILOGI("InitWifiSemiStateListener called");
409     EventFwk::MatchingSkills matchingSkills;
410     matchingSkills.AddEvent(COMMON_EVENT_WIFI_SEMI_STATE);
411     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
412     subscribeInfo.SetPublisherUid(SEMI_WIFI_ID);
413     auto wifiStateListener = std::make_shared<WifiStateListener>(subscribeInfo);
414     if (!EventFwk::CommonEventManager::SubscribeCommonEvent(wifiStateListener)) {
415         HILOGE("SubscribeCommonEvent wifiSemiStateListener failed!");
416     }
417 }
418 
InitDeviceCfg()419 void DistributedSchedService::InitDeviceCfg()
420 {
421     HILOGI("called");
422     DmsKvSyncE2E::GetInstance()->SetDeviceCfg();
423 }
424 
DurationStart(const std::string srcDeviceId,const std::string dstDeviceId)425 void DistributedSchedService::DurationStart(const std::string srcDeviceId, const std::string dstDeviceId)
426 {
427     DmsContinueTime::GetInstance().Init();
428     std::string strBeginTime = DmsContinueTime::GetInstance().GetCurrentTime();
429     DmsContinueTime::GetInstance().SetDurationStrTime(DMSDURATION_BEGINTIME, strBeginTime);
430     DmsContinueTime::GetInstance().SetNetWorkId(srcDeviceId, dstDeviceId);
431 }
432 
GetCallerInfo(const std::string & localDeviceId,int32_t callerUid,uint32_t accessToken,CallerInfo & callerInfo)433 int32_t DistributedSchedService::GetCallerInfo(const std::string &localDeviceId, int32_t callerUid,
434     uint32_t accessToken, CallerInfo &callerInfo)
435 {
436     callerInfo.sourceDeviceId = localDeviceId;
437     callerInfo.uid = callerUid;
438     callerInfo.accessToken = accessToken;
439     if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
440         HILOGE("GetCallerAppIdFromBms failed");
441         return INVALID_PARAMETERS_ERR;
442     }
443     if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
444         HILOGE("GetBundleNameListFromBms failed");
445         return INVALID_PARAMETERS_ERR;
446     }
447     callerInfo.extraInfoJson[DMS_VERSION_ID] = DMS_VERSION;
448     return ERR_OK;
449 }
450 
StartRemoteAbility(const OHOS::AAFwk::Want & want,int32_t callerUid,int32_t requestCode,uint32_t accessToken)451 int32_t DistributedSchedService::StartRemoteAbility(const OHOS::AAFwk::Want& want,
452     int32_t callerUid, int32_t requestCode, uint32_t accessToken)
453 {
454     std::string localDeviceId;
455     std::string deviceId = want.GetElement().GetDeviceID();
456     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, deviceId)) {
457         HILOGE("check deviceId failed");
458         return INVALID_PARAMETERS_ERR;
459     }
460     sptr<IDistributedSched> remoteDms = GetRemoteDms(deviceId);
461     if (remoteDms == nullptr) {
462         HILOGE("get remoteDms failed");
463         return INVALID_PARAMETERS_ERR;
464     }
465 
466     CallerInfo callerInfo;
467     int32_t ret = GetCallerInfo(localDeviceId, callerUid, accessToken, callerInfo);
468     if (ret != ERR_OK) {
469         HILOGE("Get local device caller info fail, ret: %{public}d.", ret);
470         return ret;
471     }
472     AccountInfo accountInfo;
473     ret = DistributedSchedPermission::GetInstance().GetAccountInfo(deviceId, callerInfo, accountInfo);
474     if (ret != ERR_OK) {
475         HILOGE("GetAccountInfo fail, ret: %{public}d.", ret);
476         return ret;
477     }
478     AAFwk::Want* newWant = const_cast<Want*>(&want);
479     newWant->SetParam(DMS_SRC_NETWORK_ID, localDeviceId);
480     AppExecFwk::AbilityInfo abilityInfo;
481 
482     HILOGI("[PerformanceTest] StartRemoteAbility transact begin");
483     if (!DmsContinueTime::GetInstance().GetPull()) {
484         int64_t begin = GetTickCount();
485         DmsContinueTime::GetInstance().SetDurationBegin(DMSDURATION_SRCTODSTRPCTIME, begin);
486     }
487     int32_t result = remoteDms->StartAbilityFromRemote(*newWant, abilityInfo, requestCode, callerInfo, accountInfo);
488     if (!DmsContinueTime::GetInstance().GetPull()) {
489         int64_t end = GetTickCount();
490         DmsContinueTime::GetInstance().SetDurationBegin(DMSDURATION_STARTABILITY, end);
491         DmsContinueTime::GetInstance().SetDurationEnd(DMSDURATION_SRCTODSTRPCTIME, end);
492     }
493     HILOGI("[PerformanceTest] StartRemoteAbility transact end");
494     return result;
495 }
496 
StartAbilityFromRemote(const OHOS::AAFwk::Want & want,const OHOS::AppExecFwk::AbilityInfo & abilityInfo,int32_t requestCode,const CallerInfo & callerInfo,const AccountInfo & accountInfo)497 int32_t DistributedSchedService::StartAbilityFromRemote(const OHOS::AAFwk::Want& want,
498     const OHOS::AppExecFwk::AbilityInfo& abilityInfo, int32_t requestCode,
499     const CallerInfo& callerInfo, const AccountInfo& accountInfo)
500 {
501     std::string localDeviceId;
502     std::string timeInfo;
503     std::string deviceId = want.GetElement().GetDeviceID();
504     if (!GetLocalDeviceId(localDeviceId) ||
505         !CheckDeviceIdFromRemote(localDeviceId, deviceId, callerInfo.sourceDeviceId)) {
506         HILOGE("check deviceId failed");
507         return INVALID_REMOTE_PARAMETERS_ERR;
508     }
509     if (DmsContinueTime::GetInstance().GetPull()) {
510         timeInfo = want.GetStringParam(DMSDURATION_SAVETIME);
511         DmsContinueTime::GetInstance().ReadDurationInfo(timeInfo.c_str());
512         DmsContinueTime::GetInstance().SetSrcBundleName(want.GetElement().GetBundleName());
513         DmsContinueTime::GetInstance().SetSrcAbilityName(want.GetElement().GetAbilityName());
514     }
515     int32_t result = CheckTargetPermission(want, callerInfo, accountInfo, START_PERMISSION, true);
516     if (result != ERR_OK) {
517         HILOGE("CheckTargetPermission failed!!");
518         return result;
519     }
520 
521     return StartAbility(want, requestCode);
522 }
523 
SendResultFromRemote(OHOS::AAFwk::Want & want,int32_t requestCode,const CallerInfo & callerInfo,const AccountInfo & accountInfo,int32_t resultCode)524 int32_t DistributedSchedService::SendResultFromRemote(OHOS::AAFwk::Want& want, int32_t requestCode,
525     const CallerInfo& callerInfo, const AccountInfo& accountInfo, int32_t resultCode)
526 {
527     std::string localDeviceId;
528     std::string deviceId = want.GetStringParam(DMS_SRC_NETWORK_ID);
529     want.RemoveParam(DMS_SRC_NETWORK_ID);
530     if (!GetLocalDeviceId(localDeviceId) ||
531         !CheckDeviceIdFromRemote(localDeviceId, deviceId, callerInfo.sourceDeviceId)) {
532         HILOGE("check deviceId failed");
533         return INVALID_REMOTE_PARAMETERS_ERR;
534     }
535     if (want.GetElement().GetBundleName().empty() && want.GetElement().GetAbilityName().empty()) {
536         HILOGW("Remote died abnormal");
537         int32_t missionId = want.GetIntParam(DMS_MISSION_ID, DEFAULT_DMS_MISSION_ID);
538         ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->Connect();
539         if (ret != ERR_OK) {
540             HILOGE("connect ability server failed %{public}d", ret);
541             return ret;
542         }
543         MissionInfo missionInfo;
544         ret = AAFwk::AbilityManagerClient::GetInstance()->GetMissionInfo("", missionId, missionInfo);
545         if (ret != ERR_OK) {
546             HILOGE("SendResult failed %{public}d", ret);
547             return ret;
548         }
549         std::string bundleName = missionInfo.want.GetElement().GetBundleName();
550         std::string abilityName = missionInfo.want.GetElement().GetAbilityName();
551         HILOGD("bundlename: %{public}s, ability is %{public}s", bundleName.c_str(), abilityName.c_str());
552         ElementName element{"", bundleName, abilityName};
553         want.SetElement(element);
554     }
555     int32_t result = CheckTargetPermission(want, callerInfo, accountInfo, SEND_RESULT_PERMISSION, false);
556     if (result != ERR_OK) {
557         HILOGE("CheckTargetPermission failed!!");
558         return result;
559     }
560     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->Connect();
561     if (err != ERR_OK) {
562         HILOGE("connect ability server failed %{public}d", err);
563         return err;
564     }
565     err = AAFwk::AbilityManagerClient::GetInstance()->SendResultToAbility(requestCode, resultCode, want);
566     if (err != ERR_OK) {
567         HILOGE("SendResult failed %{public}d", err);
568     }
569     return err;
570 }
571 
RemoveContinuationTimeout(int32_t missionId)572 void DistributedSchedService::RemoveContinuationTimeout(int32_t missionId)
573 {
574     if (dschedContinuation_ == nullptr) {
575         HILOGE("continuation object null!");
576         return;
577     }
578     dschedContinuation_->RemoveTimeOut(missionId);
579 }
580 
SetContinuationTimeout(int32_t missionId,int32_t timeout)581 void DistributedSchedService::SetContinuationTimeout(int32_t missionId, int32_t timeout)
582 {
583     if (dschedContinuation_ == nullptr) {
584         HILOGE("continuation object null!");
585         return;
586     }
587     dschedContinuation_->SetTimeOut(missionId, timeout);
588 }
589 
GetContinuaitonDevice(int32_t missionId)590 std::string DistributedSchedService::GetContinuaitonDevice(int32_t missionId)
591 {
592     if (dschedContinuation_ == nullptr) {
593         HILOGE("continuation object null!");
594         return "";
595     }
596     return dschedContinuation_->GetTargetDevice(missionId);
597 }
598 
ContinueLocalMissionDealFreeInstall(OHOS::AAFwk::Want & want,int32_t missionId,const std::string & dstDeviceId,const sptr<IRemoteObject> & callback)599 int32_t DistributedSchedService::ContinueLocalMissionDealFreeInstall(OHOS::AAFwk::Want& want, int32_t missionId,
600     const std::string& dstDeviceId, const sptr<IRemoteObject>& callback)
601 {
602     bool isFreeInstall = want.GetBoolParam("isFreeInstall", false);
603     if (!isFreeInstall) {
604         HILOGE("remote not installed but support freeInstall, try again with freeInstall flag");
605         return CONTINUE_REMOTE_UNINSTALLED_SUPPORT_FREEINSTALL;
606     }
607 
608     if (dschedContinuation_ == nullptr) {
609         HILOGE("continuation object null!");
610         return INVALID_PARAMETERS_ERR;
611     }
612     dschedContinuation_->PushCallback(missionId, callback, dstDeviceId, true);
613     SetContinuationTimeout(missionId, CHECK_REMOTE_INSTALL_ABILITY);
614 
615     want.SetDeviceId(dstDeviceId);
616     if (!BundleManagerInternal::CheckIfRemoteCanInstall(want, missionId)) {
617         HILOGE("call CheckIfRemoteCanInstall failed");
618         RemoveContinuationTimeout(missionId);
619         dschedContinuation_->PopCallback(missionId);
620         return INVALID_PARAMETERS_ERR;
621     }
622     return ERR_OK;
623 }
624 
ContinueLocalMission(const std::string & dstDeviceId,int32_t missionId,const sptr<IRemoteObject> & callback,const OHOS::AAFwk::WantParams & wantParams)625 int32_t DistributedSchedService::ContinueLocalMission(const std::string& dstDeviceId, int32_t missionId,
626     const sptr<IRemoteObject>& callback, const OHOS::AAFwk::WantParams& wantParams)
627 {
628     if (!dataShareManager.IsCurrentContinueSwitchOn()) {
629         HILOGE("ContinueSwitch status is off");
630         return DMS_PERMISSION_DENIED;
631     }
632     if (dschedContinuation_ == nullptr) {
633         HILOGE("continuation object null!");
634         return INVALID_PARAMETERS_ERR;
635     }
636     if (dschedContinuation_->IsInContinuationProgress(missionId)) {
637         HILOGE("ContinueLocalMission already in progress!");
638         return CONTINUE_ALREADY_IN_PROGRESS;
639     }
640     DmsVersion thresholdDmsVersion = {3, 2, 0};
641     if (DmsVersionManager::IsRemoteDmsVersionLower(dstDeviceId, thresholdDmsVersion)) {
642         HILOGI("remote dms is low version");
643         return ContinueAbilityWithTimeout(dstDeviceId, missionId, callback);
644     }
645 
646     MissionInfo missionInfo;
647     int32_t result = AbilityManagerClient::GetInstance()->GetMissionInfo("", missionId, missionInfo);
648     if (result != ERR_OK) {
649         HILOGE("get missionInfo failed");
650         return NO_MISSION_INFO_FOR_MISSION_ID;
651     }
652     if (missionInfo.continueState != AAFwk::ContinueState::CONTINUESTATE_ACTIVE) {
653         HILOGE("Mission continue state set to INACTIVE. Can't continue. Mission id: %{public}d", missionId);
654         return INVALID_PARAMETERS_ERR;
655     }
656     std::string bundleName = missionInfo.want.GetBundle();
657     if (!CheckBundleContinueConfig(bundleName)) {
658         HILOGI("App does not allow continue in config file, bundle name %{public}s, missionId: %{public}d",
659             bundleName.c_str(), missionId);
660         return REMOTE_DEVICE_BIND_ABILITY_ERR;
661     }
662     missionInfo.want.SetParams(wantParams);
663     DistributedBundleInfo remoteBundleInfo;
664     result = BundleManagerInternal::CheckRemoteBundleInfoForContinuation(dstDeviceId,
665         bundleName, remoteBundleInfo);
666     if (result == ERR_OK) {
667         return ContinueAbilityWithTimeout(dstDeviceId, missionId, callback, remoteBundleInfo.versionCode);
668     }
669     if (result == CONTINUE_REMOTE_UNINSTALLED_UNSUPPORT_FREEINSTALL) {
670         HILOGE("remote not installed and app not support free install");
671         return result;
672     }
673 
674     return ContinueLocalMissionDealFreeInstall(missionInfo.want, missionId, dstDeviceId, callback);
675 }
676 
ContinueAbilityWithTimeout(const std::string & dstDeviceId,int32_t missionId,const sptr<IRemoteObject> & callback,uint32_t remoteBundleVersion)677 int32_t DistributedSchedService::ContinueAbilityWithTimeout(const std::string& dstDeviceId, int32_t missionId,
678     const sptr<IRemoteObject>& callback, uint32_t remoteBundleVersion)
679 {
680     if (dschedContinuation_ == nullptr) {
681         HILOGE("continuation object null!");
682         return INVALID_PARAMETERS_ERR;
683     }
684     bool isPushSucceed = dschedContinuation_->PushCallback(missionId, callback, dstDeviceId, false);
685     if (!isPushSucceed) {
686         HILOGE("Callback already in progress!");
687         return CONTINUE_ALREADY_IN_PROGRESS;
688     }
689     SetContinuationTimeout(missionId, CONTINUATION_TIMEOUT);
690     int64_t saveDataBegin = GetTickCount();
691     DmsContinueTime::GetInstance().SetSaveDataDurationBegin(saveDataBegin);
692     DmsRadar::GetInstance().SaveDataDmsContinue("ContinueAbility", ERR_OK);
693     int32_t result = AbilityManagerClient::GetInstance()->ContinueAbility(dstDeviceId, missionId, remoteBundleVersion);
694     HILOGI("result: %{public}d!", result);
695     if (result == ERR_INVALID_VALUE) {
696         return MISSION_FOR_CONTINUING_IS_NOT_ALIVE;
697     }
698     return result;
699 }
700 
ContinueRemoteMission(const std::string & srcDeviceId,const std::string & dstDeviceId,int32_t missionId,const sptr<IRemoteObject> & callback,const OHOS::AAFwk::WantParams & wantParams)701 int32_t DistributedSchedService::ContinueRemoteMission(const std::string& srcDeviceId, const std::string& dstDeviceId,
702     int32_t missionId, const sptr<IRemoteObject>& callback, const OHOS::AAFwk::WantParams& wantParams)
703 {
704     if (!dataShareManager.IsCurrentContinueSwitchOn()) {
705         HILOGE("ContinueSwitch status is off");
706         return DMS_PERMISSION_DENIED;
707     }
708     sptr<IDistributedSched> remoteDms = GetRemoteDms(srcDeviceId);
709     if (remoteDms == nullptr) {
710         HILOGE("get remote dms null!");
711         return INVALID_REMOTE_PARAMETERS_ERR;
712     }
713 
714     MissionInfo missionInfo;
715     int32_t ret = AAFwk::AbilityManagerClient::GetInstance()->GetMissionInfo("", missionId, missionInfo);
716     if (ret != ERR_OK) {
717         HILOGE("GeGetMissionInfo failed %{public}d", ret);
718         return ret;
719     }
720     std::string bundleName = missionInfo.want.GetElement().GetBundleName();
721     std::string abilityName = missionInfo.want.GetElement().GetAbilityName();
722     HILOGD("bundlename: %{public}s, ability is %{public}s", bundleName.c_str(), abilityName.c_str());
723     DmsUE::GetInstance().TriggerDmsContinue(bundleName, abilityName, srcDeviceId, ERR_OK);
724 
725     std::string peerUdid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(srcDeviceId);
726     DmsRadar::GetInstance().ClickIconDmsContinue("ContinueMission", ERR_OK, peerUdid, bundleName, bundleName);
727 
728     int32_t result = remoteDms->ContinueMission(srcDeviceId, dstDeviceId, missionId, callback, wantParams);
729     HILOGI("ContinueRemoteMission result: %{public}d!", result);
730     return result;
731 }
732 
ContinueRemoteMission(const std::string & srcDeviceId,const std::string & dstDeviceId,const std::string & bundleName,const sptr<IRemoteObject> & callback,const OHOS::AAFwk::WantParams & wantParams)733 int32_t DistributedSchedService::ContinueRemoteMission(const std::string& srcDeviceId, const std::string& dstDeviceId,
734     const std::string& bundleName, const sptr<IRemoteObject>& callback, const OHOS::AAFwk::WantParams& wantParams)
735 {
736     HILOGI("ContinueRemoteMission srcDeviceId: %{public}s. dstDeviceId: %{public}s. bundleName: %{public}s.",
737         GetAnonymStr(srcDeviceId).c_str(), GetAnonymStr(dstDeviceId).c_str(), bundleName.c_str());
738     if (!CheckBundleContinueConfig(bundleName)) {
739         HILOGI("App does not allow continue in config file, bundle name %{public}s", bundleName.c_str());
740         return REMOTE_DEVICE_BIND_ABILITY_ERR;
741     }
742 
743     if (DmsContinueTime::GetInstance().GetPull()) {
744         int64_t begin = GetTickCount();
745         DmsContinueTime::GetInstance().SetDurationBegin(DMSDURATION_DSTTOSRCRPCTIME, begin);
746         DmsContinueTime::GetInstance().SetDurationBegin(DMSDURATION_TOTALTIME, begin);
747     }
748 
749     sptr<IDistributedSched> remoteDms = GetRemoteDms(srcDeviceId);
750     if (remoteDms == nullptr) {
751         HILOGE("get remote dms null!");
752         if (dschedContinuation_ == nullptr) {
753             HILOGE("continuation object null!");
754             return INVALID_PARAMETERS_ERR;
755         }
756         int32_t dSchedEventresult = dschedContinuation_->NotifyDSchedEventResult(INVALID_REMOTE_PARAMETERS_ERR);
757         HILOGD("NotifyDSchedEventResult result:%{public}d", dSchedEventresult);
758         return INVALID_REMOTE_PARAMETERS_ERR;
759     }
760     int32_t result = remoteDms->ContinueMission(srcDeviceId, dstDeviceId, bundleName, callback, wantParams);
761     HILOGI("ContinueRemoteMission result: %{public}d!", result);
762     if (DmsContinueTime::GetInstance().GetPull()) {
763         int64_t end = GetTickCount();
764         DmsContinueTime::GetInstance().SetDurationEnd(DMSDURATION_DSTTOSRCRPCTIME, end);
765     }
766     if (result != ERR_OK) {
767         if (dschedContinuation_ == nullptr) {
768             HILOGE("continuation object null!");
769             return INVALID_PARAMETERS_ERR;
770         }
771         int32_t dSchedEventresult = dschedContinuation_->NotifyDSchedEventResult(result);
772         HILOGD("NotifyDSchedEventResult result:%{public}d", dSchedEventresult);
773     }
774     return result;
775 }
776 
ContinueMission(const std::string & srcDeviceId,const std::string & dstDeviceId,int32_t missionId,const sptr<IRemoteObject> & callback,const OHOS::AAFwk::WantParams & wantParams)777 int32_t DistributedSchedService::ContinueMission(const std::string& srcDeviceId, const std::string& dstDeviceId,
778     int32_t missionId, const sptr<IRemoteObject>& callback, const OHOS::AAFwk::WantParams& wantParams)
779 {
780     HILOGI("ContinueMission called");
781     if (srcDeviceId.empty() || dstDeviceId.empty() || callback == nullptr) {
782         HILOGE("srcDeviceId or dstDeviceId or callback is null!");
783         return INVALID_PARAMETERS_ERR;
784     }
785     std::string localDevId;
786     if (!GetLocalDeviceId(localDevId)) {
787         HILOGE("get local deviceId failed!");
788         return INVALID_PARAMETERS_ERR;
789     }
790     DurationStart(srcDeviceId, dstDeviceId);
791 
792     if (srcDeviceId == localDevId) {
793         if (DtbschedmgrDeviceInfoStorage::GetInstance().GetDeviceInfoById(dstDeviceId) == nullptr) {
794             HILOGE("GetDeviceInfoById failed, dstDeviceId: %{public}s.", GetAnonymStr(dstDeviceId).c_str());
795             return INVALID_REMOTE_PARAMETERS_ERR;
796         }
797         return ContinueLocalMission(dstDeviceId, missionId, callback, wantParams);
798     } else if (dstDeviceId == localDevId) {
799         DmsContinueTime::GetInstance().SetPull(true);
800         if (DtbschedmgrDeviceInfoStorage::GetInstance().GetDeviceInfoById(srcDeviceId) == nullptr) {
801             HILOGE("GetDeviceInfoById failed, srcDeviceId: %{public}s.", GetAnonymStr(srcDeviceId).c_str());
802             return INVALID_REMOTE_PARAMETERS_ERR;
803         }
804         return ContinueRemoteMission(srcDeviceId, dstDeviceId, missionId, callback, wantParams);
805     } else {
806         HILOGE("source or target device must be local!");
807         return OPERATION_DEVICE_NOT_INITIATOR_OR_TARGET;
808     }
809 }
810 
ProcessContinueLocalMission(const std::string & srcDeviceId,const std::string & dstDeviceId,const std::string & bundleName,const sptr<IRemoteObject> & callback,const OHOS::AAFwk::WantParams & wantParams)811 int32_t DistributedSchedService::ProcessContinueLocalMission(const std::string& srcDeviceId,
812     const std::string& dstDeviceId, const std::string& bundleName, const sptr<IRemoteObject>& callback,
813     const OHOS::AAFwk::WantParams& wantParams)
814 {
815     HILOGI("ProcessContinueLocalMission called.");
816     if (DtbschedmgrDeviceInfoStorage::GetInstance().GetDeviceInfoById(dstDeviceId) == nullptr) {
817         HILOGE("GetDeviceInfoById failed, dstDeviceId: %{public}s.", GetAnonymStr(dstDeviceId).c_str());
818         return INVALID_REMOTE_PARAMETERS_ERR;
819     }
820 
821     int32_t missionId = 1;
822 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
823     int32_t ret = DMSContinueSendMgr::GetInstance().GetMissionIdByBundleName(bundleName, missionId);
824     if (ret != ERR_OK) {
825         HILOGE("get missionId failed");
826         return ret;
827     }
828 #endif
829 
830     if (dschedContinuation_ == nullptr) {
831         HILOGE("continuation object null!");
832         return INVALID_PARAMETERS_ERR;
833     }
834     dschedContinuation_->continueEvent_.srcNetworkId_ = srcDeviceId;
835     dschedContinuation_->continueEvent_.dstNetworkId_ = dstDeviceId;
836     return ContinueLocalMission(dstDeviceId, missionId, callback, wantParams);
837 }
838 
ProcessContinueRemoteMission(const std::string & srcDeviceId,const std::string & dstDeviceId,const std::string & bundleName,const sptr<IRemoteObject> & callback,const OHOS::AAFwk::WantParams & wantParams)839 int32_t DistributedSchedService::ProcessContinueRemoteMission(const std::string& srcDeviceId,
840     const std::string& dstDeviceId, const std::string& bundleName, const sptr<IRemoteObject>& callback,
841     const OHOS::AAFwk::WantParams& wantParams)
842 {
843     HILOGI("ProcessContinueRemoteMission start.");
844     if (DtbschedmgrDeviceInfoStorage::GetInstance().GetDeviceInfoById(srcDeviceId) == nullptr) {
845         HILOGE("GetDeviceInfoById failed, srcDeviceId: %{public}s.", GetAnonymStr(srcDeviceId).c_str());
846         return INVALID_REMOTE_PARAMETERS_ERR;
847     }
848     if (dschedContinuation_ == nullptr) {
849         HILOGE("continuation object null!");
850         return INVALID_PARAMETERS_ERR;
851     }
852     dschedContinuation_->continueEvent_.srcNetworkId_ = dstDeviceId;
853     dschedContinuation_->continueEvent_.dstNetworkId_ = srcDeviceId;
854     HILOGI("ProcessContinueRemoteMission end.");
855     return ContinueRemoteMission(srcDeviceId, dstDeviceId, bundleName, callback, wantParams);
856 }
857 
ContinueMission(const std::string & srcDeviceId,const std::string & dstDeviceId,const std::string & bundleName,const sptr<IRemoteObject> & callback,const OHOS::AAFwk::WantParams & wantParams)858 int32_t DistributedSchedService::ContinueMission(const std::string& srcDeviceId, const std::string& dstDeviceId,
859     const std::string& bundleName, const sptr<IRemoteObject>& callback, const OHOS::AAFwk::WantParams& wantParams)
860 {
861     HILOGI("ContinueMission srcDeviceId: %{public}s. dstDeviceId: %{public}s. bundleName: %{public}s.",
862         GetAnonymStr(srcDeviceId).c_str(), GetAnonymStr(dstDeviceId).c_str(), bundleName.c_str());
863     if (srcDeviceId.empty() || dstDeviceId.empty() || callback == nullptr) {
864         HILOGE("srcDeviceId or dstDeviceId or callback is null!");
865         return INVALID_PARAMETERS_ERR;
866     }
867     std::string localDevId;
868     if (!GetLocalDeviceId(localDevId)) {
869         HILOGE("get local deviceId failed!");
870         return INVALID_PARAMETERS_ERR;
871     }
872     DurationStart(srcDeviceId, dstDeviceId);
873 
874     if (srcDeviceId == localDevId) {
875         return ProcessContinueLocalMission(srcDeviceId, dstDeviceId, bundleName, callback, wantParams);
876     } else if (dstDeviceId == localDevId) {
877         DmsContinueTime::GetInstance().SetPull(true);
878         return ProcessContinueRemoteMission(srcDeviceId, dstDeviceId, bundleName, callback, wantParams);
879     } else {
880         HILOGE("source or target device must be local!");
881         return OPERATION_DEVICE_NOT_INITIATOR_OR_TARGET;
882     }
883 }
884 
SetWantForContinuation(AAFwk::Want & newWant,int32_t missionId)885 int32_t DistributedSchedService::SetWantForContinuation(AAFwk::Want& newWant, int32_t missionId)
886 {
887     std::string devId;
888     if (!GetLocalDeviceId(devId)) {
889         HILOGE("StartContinuation get local deviceId failed!");
890         return INVALID_REMOTE_PARAMETERS_ERR;
891     }
892 
893     newWant.SetParam("sessionId", missionId);
894     newWant.SetParam("deviceId", devId);
895     std::string strInfo = DmsContinueTime::GetInstance().WriteDurationInfo(
896         DmsContinueTime::GetInstance().GetSaveDataDuration());
897     newWant.SetParam(DMSDURATION_SAVETIME, strInfo);
898     BundleInfo localBundleInfo;
899     if (BundleManagerInternal::GetLocalBundleInfo(newWant.GetBundle(), localBundleInfo) != ERR_OK) {
900         HILOGE("get local bundle info failed");
901         return INVALID_PARAMETERS_ERR;
902     }
903     newWant.SetParam(VERSION_CODE_KEY, static_cast<int32_t>(localBundleInfo.versionCode));
904 
905     bool isPageStackContinue = newWant.GetBoolParam(SUPPORT_CONTINUE_PAGE_STACK_KEY, true);
906     std::string moduleName = newWant.GetStringParam(SUPPORT_CONTINUE_MODULE_NAME_UPDATE_KEY);
907     if (!isPageStackContinue && !moduleName.empty() && moduleName.length() <= MAX_MODULENAME_LEN) {
908         HILOGD("set application moduleName = %{private}s!", moduleName.c_str());
909         OHOS::AppExecFwk::ElementName element = newWant.GetElement();
910         newWant.SetElementName(element.GetDeviceID(), element.GetBundleName(), element.GetAbilityName(), moduleName);
911     }
912     HILOGD("local version = %{public}u!", localBundleInfo.versionCode);
913     return ERR_OK;
914 }
915 
DealDSchedEventResult(const OHOS::AAFwk::Want & want,int32_t status)916 int32_t DistributedSchedService::DealDSchedEventResult(const OHOS::AAFwk::Want& want, int32_t status)
917 {
918     if (dschedContinuation_ == nullptr) {
919         HILOGE("continuation object null!");
920         return INVALID_PARAMETERS_ERR;
921     }
922     DmsContinueTime::GetInstance().SetSrcBundleName(want.GetElement().GetBundleName());
923     DmsContinueTime::GetInstance().SetSrcAbilityName(dschedContinuation_->continueEvent_.srcAbilityName_);
924     if (status != ERR_OK) {
925         HILOGD("want deviceId result:%{public}s", GetAnonymStr(want.GetElement().GetDeviceID()).c_str());
926         std::string deviceId = want.GetElement().GetDeviceID();
927         sptr<IDistributedSched> remoteDms = GetRemoteDms(deviceId);
928         if (remoteDms == nullptr) {
929             HILOGE("NotifyCompleteContinuation get remote dms null!");
930             return INVALID_REMOTE_PARAMETERS_ERR;
931         }
932         int dSchedEventresult = remoteDms->NotifyDSchedEventResultFromRemote(DSCHED_EVENT_KEY, status);
933         HILOGI("NotifyDSchedEventResultFromRemote result:%{public}d", dSchedEventresult);
934     }
935     return ERR_OK;
936 }
937 
GetIsFreeInstall(int32_t missionId)938 bool DistributedSchedService::GetIsFreeInstall(int32_t missionId)
939 {
940     if (dschedContinuation_ == nullptr) {
941         return false;
942     }
943     return dschedContinuation_->IsFreeInstall(missionId);
944 }
945 
StartContinuation(const OHOS::AAFwk::Want & want,int32_t missionId,int32_t callerUid,int32_t status,uint32_t accessToken)946 int32_t DistributedSchedService::StartContinuation(const OHOS::AAFwk::Want& want, int32_t missionId,
947     int32_t callerUid, int32_t status, uint32_t accessToken)
948 {
949     HILOGD("[PerformanceTest] StartContinuation begin");
950     DealDSchedEventResult(want, status);
951     if (status != ERR_OK) {
952         HILOGE("continuation has been rejected, status: %{public}d", status);
953         NotifyContinuationCallbackResult(missionId, status);
954         return INVALID_REMOTE_PARAMETERS_ERR;
955     }
956     auto flags = want.GetFlags();
957     if ((flags & AAFwk::Want::FLAG_ABILITY_CONTINUATION) == 0) {
958         HILOGE("StartContinuation want continuation flags invalid!");
959         return INVALID_REMOTE_PARAMETERS_ERR;
960     }
961     HILOGD("StartContinuation: devId = %{private}s, bundleName = %{private}s, abilityName = %{private}s",
962         GetAnonymStr(want.GetElement().GetDeviceID()).c_str(), want.GetElement().GetBundleName().c_str(),
963         want.GetElement().GetAbilityName().c_str());
964     if (dschedContinuation_ == nullptr) {
965         HILOGE("StartContinuation continuation object null!");
966         return INVALID_REMOTE_PARAMETERS_ERR;
967     }
968     if (!dschedContinuation_->IsInContinuationProgress(missionId)) {
969         dschedContinuation_->SetTimeOut(missionId, CONTINUATION_TIMEOUT);
970     }
971     AAFwk::Want newWant = want;
972     int result = SetWantForContinuation(newWant, missionId);
973     if (result != ERR_OK) {
974         HILOGE("set new want failed");
975         return result;
976     }
977     bool flag = GetIsFreeInstall(missionId);
978     SetCleanMissionFlag(want, missionId);
979     if (flag) {
980         result = StartRemoteFreeInstall(newWant, callerUid, DEFAULT_REQUEST_CODE, accessToken, nullptr);
981         if (result != ERR_OK) {
982             HILOGE("continue free install failed, result = %{public}d", result);
983             return result;
984         }
985     } else {
986         result = StartRemoteAbility(newWant, callerUid, DEFAULT_REQUEST_CODE, accessToken);
987         DmsRadar::GetInstance().SaveDataDmsRemoteWant("StartRemoteAbility", result);
988         if (result != ERR_OK) {
989             HILOGE("continue ability failed, errorCode = %{public}d", result);
990             return result;
991         }
992     }
993     HILOGD("[PerformanceTest] StartContinuation end");
994     return result;
995 }
996 
NotifyCompleteContinuation(const std::u16string & devId,int32_t sessionId,bool isSuccess)997 void DistributedSchedService::NotifyCompleteContinuation(const std::u16string& devId,
998     int32_t sessionId, bool isSuccess)
999 {
1000     if (!isSuccess) {
1001         HILOGE("NotifyCompleteContinuation failed!");
1002     }
1003     if (sessionId <= 0) {
1004         HILOGE("NotifyCompleteContinuation sessionId invalid!");
1005         return;
1006     }
1007     std::string deviceId = Str16ToStr8(devId);
1008     sptr<IDistributedSched> remoteDms = GetRemoteDms(deviceId);
1009     if (remoteDms == nullptr) {
1010         HILOGE("NotifyCompleteContinuation get remote dms null!");
1011         return;
1012     }
1013     if (dschedContinuation_ == nullptr) {
1014         HILOGE("continuation object null!");
1015         return;
1016     }
1017     int dSchedEventResult = dschedContinuation_->NotifyDSchedEventResult(ERR_OK);
1018     HILOGD("NotifyDSchedEventResult result:%{public}d", dSchedEventResult);
1019 
1020     std::string dstInfo("");
1021     if (DmsContinueTime::GetInstance().GetPull()) {
1022         int64_t end = GetTickCount();
1023         std::string strEndTime = DmsContinueTime::GetInstance().GetCurrentTime();
1024         DmsContinueTime::GetInstance().SetDurationEnd(DMSDURATION_STARTABILITY, end);
1025         DmsContinueTime::GetInstance().SetDurationEnd(DMSDURATION_TOTALTIME, end);
1026         DmsContinueTime::GetInstance().SetDurationStrTime(DMSDURATION_ENDTIME, strEndTime);
1027 
1028         std::string bundleName = DmsContinueTime::GetInstance().GetDstInfo().bundleName;
1029         std::string abilityName = DmsContinueTime::GetInstance().GetDstInfo().abilityName;
1030         std::string srcNetworkId = dschedContinuation_->continueInfo_.srcNetworkId_;
1031         DmsUE::GetInstance().DmsContinueComplete(bundleName, abilityName, srcNetworkId, dSchedEventResult);
1032 
1033         DmsContinueTime::GetInstance().AppendInfo();
1034         DmsContinueTime::GetInstance().SetPull(false);
1035     } else {
1036         dstInfo = DmsContinueTime::GetInstance().WriteDstInfo(DmsContinueTime::GetInstance().GetDstInfo().bundleName,
1037             DmsContinueTime::GetInstance().GetDstInfo().abilityName);
1038     }
1039 
1040     remoteDms->NotifyContinuationResultFromRemote(sessionId, isSuccess, dstInfo);
1041     dschedContinuation_->continueInfo_.srcNetworkId_ = "";
1042     dschedContinuation_->continueInfo_.dstNetworkId_ = "";
1043     DmsRadar::GetInstance().ClickIconDmsRecvOver("NotifyContinuationResultFromRemote", dSchedEventResult);
1044 }
1045 
NotifyContinuationResultFromRemote(int32_t sessionId,bool isSuccess,const std::string dstInfo)1046 int32_t DistributedSchedService::NotifyContinuationResultFromRemote(int32_t sessionId, bool isSuccess,
1047     const std::string dstInfo)
1048 {
1049     if (sessionId <= 0) {
1050         HILOGE("NotifyContinuationResultFromRemote sessionId:%{public}d invalid!", sessionId);
1051         return INVALID_REMOTE_PARAMETERS_ERR;
1052     }
1053     if (dstInfo.length() != 0) {
1054         int64_t end = GetTickCount();
1055         DmsContinueTime::GetInstance().SetDurationEnd(DMSDURATION_STARTABILITY, end);
1056         std::string strEndTime = DmsContinueTime::GetInstance().GetCurrentTime();
1057         DmsContinueTime::GetInstance().SetDurationStrTime(DMSDURATION_ENDTIME, strEndTime);
1058         DmsContinueTime::GetInstance().ReadDstInfo(dstInfo.c_str());
1059         DmsContinueTime::GetInstance().AppendInfo();
1060     }
1061 
1062     int32_t missionId = sessionId;
1063     NotifyContinuationCallbackResult(missionId, isSuccess ? 0 : NOTIFYCOMPLETECONTINUATION_FAILED);
1064     if (dschedContinuation_ == nullptr) {
1065         HILOGW("continuation object null!");
1066         return ERR_OK;
1067     }
1068     dschedContinuation_->continueInfo_.srcNetworkId_ = "";
1069     dschedContinuation_->continueInfo_.dstNetworkId_ = "";
1070     return ERR_OK;
1071 }
1072 
NotifyDSchedEventResultFromRemote(const std::string type,int32_t dSchedEventResult)1073 int32_t DistributedSchedService::NotifyDSchedEventResultFromRemote(const std::string type, int32_t dSchedEventResult)
1074 {
1075     NotifyDSchedEventCallbackResult(dSchedEventResult);
1076     return ERR_OK;
1077 }
1078 
1079 #ifdef SUPPORT_DISTRIBUTED_FORM_SHARE
GetFormMgrProxy()1080 sptr<IFormMgr> DistributedSchedService::GetFormMgrProxy()
1081 {
1082     HILOGD("GetFormMgrProxy begin.");
1083     std::lock_guard<std::mutex> lock(formMgrLock_);
1084     if (formMgrProxy_ != nullptr) {
1085         HILOGD("get fms proxy success.");
1086         return formMgrProxy_;
1087     }
1088 
1089     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1090     if (systemAbilityMgr == nullptr) {
1091         HILOGE("system ability manager is nullptr.");
1092         return nullptr;
1093     }
1094 
1095     auto remoteObj = systemAbilityMgr->GetSystemAbility(FORM_MGR_SERVICE_ID);
1096     if (remoteObj == nullptr) {
1097         HILOGE("failed to get form manager service");
1098         return nullptr;
1099     }
1100 
1101     formMgrDeathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new FormMgrDeathRecipient());
1102     if (formMgrDeathRecipient_ == nullptr) {
1103         HILOGE("failed to create FormMgrDeathRecipient!");
1104         return nullptr;
1105     }
1106 
1107     if ((remoteObj->IsProxyObject()) && (!remoteObj->AddDeathRecipient(formMgrDeathRecipient_))) {
1108         HILOGE("add death recipient to FormMgrService failed.");
1109         return nullptr;
1110     }
1111 
1112     formMgrProxy_ = iface_cast<IFormMgr>(remoteObj);
1113     return formMgrProxy_;
1114 }
1115 
ProcessFormMgrDied(const wptr<IRemoteObject> & remote)1116 void DistributedSchedService::ProcessFormMgrDied(const wptr<IRemoteObject>& remote)
1117 {
1118     std::lock_guard<std::mutex> lock(formMgrLock_);
1119     if (formMgrProxy_ == nullptr) {
1120         return;
1121     }
1122 
1123     auto serviceRemote = formMgrProxy_->AsObject();
1124     if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
1125         serviceRemote->RemoveDeathRecipient(formMgrDeathRecipient_);
1126         formMgrProxy_ = nullptr;
1127     }
1128 }
1129 #endif
1130 
NotifyContinuationCallbackResult(int32_t missionId,int32_t resultCode)1131 void DistributedSchedService::NotifyContinuationCallbackResult(int32_t missionId, int32_t resultCode)
1132 {
1133     HILOGD("Continuation result is: %{public}d", resultCode);
1134 
1135     if (dschedContinuation_ == nullptr) {
1136         HILOGE("continuation object null!");
1137         return;
1138     }
1139 
1140     int32_t result = 0;
1141     if (dschedContinuation_->IsInContinuationProgress(missionId)) {
1142         if (resultCode == ERR_OK && dschedContinuation_->IsCleanMission(missionId)) {
1143             result = AbilityManagerClient::GetInstance()->CleanMission(missionId);
1144             HILOGD("clean mission result:%{public}d", result);
1145         }
1146         result = dschedContinuation_->NotifyMissionCenterResult(missionId, resultCode);
1147     } else {
1148         result = AbilityManagerClient::GetInstance()->NotifyContinuationResult(missionId, resultCode);
1149         dschedContinuation_->RemoveTimeOut(missionId);
1150     }
1151     HILOGD("NotifyContinuationCallbackResult result:%{public}d", result);
1152 }
1153 
NotifyDSchedEventCallbackResult(int32_t resultCode)1154 void DistributedSchedService::NotifyDSchedEventCallbackResult(int32_t resultCode)
1155 {
1156     HILOGD("Continuation result is: %{public}d", resultCode);
1157     if (dschedContinuation_ == nullptr) {
1158         HILOGE("continuation object null!");
1159         return;
1160     }
1161     int dSchedEventresult = dschedContinuation_->NotifyDSchedEventResult(resultCode);
1162     HILOGD("NotifyDSchedEventResult result:%{public}d", dSchedEventresult);
1163 }
1164 
NotifyDSchedEventCallbackResult(int32_t resultCode,const EventNotify & event)1165 void DistributedSchedService::NotifyDSchedEventCallbackResult(int32_t resultCode, const EventNotify& event)
1166 {
1167     HILOGD("Continuation result is: %{public}d", resultCode);
1168     switch (event.dSchedEventType_) {
1169         case DMS_CONTINUE:
1170             NotifyContinuateEventResult(resultCode, event);
1171             break;
1172         case DMS_COLLABORATION:
1173             NotifyCollaborateEventResult(resultCode, event);
1174             break;
1175         default:
1176             HILOGE("Event does not carry specific operation type, eventType %{public}d.", event.dSchedEventType_);
1177             return;
1178     }
1179 }
1180 
NotifyContinuateEventResult(int32_t resultCode,const EventNotify & event)1181 void DistributedSchedService::NotifyContinuateEventResult(int32_t resultCode, const EventNotify& event)
1182 {
1183     if (dschedContinuation_ == nullptr) {
1184         HILOGE("continuation object null!");
1185         return;
1186     }
1187     dschedContinuation_->continueEvent_ = event;
1188     int dSchedEventresult = dschedContinuation_->NotifyDSchedEventResult(resultCode);
1189     HILOGD("NotifyDSchedEventResult result:%{public}d", dSchedEventresult);
1190     if (event.state_ == DMS_DSCHED_EVENT_FINISH || resultCode != ERR_OK) {
1191         dschedContinuation_->continueEvent_ = EventNotify();
1192     }
1193 }
1194 
NotifyCollaborateEventResult(int32_t resultCode,const EventNotify & event)1195 void DistributedSchedService::NotifyCollaborateEventResult(int32_t resultCode, const EventNotify& event)
1196 {
1197     if (collaborateCbMgr_ == nullptr) {
1198         HILOGE("collaborate callback manager is null.");
1199         return;
1200     }
1201     int32_t collaborateEventRet = collaborateCbMgr_->NotifyDSchedEventResult(resultCode, event);
1202     HILOGD("NotifyDSchedEventResult result: %{public}d", collaborateEventRet);
1203 }
1204 
NotifyCollaborateEventWithSessions(const std::list<ConnectAbilitySession> & sessionsList,DSchedEventState state,int32_t ret)1205 void DistributedSchedService::NotifyCollaborateEventWithSessions(
1206     const std::list<ConnectAbilitySession> &sessionsList, DSchedEventState state, int32_t ret)
1207 {
1208     for (const auto &session : sessionsList) {
1209         for (const auto &element : session.GetElementsList()) {
1210             EventNotify tempEvent;
1211             GetCurSrcCollaborateEvent(session.GetCallerInfo(), element, state, ret, tempEvent);
1212             NotifyDSchedEventCallbackResult(ret, tempEvent);
1213         }
1214     }
1215 }
1216 
GetCurSrcCollaborateEvent(const CallerInfo & callerInfo,const AppExecFwk::ElementName & element,DSchedEventState state,int32_t ret,EventNotify & event)1217 void DistributedSchedService::GetCurSrcCollaborateEvent(const CallerInfo &callerInfo,
1218     const AppExecFwk::ElementName &element, DSchedEventState state, int32_t ret, EventNotify &event)
1219 {
1220     std::string callingBundleName;
1221     if (!BundleManagerInternal::GetSpecifyBundleNameFromBms(callerInfo.uid, callingBundleName)) {
1222         HILOGE("Get specify bundle name for from Bms fail, connect session caller uid %{public}d.", callerInfo.uid);
1223     }
1224 
1225     event.eventResult_ = ret;
1226     event.srcNetworkId_ = callerInfo.sourceDeviceId;
1227     event.dstNetworkId_ = element.GetDeviceID();
1228     event.srcBundleName_ = callingBundleName;
1229     event.srcModuleName_ = "";
1230     event.srcAbilityName_ = "";
1231     event.destBundleName_ = element.GetBundleName();
1232     event.destModuleName_ = element.GetModuleName();
1233     event.destAbilityName_ = element.GetAbilityName();
1234     event.dSchedEventType_ = DMS_COLLABORATION;
1235     event.state_ = state;
1236 }
1237 
GetCurDestCollaborateEvent(const CallerInfo & callerInfo,const AppExecFwk::ElementName & element,DSchedEventState state,int32_t ret,EventNotify & event)1238 void DistributedSchedService::GetCurDestCollaborateEvent(const CallerInfo &callerInfo,
1239     const AppExecFwk::ElementName &element, DSchedEventState state, int32_t ret, EventNotify &event)
1240 {
1241     std::string callerBundleName;
1242     if (callerInfo.extraInfoJson.find(DMS_UID_SPEC_BUNDLE_NAME) != callerInfo.extraInfoJson.end() &&
1243         callerInfo.extraInfoJson[DMS_UID_SPEC_BUNDLE_NAME].is_string()) {
1244         callerBundleName = callerInfo.extraInfoJson[DMS_UID_SPEC_BUNDLE_NAME];
1245     }
1246 
1247     event.eventResult_ = ret;
1248     event.srcNetworkId_ = callerInfo.sourceDeviceId;
1249     event.dstNetworkId_ = element.GetDeviceID();
1250     event.srcBundleName_ = callerBundleName;
1251     event.srcModuleName_ = "";
1252     event.srcAbilityName_ = "";
1253     event.destBundleName_ = element.GetBundleName();
1254     event.destModuleName_ = element.GetModuleName();
1255     event.destAbilityName_ = element.GetAbilityName();
1256     event.dSchedEventType_ = DMS_COLLABORATION;
1257     event.state_ = state;
1258 }
1259 
RemoteConnectAbilityMappingLocked(const sptr<IRemoteObject> & connect,const std::string & localDeviceId,const std::string & remoteDeviceId,const AppExecFwk::ElementName & element,const CallerInfo & callerInfo,TargetComponent targetComponent)1260 void DistributedSchedService::RemoteConnectAbilityMappingLocked(const sptr<IRemoteObject>& connect,
1261     const std::string& localDeviceId, const std::string& remoteDeviceId, const AppExecFwk::ElementName& element,
1262     const CallerInfo& callerInfo, TargetComponent targetComponent)
1263 {
1264     if (connect == nullptr) {
1265         return;
1266     }
1267     auto itConnect = distributedConnectAbilityMap_.find(connect);
1268     if (itConnect == distributedConnectAbilityMap_.end()) {
1269         // add uid's connect number
1270         uint32_t number = ++trackingUidMap_[callerInfo.uid];
1271         HILOGD("uid %{public}d has %{public}u connection(s), targetComponent: %{public}d.",
1272             callerInfo.uid, number, targetComponent);
1273         // new connect, add death recipient
1274         connect->AddDeathRecipient(connectDeathRecipient_);
1275         ReportDistributedComponentChange(callerInfo, DISTRIBUTED_COMPONENT_ADD, IDistributedSched::CONNECT,
1276             IDistributedSched::CALLER);
1277     }
1278     auto& sessionsList = distributedConnectAbilityMap_[connect];
1279     for (auto& session : sessionsList) {
1280         if (remoteDeviceId == session.GetDestinationDeviceId()) {
1281             session.AddElement(element);
1282             // already added session for remote device
1283             return;
1284         }
1285     }
1286     // connect to another remote device, add a new session to list
1287     auto& session = sessionsList.emplace_back(localDeviceId, remoteDeviceId, callerInfo, targetComponent);
1288     session.AddElement(element);
1289     HILOGD("add connection success");
1290 }
1291 
CheckDistributedConnectLocked(const CallerInfo & callerInfo) const1292 int32_t DistributedSchedService::CheckDistributedConnectLocked(const CallerInfo& callerInfo) const
1293 {
1294     if (callerInfo.uid < 0) {
1295         HILOGE("uid %{public}d is invalid.", callerInfo.uid);
1296         return BIND_ABILITY_UID_INVALID_ERR;
1297     }
1298     auto it = trackingUidMap_.find(callerInfo.uid);
1299     if (it != trackingUidMap_.end() && it->second >= MAX_DISTRIBUTED_CONNECT_NUM) {
1300         HILOGE("uid %{public}d connected too much abilities, it maybe leak.", callerInfo.uid);
1301         return BIND_ABILITY_LEAK_ERR;
1302     }
1303     return ERR_OK;
1304 }
1305 
DecreaseConnectLocked(int32_t uid)1306 void DistributedSchedService::DecreaseConnectLocked(int32_t uid)
1307 {
1308     if (uid < 0) {
1309         HILOGE("DecreaseConnectLocked invalid uid %{public}d", uid);
1310         return;
1311     }
1312     auto it = trackingUidMap_.find(uid);
1313     if (it != trackingUidMap_.end()) {
1314         auto& conns = it->second;
1315         if (conns > 0) {
1316             conns--;
1317         }
1318         if (conns == 0) {
1319             HILOGD("DecreaseConnectLocked uid %{public}d connection(s) is 0", uid);
1320             trackingUidMap_.erase(it);
1321         }
1322     }
1323 }
1324 
GetUidLocked(const std::list<ConnectAbilitySession> & sessionsList)1325 int32_t DistributedSchedService::GetUidLocked(const std::list<ConnectAbilitySession>& sessionsList)
1326 {
1327     if (!sessionsList.empty()) {
1328         return sessionsList.front().GetCallerInfo().uid;
1329     }
1330     return INVALID_CALLER_UID;
1331 }
1332 
ConnectRemoteAbility(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,int32_t callerUid,int32_t callerPid,uint32_t accessToken)1333 int32_t DistributedSchedService::ConnectRemoteAbility(const OHOS::AAFwk::Want& want,
1334     const sptr<IRemoteObject>& connect, int32_t callerUid, int32_t callerPid, uint32_t accessToken)
1335 {
1336     std::string localDeviceId;
1337     std::string remoteDeviceId = want.GetElement().GetDeviceID();
1338     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, remoteDeviceId)) {
1339         HILOGE("ConnectRemoteAbility check deviceId failed");
1340         return INVALID_PARAMETERS_ERR;
1341     }
1342     CallerInfo callerInfo = { callerUid, callerPid, CALLER_TYPE_HARMONY, localDeviceId };
1343     callerInfo.accessToken = accessToken;
1344     {
1345         std::lock_guard<std::mutex> autoLock(distributedLock_);
1346         int32_t checkResult = CheckDistributedConnectLocked(callerInfo);
1347         if (checkResult != ERR_OK) {
1348             return checkResult;
1349         }
1350     }
1351     if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
1352         HILOGE("GetCallerAppIdFromBms failed");
1353         return INVALID_PARAMETERS_ERR;
1354     }
1355     if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
1356         HILOGE("GetBundleNameListFromBms failed");
1357         return INVALID_PARAMETERS_ERR;
1358     }
1359     callerInfo.extraInfoJson[DMS_VERSION_ID] = DMS_VERSION;
1360     HILOGD("[PerformanceTest] ConnectRemoteAbility begin");
1361     int32_t result = TryConnectRemoteAbility(want, connect, callerInfo);
1362     if (result != ERR_OK) {
1363         HILOGE("ConnectRemoteAbility result is %{public}d", result);
1364     }
1365     HILOGD("[PerformanceTest] ConnectRemoteAbility end");
1366     return result;
1367 }
1368 
TryConnectRemoteAbility(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,const CallerInfo & callerInfo)1369 int32_t DistributedSchedService::TryConnectRemoteAbility(const OHOS::AAFwk::Want& want,
1370     const sptr<IRemoteObject>& connect, const CallerInfo& callerInfo)
1371 {
1372     AppExecFwk::AbilityInfo abilityInfo;
1373     AccountInfo accountInfo;
1374     std::string remoteDeviceId = want.GetElement().GetDeviceID();
1375     sptr<IDistributedSched> remoteDms = GetRemoteDms(remoteDeviceId);
1376     if (remoteDms == nullptr || connect == nullptr) {
1377         HILOGE("TryConnectRemoteAbility invalid parameters");
1378         return INVALID_PARAMETERS_ERR;
1379     }
1380     int32_t ret = DistributedSchedPermission::GetInstance().GetAccountInfo(remoteDeviceId, callerInfo, accountInfo);
1381     if (ret != ERR_OK) {
1382         HILOGE("GetAccountInfo failed");
1383         return ret;
1384     }
1385     int32_t retryTimes = BIND_CONNECT_RETRY_TIMES;
1386     int32_t result = REMOTE_DEVICE_BIND_ABILITY_ERR;
1387     while (retryTimes--) {
1388         int64_t start = GetTickCount();
1389         HILOGD("[PerformanceTest] ConnectRemoteAbility begin");
1390         result = remoteDms->ConnectAbilityFromRemote(want, abilityInfo, connect, callerInfo, accountInfo);
1391         HILOGD("[PerformanceTest] ConnectRemoteAbility end");
1392         if (result == ERR_OK) {
1393             std::lock_guard<std::mutex> autoLock(distributedLock_);
1394             RemoteConnectAbilityMappingLocked(connect, callerInfo.sourceDeviceId, remoteDeviceId,
1395                 want.GetElement(), callerInfo, TargetComponent::HARMONY_COMPONENT);
1396             break;
1397         }
1398         if (result == INVALID_REMOTE_PARAMETERS_ERR || result == REMOTE_DEVICE_BIND_ABILITY_ERR) {
1399             break;
1400         }
1401         int64_t elapsedTime = GetTickCount() - start;
1402         if (elapsedTime > BIND_CONNECT_TIMEOUT) {
1403             HILOGW("ConnectRemoteAbility timeout, elapsedTime is %{public}" PRId64 " ms", elapsedTime);
1404             break;
1405         }
1406     }
1407     return result;
1408 }
1409 
ProcessCallerDied(const sptr<IRemoteObject> & connect,int32_t deviceType)1410 void DistributedSchedService::ProcessCallerDied(const sptr<IRemoteObject>& connect, int32_t deviceType)
1411 {
1412     if (connect == nullptr) {
1413         HILOGE("ProcessCallerDied connect is null");
1414         return;
1415     }
1416     HILOGI("Caller Died DeviceType : %{public}d", deviceType);
1417     if (deviceType == IDistributedSched::CALLER) {
1418         HandleLocalCallerDied(connect);
1419         return;
1420     }
1421     sptr<IRemoteObject> callbackWrapper = connect;
1422     CallerInfo callerInfo;
1423     AppExecFwk::ElementName element;
1424     EventNotify tempEvent;
1425     {
1426         std::lock_guard<std::mutex> autoLock(calleeLock_);
1427         auto itConnect = calleeMap_.find(connect);
1428         if (itConnect != calleeMap_.end()) {
1429             callbackWrapper = itConnect->second.callbackWrapper;
1430             element = itConnect->second.element;
1431             callerInfo = itConnect->second.callerInfo;
1432             ReportDistributedComponentChange(itConnect->second, DISTRIBUTED_COMPONENT_REMOVE,
1433                 IDistributedSched::CALL, IDistributedSched::CALLEE);
1434 
1435             GetCurDestCollaborateEvent(callerInfo, element, DMS_DSCHED_EVENT_STOP, ERR_OK, tempEvent);
1436             NotifyDSchedEventCallbackResult(ERR_OK, tempEvent);
1437             calleeMap_.erase(itConnect);
1438         } else {
1439             HILOGW("ProcessCallerDied connect not found");
1440         }
1441     }
1442     UnregisterAppStateObserver(callbackWrapper);
1443     int32_t result = DistributedSchedAdapter::GetInstance().ReleaseAbility(callbackWrapper, element);
1444     if (result != ERR_OK) {
1445         HILOGW("ProcessCallerDied failed, error: %{public}d", result);
1446     }
1447     GetCurDestCollaborateEvent(callerInfo, element, DMS_DSCHED_EVENT_FINISH, result, tempEvent);
1448     NotifyDSchedEventCallbackResult(result, tempEvent);
1449 }
1450 
HandleLocalCallerDied(const sptr<IRemoteObject> & connect)1451 void DistributedSchedService::HandleLocalCallerDied(const sptr<IRemoteObject>& connect)
1452 {
1453     {
1454         std::lock_guard<std::mutex> autoLock(callerLock_);
1455         auto it = callerMap_.find(connect);
1456         if (it != callerMap_.end()) {
1457             std::list<ConnectAbilitySession> sessionsList = it->second;
1458             if (!sessionsList.empty()) {
1459                 ReportDistributedComponentChange(sessionsList.front().GetCallerInfo(), DISTRIBUTED_COMPONENT_REMOVE,
1460                     IDistributedSched::CALL, IDistributedSched::CALLER);
1461             }
1462             NotifyCollaborateEventWithSessions(sessionsList, DMS_DSCHED_EVENT_FINISH, ERR_OK);
1463             callerMap_.erase(it);
1464             HILOGI("remove connection success");
1465         } else {
1466             HILOGW("HandleLocalCallerDied connect not found");
1467         }
1468     }
1469     {
1470         std::lock_guard<std::mutex> autoLock(callLock_);
1471         for (auto iter = callMap_.begin(); iter != callMap_.end(); iter++) {
1472             if (iter->first == connect) {
1473                 callMap_.erase(iter);
1474                 HILOGI("remove callMap_ connect success");
1475                 break;
1476             }
1477         }
1478     }
1479 }
1480 
ProcessCalleeDied(const sptr<IRemoteObject> & connect)1481 void DistributedSchedService::ProcessCalleeDied(const sptr<IRemoteObject>& connect)
1482 {
1483     if (connect == nullptr) {
1484         HILOGE("ProcessCalleeDied connect is null");
1485         return;
1486     }
1487     sptr<IRemoteObject> callbackWrapper;
1488     CallerInfo callerInfo;
1489     AppExecFwk::ElementName element;
1490     EventNotify tempEvent;
1491     {
1492         std::lock_guard<std::mutex> autoLock(calleeLock_);
1493         auto itConnect = calleeMap_.find(connect);
1494         if (itConnect != calleeMap_.end()) {
1495             ReportDistributedComponentChange(itConnect->second, DISTRIBUTED_COMPONENT_REMOVE,
1496                 IDistributedSched::CALL, IDistributedSched::CALLEE);
1497             callbackWrapper = itConnect->second.callbackWrapper;
1498             callerInfo = itConnect->second.callerInfo;
1499             element = itConnect->second.element;
1500             calleeMap_.erase(itConnect);
1501         } else {
1502             HILOGW("ProcessCalleeDied connect not found");
1503             return;
1504         }
1505     }
1506     GetCurDestCollaborateEvent(callerInfo, element, DMS_DSCHED_EVENT_STOP, ERR_OK, tempEvent);
1507     NotifyDSchedEventCallbackResult(ERR_OK, tempEvent);
1508 
1509     UnregisterAppStateObserver(callbackWrapper);
1510     GetCurDestCollaborateEvent(callerInfo, element, DMS_DSCHED_EVENT_FINISH, ERR_OK, tempEvent);
1511     NotifyDSchedEventCallbackResult(ERR_OK, tempEvent);
1512 }
1513 
ProcessCallResult(const sptr<IRemoteObject> & calleeConnect,const sptr<IRemoteObject> & callerConnect)1514 void DistributedSchedService::ProcessCallResult(const sptr<IRemoteObject>& calleeConnect,
1515     const sptr<IRemoteObject>& callerConnect)
1516 {
1517     sptr<IRemoteObject> token;
1518     AbilityManagerClient::GetInstance()->GetAbilityTokenByCalleeObj(calleeConnect, token);
1519     if (token == nullptr) {
1520         return;
1521     }
1522     std::lock_guard<std::mutex> autoLock(observerLock_);
1523     for (auto iter = observerMap_.begin(); iter != observerMap_.end(); iter++) {
1524         if (iter->second.srcConnect == callerConnect) {
1525             iter->second.token = token;
1526             return;
1527         }
1528     }
1529     HILOGE("observerMap can not find callerConnect");
1530 }
1531 
TryStartRemoteAbilityByCall(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,const CallerInfo & callerInfo)1532 int32_t DistributedSchedService::TryStartRemoteAbilityByCall(const OHOS::AAFwk::Want& want,
1533     const sptr<IRemoteObject>& connect, const CallerInfo& callerInfo)
1534 {
1535     std::string remoteDeviceId = want.GetElement().GetDeviceID();
1536     HILOGD("[PerformanceTest] TryStartRemoteAbilityByCall get remote DMS");
1537     sptr<IDistributedSched> remoteDms = GetRemoteDms(remoteDeviceId);
1538     if (remoteDms == nullptr) {
1539         HILOGE("TryStartRemoteAbilityByCall get remote DMS failed, remoteDeviceId: %{public}s",
1540             GetAnonymStr(remoteDeviceId).c_str());
1541         return INVALID_PARAMETERS_ERR;
1542     }
1543     HILOGD("[PerformanceTest] TryStartRemoteAbilityByCall RPC begin");
1544     AccountInfo accountInfo;
1545     int32_t ret = DistributedSchedPermission::GetInstance().GetAccountInfo(remoteDeviceId, callerInfo, accountInfo);
1546     if (ret != ERR_OK) {
1547         HILOGE("GetAccountInfo failed");
1548         return ret;
1549     }
1550     AAFwk::Want remoteWant = want;
1551     int32_t connectToken = SaveConnectToken(want, connect);
1552     remoteWant.SetParam(DMS_CONNECT_TOKEN, connectToken);
1553     HILOGD("connectToken is %{public}s", GetAnonymStr(std::to_string(connectToken)).c_str());
1554     int32_t result = remoteDms->StartAbilityByCallFromRemote(remoteWant, connect, callerInfo, accountInfo);
1555     HILOGD("[PerformanceTest] TryStartRemoteAbilityByCall RPC end");
1556     if (result == ERR_OK) {
1557         SaveCallerComponent(want, connect, callerInfo);
1558     } else {
1559         HILOGE("TryStartRemoteAbilityByCall failed, result : %{public}d", result);
1560     }
1561     return result;
1562 }
1563 
SaveCallerComponent(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,const CallerInfo & callerInfo)1564 void DistributedSchedService::SaveCallerComponent(const OHOS::AAFwk::Want& want,
1565     const sptr<IRemoteObject>& connect, const CallerInfo& callerInfo)
1566 {
1567     if (connect == nullptr) {
1568         HILOGW("connect is nullptr");
1569         return;
1570     }
1571     std::lock_guard<std::mutex> autoLock(callerLock_);
1572     auto itConnect = callerMap_.find(connect);
1573     if (itConnect == callerMap_.end()) {
1574         connect->AddDeathRecipient(callerDeathRecipientForLocalDevice_);
1575         ReportDistributedComponentChange(callerInfo, DISTRIBUTED_COMPONENT_ADD, IDistributedSched::CALL,
1576             IDistributedSched::CALLER);
1577     }
1578     auto& sessionsList = callerMap_[connect];
1579     std::string remoteDeviceId = want.GetElement().GetDeviceID();
1580     for (auto& session : sessionsList) {
1581         if (remoteDeviceId == session.GetDestinationDeviceId()) {
1582             session.AddElement(want.GetElement());
1583             // already added session for remote device
1584             return;
1585         }
1586     }
1587     // connect to another remote device, add a new session to list
1588     auto& session = sessionsList.emplace_back(callerInfo.sourceDeviceId, remoteDeviceId, callerInfo);
1589     session.AddElement(want.GetElement());
1590 
1591     HILOGD("add connection success");
1592     EventNotify tempEvent;
1593     GetCurSrcCollaborateEvent(callerInfo, want.GetElement(), DMS_DSCHED_EVENT_PROCESSING, ERR_OK, tempEvent);
1594     NotifyDSchedEventCallbackResult(ERR_OK, tempEvent);
1595 }
1596 
RemoveCallerComponent(const sptr<IRemoteObject> & connect)1597 void DistributedSchedService::RemoveCallerComponent(const sptr<IRemoteObject>& connect)
1598 {
1599     if (connect == nullptr) {
1600         HILOGW("connect is nullptr");
1601         return;
1602     }
1603     {
1604         std::lock_guard<std::mutex> autoLock(callerLock_);
1605         auto it = callerMap_.find(connect);
1606         if (it != callerMap_.end()) {
1607             connect->RemoveDeathRecipient(callerDeathRecipientForLocalDevice_);
1608             std::list<ConnectAbilitySession> sessionsList = it->second;
1609             if (!sessionsList.empty()) {
1610                 ReportDistributedComponentChange(sessionsList.front().GetCallerInfo(), DISTRIBUTED_COMPONENT_REMOVE,
1611                     IDistributedSched::CALL, IDistributedSched::CALLER);
1612             }
1613             NotifyCollaborateEventWithSessions(sessionsList, DMS_DSCHED_EVENT_FINISH, ERR_OK);
1614             callerMap_.erase(it);
1615             HILOGI("remove connection success");
1616         } else {
1617             HILOGW("RemoveCallerComponent connect not found");
1618         }
1619     }
1620     {
1621         std::lock_guard<std::mutex> autoLock(callLock_);
1622         for (auto iter = callMap_.begin(); iter != callMap_.end(); iter++) {
1623             if (iter->first == connect) {
1624                 callMap_.erase(iter);
1625                 HILOGI("remove callMap_ connect success");
1626                 break;
1627             }
1628         }
1629     }
1630 }
1631 
ProcessCalleeOffline(const std::string & deviceId)1632 void DistributedSchedService::ProcessCalleeOffline(const std::string& deviceId)
1633 {
1634     {
1635         std::lock_guard<std::mutex> autoLock(callerLock_);
1636         for (auto iter = callerMap_.begin(); iter != callerMap_.end();) {
1637             std::list<ConnectAbilitySession>& sessionsList = iter->second;
1638             auto itSession = std::find_if(sessionsList.begin(), sessionsList.end(), [&deviceId](const auto& session) {
1639                 return session.GetDestinationDeviceId() == deviceId;
1640             });
1641             CallerInfo callerInfo;
1642             if (itSession != sessionsList.end()) {
1643                 callerInfo = itSession->GetCallerInfo();
1644                 for (const auto &element : itSession->GetElementsList()) {
1645                     EventNotify tempEvent;
1646                     GetCurSrcCollaborateEvent(callerInfo, element, DMS_DSCHED_EVENT_FINISH, ERR_OK, tempEvent);
1647                     NotifyDSchedEventCallbackResult(ERR_OK, tempEvent);
1648                 }
1649                 sessionsList.erase(itSession);
1650             }
1651 
1652             if (sessionsList.empty()) {
1653                 if (iter->first != nullptr) {
1654                     iter->first->RemoveDeathRecipient(callerDeathRecipientForLocalDevice_);
1655                 }
1656                 ReportDistributedComponentChange(callerInfo, DISTRIBUTED_COMPONENT_REMOVE,
1657                     IDistributedSched::CALL, IDistributedSched::CALLER);
1658                 iter = callerMap_.erase(iter);
1659             } else {
1660                 iter++;
1661             }
1662         }
1663     }
1664     {
1665         std::lock_guard<std::mutex> autoLock(callLock_);
1666         for (auto iter = callMap_.begin(); iter != callMap_.end();) {
1667             if (iter->second.remoteDeviceId == deviceId) {
1668                 iter = callMap_.erase(iter);
1669                 HILOGI("remove callMap_ connect success");
1670             } else {
1671                 iter++;
1672             }
1673         }
1674     }
1675 }
1676 
SaveConnectToken(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect)1677 int32_t DistributedSchedService::SaveConnectToken(const OHOS::AAFwk::Want& want, const sptr<IRemoteObject>& connect)
1678 {
1679     int32_t tToken = -1;
1680     {
1681         std::lock_guard<std::mutex> tokenLock(tokenMutex_);
1682         tToken = token_.load();
1683         if (++tToken > MAX_TOKEN_NUM) {
1684             tToken = 1;
1685         }
1686         token_.store(tToken);
1687     }
1688     {
1689         std::lock_guard<std::mutex> autoLock(callLock_);
1690         callMap_[connect] = {tToken, want.GetElement().GetDeviceID()};
1691         HILOGI("add connect success");
1692     }
1693     return tToken;
1694 }
1695 
StartRemoteAbilityByCall(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,int32_t callerUid,int32_t callerPid,uint32_t accessToken)1696 int32_t DistributedSchedService::StartRemoteAbilityByCall(const OHOS::AAFwk::Want& want,
1697     const sptr<IRemoteObject>& connect, int32_t callerUid, int32_t callerPid, uint32_t accessToken)
1698 {
1699     if (connect == nullptr) {
1700         HILOGE("StartRemoteAbilityByCall connect is null");
1701         return INVALID_PARAMETERS_ERR;
1702     }
1703     std::string localDeviceId;
1704     std::string remoteDeviceId = want.GetElement().GetDeviceID();
1705     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, remoteDeviceId)) {
1706         HILOGE("StartRemoteAbilityByCall check deviceId failed");
1707         return INVALID_PARAMETERS_ERR;
1708     }
1709     CallerInfo callerInfo = { callerUid, callerPid };
1710     callerInfo.sourceDeviceId = localDeviceId;
1711     callerInfo.accessToken = accessToken;
1712     if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
1713         HILOGE("GetCallerAppIdFromBms failed");
1714         return INVALID_PARAMETERS_ERR;
1715     }
1716     if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
1717         HILOGE("GetBundleNameListFromBms failed");
1718         return INVALID_PARAMETERS_ERR;
1719     }
1720     callerInfo.extraInfoJson[DMS_VERSION_ID] = DMS_VERSION;
1721     std::string uidSpecBundleName;
1722     if (!BundleManagerInternal::GetSpecifyBundleNameFromBms(callerInfo.uid, uidSpecBundleName)) {
1723         HILOGE("Get specify bundle name for from Bms fail, connect session caller uid %{public}d.", callerInfo.uid);
1724     }
1725     callerInfo.extraInfoJson[DMS_UID_SPEC_BUNDLE_NAME] = uidSpecBundleName;
1726 
1727     EventNotify tempEvent;
1728     GetCurSrcCollaborateEvent(callerInfo, want.GetElement(), DMS_DSCHED_EVENT_START, ERR_OK, tempEvent);
1729     NotifyDSchedEventCallbackResult(ERR_OK, tempEvent);
1730 
1731     int32_t ret = TryStartRemoteAbilityByCall(want, connect, callerInfo);
1732     if (ret != ERR_OK) {
1733         {
1734             std::lock_guard<std::mutex> autoLock(callLock_);
1735             callMap_.erase(connect);
1736         }
1737         HILOGE("StartRemoteAbilityByCall result is %{public}d", ret);
1738     }
1739     return ret;
1740 }
1741 
ReleaseRemoteAbility(const sptr<IRemoteObject> & connect,const AppExecFwk::ElementName & element)1742 int32_t DistributedSchedService::ReleaseRemoteAbility(const sptr<IRemoteObject>& connect,
1743     const AppExecFwk::ElementName &element)
1744 {
1745     if (connect == nullptr) {
1746         HILOGE("ReleaseRemoteAbility connect is null");
1747         return INVALID_PARAMETERS_ERR;
1748     }
1749     if (element.GetDeviceID().empty()) {
1750         HILOGE("ReleaseRemoteAbility remote deviceId empty");
1751         return INVALID_PARAMETERS_ERR;
1752     }
1753     sptr<IDistributedSched> remoteDms = GetRemoteDms(element.GetDeviceID());
1754     if (remoteDms == nullptr) {
1755         HILOGE("ReleaseRemoteAbility get remote dms failed, devId: %{public}s",
1756             GetAnonymStr(element.GetDeviceID()).c_str());
1757         return INVALID_PARAMETERS_ERR;
1758     }
1759     CallerInfo callerInfo;
1760     if (!GetLocalDeviceId(callerInfo.sourceDeviceId)) {
1761         HILOGE("ReleaseRemoteAbility get local deviceId failed");
1762         return INVALID_PARAMETERS_ERR;
1763     }
1764     int32_t result = remoteDms->ReleaseAbilityFromRemote(connect, element, callerInfo);
1765     if (result == ERR_OK) {
1766         RemoveCallerComponent(connect);
1767     } else {
1768         HILOGE("ReleaseRemoteAbility result is %{public}d", result);
1769     }
1770     return result;
1771 }
1772 
StartAbilityByCallFromRemote(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,const CallerInfo & callerInfo,const AccountInfo & accountInfo)1773 int32_t DistributedSchedService::StartAbilityByCallFromRemote(const OHOS::AAFwk::Want& want,
1774     const sptr<IRemoteObject>& connect, const CallerInfo& callerInfo, const AccountInfo& accountInfo)
1775 {
1776     HILOGD("[PerformanceTest] DistributedSchedService StartAbilityByCallFromRemote begin");
1777     if (connect == nullptr) {
1778         HILOGE("StartAbilityByCallFromRemote connect is null");
1779         return INVALID_REMOTE_PARAMETERS_ERR;
1780     }
1781 
1782     EventNotify tempEvent;
1783     GetCurDestCollaborateEvent(callerInfo, want.GetElement(), DMS_DSCHED_EVENT_START, ERR_OK, tempEvent);
1784     NotifyDSchedEventCallbackResult(ERR_OK, tempEvent);
1785 
1786     std::string localDeviceId;
1787     std::string destinationDeviceId = want.GetElement().GetDeviceID();
1788     if (!GetLocalDeviceId(localDeviceId) ||
1789         !CheckDeviceIdFromRemote(localDeviceId, destinationDeviceId, callerInfo.sourceDeviceId)) {
1790         HILOGE("StartAbilityByCallFromRemote check deviceId failed");
1791         return INVALID_REMOTE_PARAMETERS_ERR;
1792     }
1793     int32_t result = CheckTargetPermission(want, callerInfo, accountInfo, CALL_PERMISSION, false);
1794     if (result != ERR_OK) {
1795         HILOGE("CheckTargetPermission failed!!");
1796         return result;
1797     }
1798 
1799     sptr<IRemoteObject> callbackWrapper;
1800     {
1801         std::lock_guard<std::mutex> autoLock(calleeLock_);
1802         auto itConnect = calleeMap_.find(connect);
1803         if (itConnect != calleeMap_.end()) {
1804             callbackWrapper = itConnect->second.callbackWrapper;
1805         } else {
1806             callbackWrapper = new AbilityConnectionWrapperStub(connect, localDeviceId);
1807         }
1808     }
1809     int32_t errCode = DistributedSchedAdapter::GetInstance().StartAbilityByCall(want, callbackWrapper, this);
1810     HILOGD("[PerformanceTest] StartAbilityByCallFromRemote end");
1811     if (errCode == ERR_OK) {
1812         {
1813             std::lock_guard<std::mutex> autoLock(calleeLock_);
1814             ConnectInfo connectInfo {callerInfo, callbackWrapper, want.GetElement()};
1815             ReportDistributedComponentChange(connectInfo, DISTRIBUTED_COMPONENT_ADD,
1816                 IDistributedSched::CALL, IDistributedSched::CALLEE);
1817             calleeMap_.emplace(connect, connectInfo);
1818         }
1819         connect->AddDeathRecipient(callerDeathRecipient_);
1820         if (!RegisterAppStateObserver(want, callerInfo, connect, callbackWrapper)) {
1821             HILOGE("RegisterAppStateObserver failed");
1822         }
1823     }
1824 
1825     GetCurDestCollaborateEvent(callerInfo, want.GetElement(), DMS_DSCHED_EVENT_PROCESSING, ERR_OK, tempEvent);
1826     NotifyDSchedEventCallbackResult(ERR_OK, tempEvent);
1827     return errCode;
1828 }
1829 
ReleaseAbilityFromRemote(const sptr<IRemoteObject> & connect,const AppExecFwk::ElementName & element,const CallerInfo & callerInfo)1830 int32_t DistributedSchedService::ReleaseAbilityFromRemote(const sptr<IRemoteObject>& connect,
1831     const AppExecFwk::ElementName &element, const CallerInfo& callerInfo)
1832 {
1833     if (connect == nullptr) {
1834         HILOGE("ReleaseAbilityFromRemote connect is null");
1835         return INVALID_REMOTE_PARAMETERS_ERR;
1836     }
1837     EventNotify tempEvent;
1838     GetCurDestCollaborateEvent(callerInfo, element, DMS_DSCHED_EVENT_STOP, ERR_OK, tempEvent);
1839     NotifyDSchedEventCallbackResult(ERR_OK, tempEvent);
1840 
1841     HILOGD("[PerformanceTest] ReleaseAbilityFromRemote begin");
1842     std::string localDeviceId;
1843     if (!GetLocalDeviceId(localDeviceId) || localDeviceId.empty() ||
1844         callerInfo.sourceDeviceId.empty() || localDeviceId == callerInfo.sourceDeviceId) {
1845         HILOGE("ReleaseAbilityFromRemote check deviceId failed");
1846         return INVALID_REMOTE_PARAMETERS_ERR;
1847     }
1848 
1849     sptr<IRemoteObject> callbackWrapper;
1850     {
1851         std::lock_guard<std::mutex> autoLock(calleeLock_);
1852         auto itConnect = calleeMap_.find(connect);
1853         if (itConnect == calleeMap_.end()) {
1854             HILOGE("ReleaseAbilityFromRemote callee not found");
1855             return INVALID_REMOTE_PARAMETERS_ERR;
1856         }
1857         callbackWrapper = itConnect->second.callbackWrapper;
1858         ReportDistributedComponentChange(itConnect->second, DISTRIBUTED_COMPONENT_REMOVE,
1859             IDistributedSched::CALL, IDistributedSched::CALLEE);
1860         calleeMap_.erase(itConnect);
1861         connect->RemoveDeathRecipient(callerDeathRecipient_);
1862     }
1863     UnregisterAppStateObserver(callbackWrapper);
1864     int32_t result = DistributedSchedAdapter::GetInstance().ReleaseAbility(callbackWrapper, element);
1865     HILOGD("[PerformanceTest] ReleaseAbilityFromRemote end");
1866     if (result != ERR_OK) {
1867         HILOGE("ReleaseAbilityFromRemote failed, error: %{public}d", result);
1868     }
1869     GetCurDestCollaborateEvent(callerInfo, element, DMS_DSCHED_EVENT_FINISH, result, tempEvent);
1870     NotifyDSchedEventCallbackResult(result, tempEvent);
1871     return result;
1872 }
1873 
1874 #ifdef SUPPORT_DISTRIBUTED_FORM_SHARE
StartRemoteShareForm(const std::string & remoteDeviceId,const OHOS::AppExecFwk::FormShareInfo & formShareInfo)1875 int32_t DistributedSchedService::StartRemoteShareForm(const std::string& remoteDeviceId,
1876     const OHOS::AppExecFwk::FormShareInfo& formShareInfo)
1877 {
1878     HILOGD("SHAREFORM:: func call");
1879 
1880     if (remoteDeviceId.empty()) {
1881         HILOGE("StartRemoteShareForm input params error");
1882         return INVALID_PARAMETERS_ERR;
1883     }
1884 
1885     sptr<IDistributedSched> remoteDms = GetRemoteDms(remoteDeviceId);
1886     if (remoteDms == nullptr) {
1887         HILOGE("StartRemoteShareForm get remote DMS failed, remoteDeviceId: %{public}s",
1888             GetAnonymStr(remoteDeviceId).c_str());
1889         return GET_REMOTE_DMS_FAIL;
1890     }
1891     std::string localDeviceId = "";
1892     GetLocalDeviceId(localDeviceId);
1893     OHOS::AppExecFwk::FormShareInfo formShareInfoCopy;
1894     formShareInfoCopy.formId = formShareInfo.formId;
1895     formShareInfoCopy.formName = formShareInfo.formName;
1896     formShareInfoCopy.bundleName = formShareInfo.bundleName;
1897     formShareInfoCopy.moduleName = formShareInfo.moduleName;
1898     formShareInfoCopy.abilityName = formShareInfo.abilityName;
1899     formShareInfoCopy.formTempFlag = formShareInfo.formTempFlag;
1900     formShareInfoCopy.dimensionId = formShareInfo.dimensionId;
1901     formShareInfoCopy.providerShareData = formShareInfo.providerShareData;
1902     formShareInfoCopy.deviceId = localDeviceId;
1903     int32_t result = remoteDms->StartShareFormFromRemote(remoteDeviceId, formShareInfoCopy);
1904     HILOGD("[PerformanceTest] StartRemoteShareForm RPC end");
1905     if (result != ERR_OK) {
1906         HILOGE("StartRemoteShareForm failed, result : %{public}d", result);
1907     }
1908     return result;
1909 }
1910 
StartShareFormFromRemote(const std::string & remoteDeviceId,const OHOS::AppExecFwk::FormShareInfo & formShareInfo)1911 int32_t DistributedSchedService::StartShareFormFromRemote(
1912     const std::string& remoteDeviceId, const OHOS::AppExecFwk::FormShareInfo& formShareInfo)
1913 {
1914     HILOGD("SHAREFORM:: func call begin");
1915     std::string localDeviceId = "";
1916     GetLocalDeviceId(localDeviceId);
1917     if (CheckDeviceId(localDeviceId, remoteDeviceId)) {
1918         HILOGE("localId is %{public}s != %{public}s", GetAnonymStr(localDeviceId).c_str(),
1919             GetAnonymStr(remoteDeviceId).c_str());
1920         return INVALID_REMOTE_PARAMETERS_ERR;
1921     }
1922 
1923     auto formMgr = GetFormMgrProxy();
1924     if (formMgr == nullptr) {
1925         HILOGE("get form mgr proxy failed.");
1926         return NOT_FIND_SERVICE_PROXY;
1927     }
1928 
1929     auto result = formMgr->RecvFormShareInfoFromRemote(formShareInfo);
1930     HILOGD("SHAREFORM:: func call end");
1931     return result;
1932 }
1933 #endif
1934 
GetDistributedComponentList(std::vector<std::string> & distributedComponents)1935 int32_t DistributedSchedService::GetDistributedComponentList(std::vector<std::string>& distributedComponents)
1936 {
1937     GetConnectComponentList(distributedComponents);
1938     GetCallComponentList(distributedComponents);
1939     return ERR_OK;
1940 }
1941 
GetConnectComponentList(std::vector<std::string> & distributedComponents)1942 void DistributedSchedService::GetConnectComponentList(std::vector<std::string>& distributedComponents)
1943 {
1944     {
1945         std::lock_guard<std::mutex> autoLock(distributedLock_);
1946         for (const auto& iter : distributedConnectAbilityMap_) {
1947             if (iter.second.empty()) {
1948                 continue;
1949             }
1950             CallerInfo callerInfo = iter.second.front().GetCallerInfo();
1951             nlohmann::json componentInfoJson;
1952             componentInfoJson[PID_KEY] = callerInfo.pid;
1953             componentInfoJson[UID_KEY] = callerInfo.uid;
1954             componentInfoJson[BUNDLE_NAME_KEY] =
1955                 callerInfo.bundleNames.empty() ? std::string() : callerInfo.bundleNames.front();
1956             componentInfoJson[COMPONENT_TYPE_KEY] = IDistributedSched::CONNECT;
1957             componentInfoJson[DEVICE_TYPE_KEY] = IDistributedSched::CALLER;
1958             std::string componentInfo = componentInfoJson.dump();
1959             distributedComponents.emplace_back(componentInfo);
1960         }
1961     }
1962     {
1963         std::lock_guard<std::mutex> autoLock(connectLock_);
1964         for (const auto& iter : connectAbilityMap_) {
1965             ConnectInfo connectInfo = iter.second;
1966             nlohmann::json componentInfoJson;
1967             componentInfoJson[UID_KEY] = BundleManagerInternal::GetUidFromBms(connectInfo.element.GetBundleName());
1968             componentInfoJson[BUNDLE_NAME_KEY] = connectInfo.element.GetBundleName();
1969             componentInfoJson[COMPONENT_TYPE_KEY] = IDistributedSched::CONNECT;
1970             componentInfoJson[DEVICE_TYPE_KEY] = IDistributedSched::CALLEE;
1971             std::string componentInfo = componentInfoJson.dump();
1972             distributedComponents.emplace_back(componentInfo);
1973         }
1974     }
1975 }
1976 
GetCallComponentList(std::vector<std::string> & distributedComponents)1977 void DistributedSchedService::GetCallComponentList(std::vector<std::string>& distributedComponents)
1978 {
1979     {
1980         std::lock_guard<std::mutex> autoLock(callerLock_);
1981         for (const auto& iter : callerMap_) {
1982             if (iter.second.empty()) {
1983                 continue;
1984             }
1985             CallerInfo callerInfo = iter.second.front().GetCallerInfo();
1986             nlohmann::json componentInfoJson;
1987             componentInfoJson[PID_KEY] = callerInfo.pid;
1988             componentInfoJson[UID_KEY] = callerInfo.uid;
1989             componentInfoJson[BUNDLE_NAME_KEY] =
1990                 callerInfo.bundleNames.empty() ? std::string() : callerInfo.bundleNames.front();
1991             componentInfoJson[COMPONENT_TYPE_KEY] = IDistributedSched::CALL;
1992             componentInfoJson[DEVICE_TYPE_KEY] = IDistributedSched::CALLER;
1993             std::string componentInfo = componentInfoJson.dump();
1994             distributedComponents.emplace_back(componentInfo);
1995         }
1996     }
1997     {
1998         std::lock_guard<std::mutex> autoLock(calleeLock_);
1999         for (const auto& iter : calleeMap_) {
2000             ConnectInfo connectInfo = iter.second;
2001             nlohmann::json componentInfoJson;
2002             componentInfoJson[UID_KEY] = BundleManagerInternal::GetUidFromBms(connectInfo.element.GetBundleName());
2003             componentInfoJson[BUNDLE_NAME_KEY] = connectInfo.element.GetBundleName();
2004             componentInfoJson[COMPONENT_TYPE_KEY] = IDistributedSched::CALL;
2005             componentInfoJson[DEVICE_TYPE_KEY] = IDistributedSched::CALLEE;
2006             std::string componentInfo = componentInfoJson.dump();
2007             distributedComponents.emplace_back(componentInfo);
2008         }
2009     }
2010 }
2011 
ReportDistributedComponentChange(const CallerInfo & callerInfo,int32_t changeType,int32_t componentType,int32_t deviceType)2012 void DistributedSchedService::ReportDistributedComponentChange(const CallerInfo& callerInfo, int32_t changeType,
2013     int32_t componentType, int32_t deviceType)
2014 {
2015 #if defined(EFFICIENCY_MANAGER_ENABLE) || defined(SUPPORT_DISTRIBUTEDCOMPONENT_TO_MEMMGR)
2016     HILOGI("caller report");
2017     auto func = [this, callerInfo, changeType, componentType, deviceType]() {
2018 #ifdef EFFICIENCY_MANAGER_ENABLE
2019         std::unordered_map<std::string, std::string> payload;
2020         payload[PID_KEY] = std::to_string(callerInfo.pid);
2021         payload[UID_KEY] = std::to_string(callerInfo.uid);
2022         payload[BUNDLE_NAME_KEY] =
2023             callerInfo.bundleNames.empty() ? std::string() : callerInfo.bundleNames.front();
2024         payload[COMPONENT_TYPE_KEY] = std::to_string(componentType);
2025         payload[DEVICE_TYPE_KEY] = std::to_string(deviceType);
2026         payload[CHANGE_TYPE_KEY] = std::to_string(changeType);
2027         uint32_t type = ResourceSchedule::ResType::RES_TYPE_REPORT_DISTRIBUTE_COMPONENT_CHANGE;
2028         ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
2029 #endif
2030 #ifdef SUPPORT_DISTRIBUTEDCOMPONENT_TO_MEMMGR
2031         Memory::MemMgrClient::GetInstance().NotifyDistDevStatus(callerInfo.pid, callerInfo.uid,
2032             callerInfo.bundleNames.empty() ? std::string() : callerInfo.bundleNames.front(),
2033             changeType == DISTRIBUTED_COMPONENT_ADD);
2034 #endif
2035     };
2036     if (componentChangeHandler_ != nullptr) {
2037         componentChangeHandler_->PostTask(func);
2038         return;
2039     }
2040     HILOGE("HandleDistributedComponentChange handler postTask failed");
2041 #endif
2042 }
2043 
ReportDistributedComponentChange(const ConnectInfo & connectInfo,int32_t changeType,int32_t componentType,int32_t deviceType)2044 void DistributedSchedService::ReportDistributedComponentChange(const ConnectInfo& connectInfo, int32_t changeType,
2045     int32_t componentType, int32_t deviceType)
2046 {
2047 #ifdef EFFICIENCY_MANAGER_ENABLE
2048     HILOGI("callee report");
2049     auto func = [this, connectInfo, changeType, componentType, deviceType]() {
2050         std::unordered_map<std::string, std::string> payload;
2051         payload[UID_KEY] = std::to_string(BundleManagerInternal::GetUidFromBms(connectInfo.element.GetBundleName()));
2052         payload[BUNDLE_NAME_KEY] = connectInfo.element.GetBundleName();
2053         payload[COMPONENT_TYPE_KEY] = std::to_string(componentType);
2054         payload[DEVICE_TYPE_KEY] = std::to_string(deviceType);
2055         payload[CHANGE_TYPE_KEY] = std::to_string(changeType);
2056         uint32_t type = ResourceSchedule::ResType::RES_TYPE_REPORT_DISTRIBUTE_COMPONENT_CHANGE;
2057         ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
2058     };
2059     if (componentChangeHandler_ != nullptr) {
2060         componentChangeHandler_->PostTask(func);
2061         return;
2062     }
2063     HILOGE("HandleDistributedComponentChange handler postTask failed");
2064 #endif
2065 }
2066 
GetRemoteDms(const std::string & remoteDeviceId)2067 sptr<IDistributedSched> DistributedSchedService::GetRemoteDms(const std::string& remoteDeviceId)
2068 {
2069     if (remoteDeviceId.empty()) {
2070         HILOGE("GetRemoteDms remoteDeviceId is empty");
2071         return nullptr;
2072     }
2073     HILOGD("GetRemoteDms connect deviceid is %s", GetAnonymStr(remoteDeviceId).c_str());
2074     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
2075     if (samgr == nullptr) {
2076         HILOGE("GetRemoteDms failed to connect to systemAbilityMgr!");
2077         return nullptr;
2078     }
2079     HILOGI("[PerformanceTest] GetRemoteDms begin");
2080     auto object = samgr->CheckSystemAbility(DISTRIBUTED_SCHED_SA_ID, remoteDeviceId);
2081     HILOGI("[PerformanceTest] GetRemoteDms end");
2082     if (object == nullptr) {
2083         HILOGE("GetRemoteDms failed to get remote DistributedSched %{private}s", GetAnonymStr(remoteDeviceId).c_str());
2084         return nullptr;
2085     }
2086     return iface_cast<IDistributedSched>(object);
2087 }
2088 
GetLocalDeviceId(std::string & localDeviceId)2089 bool DistributedSchedService::GetLocalDeviceId(std::string& localDeviceId)
2090 {
2091     if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(localDeviceId)) {
2092         HILOGE("GetLocalDeviceId failed");
2093         return false;
2094     }
2095     return true;
2096 }
2097 
CheckDeviceId(const std::string & localDeviceId,const std::string & remoteDeviceId)2098 bool DistributedSchedService::CheckDeviceId(const std::string& localDeviceId, const std::string& remoteDeviceId)
2099 {
2100     // remoteDeviceId must not same with localDeviceId
2101     if (localDeviceId.empty() || remoteDeviceId.empty() || localDeviceId == remoteDeviceId) {
2102         HILOGE("check deviceId failed");
2103         return false;
2104     }
2105     return true;
2106 }
2107 
CheckDeviceIdFromRemote(const std::string & localDeviceId,const std::string & destinationDeviceId,const std::string & sourceDeviceId)2108 bool DistributedSchedService::CheckDeviceIdFromRemote(const std::string& localDeviceId,
2109     const std::string& destinationDeviceId, const std::string& sourceDeviceId)
2110 {
2111     if (localDeviceId.empty() || destinationDeviceId.empty() || sourceDeviceId.empty()) {
2112         HILOGE("CheckDeviceIdFromRemote failed");
2113         return false;
2114     }
2115     // destinationDeviceId set by remote must be same with localDeviceId
2116     if (localDeviceId != destinationDeviceId) {
2117         HILOGE("destinationDeviceId is not same with localDeviceId");
2118         return false;
2119     }
2120     HILOGD("CheckDeviceIdFromRemote sourceDeviceId %s", GetAnonymStr(sourceDeviceId).c_str());
2121     HILOGD("CheckDeviceIdFromRemote localDeviceId %s", GetAnonymStr(localDeviceId).c_str());
2122     HILOGD("CheckDeviceIdFromRemote destinationDeviceId %s", GetAnonymStr(destinationDeviceId).c_str());
2123 
2124     if (sourceDeviceId == destinationDeviceId || sourceDeviceId == localDeviceId) {
2125         HILOGE("destinationDeviceId is different with localDeviceId and destinationDeviceId");
2126         return false;
2127     }
2128 
2129     if (sourceDeviceId != IPCSkeleton::GetCallingDeviceID()) {
2130         HILOGE("sourceDeviceId is not correct");
2131         return false;
2132     }
2133     return true;
2134 }
2135 
ConnectAbilityFromRemote(const OHOS::AAFwk::Want & want,const AppExecFwk::AbilityInfo & abilityInfo,const sptr<IRemoteObject> & connect,const CallerInfo & callerInfo,const AccountInfo & accountInfo)2136 int32_t DistributedSchedService::ConnectAbilityFromRemote(const OHOS::AAFwk::Want& want,
2137     const AppExecFwk::AbilityInfo& abilityInfo, const sptr<IRemoteObject>& connect,
2138     const CallerInfo& callerInfo, const AccountInfo& accountInfo)
2139 {
2140     HILOGD("[PerformanceTest] DistributedSchedService ConnectAbilityFromRemote begin");
2141     if (connect == nullptr) {
2142         HILOGE("ConnectAbilityFromRemote connect is null");
2143         return INVALID_REMOTE_PARAMETERS_ERR;
2144     }
2145     HILOGD("ConnectAbilityFromRemote uid is %{public}d, pid is %{public}d, AccessTokenID is %{public}s",
2146         callerInfo.uid, callerInfo.pid, GetAnonymStr(std::to_string(callerInfo.accessToken)).c_str());
2147     std::string localDeviceId;
2148     std::string destinationDeviceId = want.GetElement().GetDeviceID();
2149     if (!GetLocalDeviceId(localDeviceId) ||
2150         !CheckDeviceIdFromRemote(localDeviceId, destinationDeviceId, callerInfo.sourceDeviceId)) {
2151         HILOGE("ConnectAbilityFromRemote check deviceId failed");
2152         return INVALID_REMOTE_PARAMETERS_ERR;
2153     }
2154     int32_t result = CheckTargetPermission(want, callerInfo, accountInfo, START_PERMISSION, true);
2155     if (result != ERR_OK) {
2156         HILOGE("CheckTargetPermission failed!!");
2157         return result;
2158     }
2159 
2160     HILOGD("ConnectAbilityFromRemote callerType is %{public}d", callerInfo.callerType);
2161     sptr<IRemoteObject> callbackWrapper = connect;
2162     std::map<sptr<IRemoteObject>, ConnectInfo>::iterator itConnect;
2163     if (callerInfo.callerType == CALLER_TYPE_HARMONY) {
2164         std::lock_guard<std::mutex> autoLock(connectLock_);
2165         itConnect = connectAbilityMap_.find(connect);
2166         if (itConnect != connectAbilityMap_.end()) {
2167             callbackWrapper = itConnect->second.callbackWrapper;
2168         } else {
2169             callbackWrapper = new AbilityConnectionWrapperStub(connect);
2170         }
2171     }
2172     int32_t errCode = DistributedSchedAdapter::GetInstance().ConnectAbility(want, callbackWrapper, this);
2173     HILOGD("[PerformanceTest] ConnectAbilityFromRemote end");
2174     if (errCode == ERR_OK) {
2175         std::lock_guard<std::mutex> autoLock(connectLock_);
2176         if (itConnect == connectAbilityMap_.end()) {
2177             ConnectInfo connectInfo {callerInfo, callbackWrapper, want.GetElement()};
2178             ReportDistributedComponentChange(connectInfo, DISTRIBUTED_COMPONENT_ADD,
2179                 IDistributedSched::CONNECT, IDistributedSched::CALLEE);
2180             connectAbilityMap_.emplace(connect, connectInfo);
2181         }
2182     }
2183     return errCode;
2184 }
2185 
DisconnectEachRemoteAbilityLocked(const std::string & localDeviceId,const std::string & remoteDeviceId,const sptr<IRemoteObject> & connect)2186 int32_t DistributedSchedService::DisconnectEachRemoteAbilityLocked(const std::string& localDeviceId,
2187     const std::string& remoteDeviceId, const sptr<IRemoteObject>& connect)
2188 {
2189     sptr<IDistributedSched> remoteDms = GetRemoteDms(remoteDeviceId);
2190     if (remoteDms == nullptr) {
2191         HILOGE("DisconnectRemoteAbility get remote dms failed");
2192         return INVALID_PARAMETERS_ERR;
2193     }
2194     int32_t result = remoteDms->DisconnectAbilityFromRemote(connect, IPCSkeleton::GetCallingUid(), localDeviceId);
2195     if (result != ERR_OK) {
2196         HILOGE("DisconnectEachRemoteAbilityLocked result is %{public}d", result);
2197     }
2198     return result;
2199 }
2200 
DisconnectRemoteAbility(const sptr<IRemoteObject> & connect,int32_t callerUid,uint32_t accessToken)2201 int32_t DistributedSchedService::DisconnectRemoteAbility(const sptr<IRemoteObject>& connect, int32_t callerUid,
2202     uint32_t accessToken)
2203 {
2204     if (connect == nullptr) {
2205         HILOGE("DisconnectRemoteAbility connect is null");
2206         return INVALID_PARAMETERS_ERR;
2207     }
2208     std::list<ConnectAbilitySession> sessionsList;
2209     {
2210         std::lock_guard<std::mutex> autoLock(distributedLock_);
2211         auto it = distributedConnectAbilityMap_.find(connect);
2212         if (it != distributedConnectAbilityMap_.end()) {
2213             sessionsList = it->second;
2214             int32_t uid = GetUidLocked(sessionsList);
2215             // also decrease number when erase connect
2216             DecreaseConnectLocked(uid);
2217             connect->RemoveDeathRecipient(connectDeathRecipient_);
2218             if (!sessionsList.empty()) {
2219                 ReportDistributedComponentChange(sessionsList.front().GetCallerInfo(), DISTRIBUTED_COMPONENT_REMOVE,
2220                     IDistributedSched::CONNECT, IDistributedSched::CALLER);
2221             }
2222             distributedConnectAbilityMap_.erase(it);
2223             HILOGI("remove connection success");
2224         }
2225     }
2226     if (!sessionsList.empty()) {
2227         for (const auto& session : sessionsList) {
2228             if (session.GetTargetComponent() == TargetComponent::HARMONY_COMPONENT) {
2229                 DisconnectEachRemoteAbilityLocked(session.GetSourceDeviceId(),
2230                     session.GetDestinationDeviceId(), connect);
2231             } else {
2232                 HILOGW("DisconnectRemoteAbility non-harmony component");
2233             }
2234         }
2235         return ERR_OK;
2236     }
2237     return NO_CONNECT_CALLBACK_ERR;
2238 }
2239 
DisconnectAbilityFromRemote(const sptr<IRemoteObject> & connect,int32_t uid,const std::string & sourceDeviceId)2240 int32_t DistributedSchedService::DisconnectAbilityFromRemote(const sptr<IRemoteObject>& connect,
2241     int32_t uid, const std::string& sourceDeviceId)
2242 {
2243     if (connect == nullptr) {
2244         HILOGE("DisconnectAbilityFromRemote connect is null");
2245         return INVALID_REMOTE_PARAMETERS_ERR;
2246     }
2247 
2248     HILOGD("[PerformanceTest] DisconnectAbilityFromRemote begin");
2249     std::string localDeviceId;
2250     AppExecFwk::AbilityInfo abilityInfo;
2251     if (!GetLocalDeviceId(localDeviceId) || localDeviceId.empty() ||
2252         sourceDeviceId.empty() || localDeviceId == sourceDeviceId) {
2253         HILOGE("DisconnectAbilityFromRemote check deviceId failed");
2254         return INVALID_REMOTE_PARAMETERS_ERR;
2255     }
2256 
2257     sptr<IRemoteObject> callbackWrapper = connect;
2258     {
2259         std::lock_guard<std::mutex> autoLock(connectLock_);
2260         auto itConnect = connectAbilityMap_.find(connect);
2261         if (itConnect != connectAbilityMap_.end()) {
2262             callbackWrapper = itConnect->second.callbackWrapper;
2263             ReportDistributedComponentChange(itConnect->second, DISTRIBUTED_COMPONENT_REMOVE,
2264                 IDistributedSched::CONNECT, IDistributedSched::CALLEE);
2265             connectAbilityMap_.erase(itConnect);
2266         } else {
2267             if (!IPCSkeleton::IsLocalCalling()) {
2268                 HILOGE("DisconnectAbilityFromRemote connect not found");
2269                 return INVALID_REMOTE_PARAMETERS_ERR;
2270             }
2271         }
2272     }
2273     int32_t result = DistributedSchedAdapter::GetInstance().DisconnectAbility(callbackWrapper);
2274     HILOGD("[PerformanceTest] DisconnectAbilityFromRemote end");
2275     return result;
2276 }
2277 
NotifyProcessDiedFromRemote(const CallerInfo & callerInfo)2278 int32_t DistributedSchedService::NotifyProcessDiedFromRemote(const CallerInfo& callerInfo)
2279 {
2280     HILOGI("NotifyProcessDiedFromRemote called");
2281     int32_t errCode = ERR_OK;
2282     {
2283         std::lock_guard<std::mutex> autoLock(connectLock_);
2284         for (auto iter = connectAbilityMap_.begin(); iter != connectAbilityMap_.end();) {
2285             ConnectInfo& connectInfo = iter->second;
2286             if (callerInfo.sourceDeviceId == connectInfo.callerInfo.sourceDeviceId
2287                 && callerInfo.uid == connectInfo.callerInfo.uid
2288                 && callerInfo.pid == connectInfo.callerInfo.pid
2289                 && callerInfo.callerType == connectInfo.callerInfo.callerType) {
2290                 HILOGI("NotifyProcessDiedFromRemote erase connection success");
2291                 int32_t ret = DistributedSchedAdapter::GetInstance().DisconnectAbility(connectInfo.callbackWrapper);
2292                 if (ret != ERR_OK) {
2293                     errCode = ret;
2294                 }
2295                 ReportDistributedComponentChange(connectInfo, DISTRIBUTED_COMPONENT_REMOVE,
2296                     IDistributedSched::CONNECT, IDistributedSched::CALLEE);
2297                 iter = connectAbilityMap_.erase(iter);
2298             } else {
2299                 iter++;
2300             }
2301         }
2302     }
2303     return errCode;
2304 }
2305 
RemoveConnectAbilityInfo(const std::string & deviceId)2306 void DistributedSchedService::RemoveConnectAbilityInfo(const std::string& deviceId)
2307 {
2308     {
2309         std::lock_guard<std::mutex> autoLock(distributedLock_);
2310         for (auto iter = distributedConnectAbilityMap_.begin(); iter != distributedConnectAbilityMap_.end();) {
2311             std::list<ConnectAbilitySession>& sessionsList = iter->second;
2312             int32_t uid = GetUidLocked(sessionsList);
2313             auto itSession = std::find_if(sessionsList.begin(), sessionsList.end(), [&deviceId](const auto& session) {
2314                 return session.GetDestinationDeviceId() == deviceId;
2315             });
2316             CallerInfo callerInfo;
2317             if (itSession != sessionsList.end()) {
2318                 NotifyDeviceOfflineToAppLocked(iter->first, *itSession);
2319                 callerInfo = itSession->GetCallerInfo();
2320                 sessionsList.erase(itSession);
2321             }
2322 
2323             if (sessionsList.empty()) {
2324                 if (iter->first != nullptr) {
2325                     iter->first->RemoveDeathRecipient(connectDeathRecipient_);
2326                 }
2327                 DecreaseConnectLocked(uid);
2328                 ReportDistributedComponentChange(callerInfo, DISTRIBUTED_COMPONENT_REMOVE,
2329                     IDistributedSched::CONNECT, IDistributedSched::CALLER);
2330                 iter = distributedConnectAbilityMap_.erase(iter);
2331             } else {
2332                 iter++;
2333             }
2334         }
2335     }
2336 
2337     {
2338         std::lock_guard<std::mutex> autoLock(connectLock_);
2339         for (auto iter = connectAbilityMap_.begin(); iter != connectAbilityMap_.end();) {
2340             ConnectInfo& connectInfo = iter->second;
2341             if (deviceId == connectInfo.callerInfo.sourceDeviceId) {
2342                 DistributedSchedAdapter::GetInstance().DisconnectAbility(connectInfo.callbackWrapper);
2343                 ReportDistributedComponentChange(connectInfo, DISTRIBUTED_COMPONENT_REMOVE,
2344                     IDistributedSched::CONNECT, IDistributedSched::CALLEE);
2345                 connectAbilityMap_.erase(iter++);
2346                 HILOGI("ProcessDeviceOffline erase connection success");
2347             } else {
2348                 iter++;
2349             }
2350         }
2351     }
2352 }
2353 
QueryOsAccount(int32_t & activeAccountId)2354 ErrCode DistributedSchedService::QueryOsAccount(int32_t& activeAccountId)
2355 {
2356 #ifdef OS_ACCOUNT_PART
2357     std::vector<int32_t> ids;
2358     ErrCode err = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
2359     if (err != ERR_OK || ids.empty()) {
2360         HILOGE("QueryActiveOsAccountIds passing param invalid or return error!, err : %{public}d", err);
2361         return INVALID_PARAMETERS_ERR;
2362     }
2363     activeAccountId = ids[0];
2364 #endif
2365     return ERR_OK;
2366 }
2367 
ProcessDeviceOffline(const std::string & deviceId)2368 void DistributedSchedService::ProcessDeviceOffline(const std::string& deviceId)
2369 {
2370     HILOGI("ProcessDeviceOffline called");
2371     std::string localDeviceId;
2372     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, deviceId)) {
2373         HILOGE("ProcessDeviceOffline check deviceId failed");
2374         return;
2375     }
2376     RemoveConnectAbilityInfo(deviceId);
2377     ProcessCalleeOffline(deviceId);
2378     ProcessFreeInstallOffline(deviceId);
2379 }
2380 
ProcessFreeInstallOffline(const std::string & deviceId)2381 void DistributedSchedService::ProcessFreeInstallOffline(const std::string& deviceId)
2382 {
2383     if (dmsCallbackTask_ == nullptr) {
2384         HILOGE("callbackTask object null!");
2385         return;
2386     }
2387     dmsCallbackTask_->NotifyDeviceOffline(deviceId);
2388 }
2389 
NotifyDeviceOfflineToAppLocked(const sptr<IRemoteObject> & connect,const ConnectAbilitySession & session)2390 void DistributedSchedService::NotifyDeviceOfflineToAppLocked(const sptr<IRemoteObject>& connect,
2391     const ConnectAbilitySession& session)
2392 {
2393     std::list<AppExecFwk::ElementName> elementsList = session.GetElementsList();
2394     for (const auto& element : elementsList) {
2395         int32_t errCode = NotifyApp(connect, element, DEVICE_OFFLINE_ERR);
2396         if (errCode != ERR_NONE) {
2397             HILOGW("ProcessDeviceOffline notify failed, errCode = %{public}d", errCode);
2398         }
2399     }
2400 }
2401 
NotifyApp(const sptr<IRemoteObject> & connect,const AppExecFwk::ElementName & element,int32_t errCode)2402 int32_t DistributedSchedService::NotifyApp(const sptr<IRemoteObject>& connect,
2403     const AppExecFwk::ElementName& element, int32_t errCode)
2404 {
2405     if (connect == nullptr) {
2406         return OBJECT_NULL;
2407     }
2408     MessageParcel data;
2409     if (!data.WriteInterfaceToken(CONNECTION_CALLBACK_INTERFACE_TOKEN)) {
2410         return ERR_FLATTEN_OBJECT;
2411     }
2412     PARCEL_WRITE_HELPER(data, Parcelable, &element);
2413     PARCEL_WRITE_HELPER(data, Int32, errCode);
2414     MessageParcel reply;
2415     MessageOption option;
2416     return connect->SendRequest(IAbilityConnection::ON_ABILITY_DISCONNECT_DONE, data, reply, option);
2417 }
2418 
ProcessConnectDied(const sptr<IRemoteObject> & connect)2419 void DistributedSchedService::ProcessConnectDied(const sptr<IRemoteObject>& connect)
2420 {
2421     if (connect == nullptr) {
2422         HILOGE("ProcessConnectDied connect is null");
2423         return;
2424     }
2425 
2426     std::list<ProcessDiedNotifyInfo> notifyList;
2427     {
2428         std::lock_guard<std::mutex> autoLock(distributedLock_);
2429         auto it = distributedConnectAbilityMap_.find(connect);
2430         if (it == distributedConnectAbilityMap_.end()) {
2431             return;
2432         }
2433         std::list<ConnectAbilitySession>& connectSessionsList = it->second;
2434         if (connectSessionsList.empty()) {
2435             return;
2436         }
2437         CallerInfo callerInfo = connectSessionsList.front().GetCallerInfo();
2438         std::set<std::string> processedDeviceSet;
2439         // to reduce the number of communications between devices, clean all the died process's connections
2440         for (auto iter = distributedConnectAbilityMap_.begin(); iter != distributedConnectAbilityMap_.end();) {
2441             std::list<ConnectAbilitySession>& sessionsList = iter->second;
2442             if (!sessionsList.empty() && sessionsList.front().IsSameCaller(callerInfo)) {
2443                 for (const auto& session : sessionsList) {
2444                     std::string remoteDeviceId = session.GetDestinationDeviceId();
2445                     TargetComponent targetComponent = session.GetTargetComponent();
2446                     // the same session can connect different types component on the same device
2447                     std::string key = remoteDeviceId + std::to_string(static_cast<int32_t>(targetComponent));
2448                     // just notify one time for same remote device
2449                     auto [_, isSuccess] = processedDeviceSet.emplace(key);
2450                     if (isSuccess) {
2451                         ProcessDiedNotifyInfo notifyInfo = { remoteDeviceId, callerInfo, targetComponent };
2452                         notifyList.push_back(notifyInfo);
2453                     }
2454                 }
2455                 DecreaseConnectLocked(callerInfo.uid);
2456                 if (iter->first != nullptr) {
2457                     iter->first->RemoveDeathRecipient(connectDeathRecipient_);
2458                 }
2459                 ReportDistributedComponentChange(callerInfo, DISTRIBUTED_COMPONENT_REMOVE,
2460                     IDistributedSched::CONNECT, IDistributedSched::CALLER);
2461                 iter = distributedConnectAbilityMap_.erase(iter);
2462             } else {
2463                 iter++;
2464             }
2465         }
2466     }
2467     NotifyProcessDiedAll(notifyList);
2468 }
2469 
NotifyProcessDiedAll(const std::list<ProcessDiedNotifyInfo> & notifyList)2470 void DistributedSchedService::NotifyProcessDiedAll(const std::list<ProcessDiedNotifyInfo>& notifyList)
2471 {
2472     for (auto it = notifyList.begin(); it != notifyList.end(); ++it) {
2473         NotifyProcessDied(it->remoteDeviceId, it->callerInfo, it->targetComponent);
2474     }
2475 }
2476 
NotifyProcessDied(const std::string & remoteDeviceId,const CallerInfo & callerInfo,TargetComponent targetComponent)2477 void DistributedSchedService::NotifyProcessDied(const std::string& remoteDeviceId,
2478     const CallerInfo& callerInfo, TargetComponent targetComponent)
2479 {
2480     if (targetComponent != TargetComponent::HARMONY_COMPONENT) {
2481         HILOGD("NotifyProcessDied not harmony component, no need to notify");
2482         return;
2483     }
2484 
2485     sptr<IDistributedSched> remoteDms = GetRemoteDms(remoteDeviceId);
2486     if (remoteDms == nullptr) {
2487         HILOGE("NotifyProcessDied get remote dms failed");
2488         return;
2489     }
2490     int32_t result = remoteDms->NotifyProcessDiedFromRemote(callerInfo);
2491     HILOGI("NotifyProcessDied result is %{public}d", result);
2492 }
2493 
ConnectAbilitySession(const std::string & sourceDeviceId,const std::string & destinationDeviceId,const CallerInfo & callerInfo,TargetComponent targetComponent)2494 ConnectAbilitySession::ConnectAbilitySession(const std::string& sourceDeviceId, const std::string& destinationDeviceId,
2495     const CallerInfo& callerInfo, TargetComponent targetComponent)
2496     : sourceDeviceId_(sourceDeviceId),
2497       destinationDeviceId_(destinationDeviceId),
2498       callerInfo_(callerInfo),
2499       targetComponent_(targetComponent)
2500 {
2501 }
2502 
AddElement(const AppExecFwk::ElementName & element)2503 void ConnectAbilitySession::AddElement(const AppExecFwk::ElementName& element)
2504 {
2505     for (const auto& elementName : elementsList_) {
2506         if (elementName == element) {
2507             return;
2508         }
2509     }
2510     elementsList_.emplace_back(element);
2511 }
2512 
IsSameCaller(const CallerInfo & callerInfo)2513 bool ConnectAbilitySession::IsSameCaller(const CallerInfo& callerInfo)
2514 {
2515     return (callerInfo.uid == callerInfo_.uid &&
2516             callerInfo.pid == callerInfo_.pid &&
2517             callerInfo.sourceDeviceId == callerInfo_.sourceDeviceId &&
2518             callerInfo.callerType == callerInfo_.callerType);
2519 }
2520 
DumpConnectInfo(std::string & info)2521 void DistributedSchedService::DumpConnectInfo(std::string& info)
2522 {
2523     std::lock_guard<std::mutex> autoLock(distributedLock_);
2524     info += "connected remote abilities:\n";
2525     if (!distributedConnectAbilityMap_.empty()) {
2526         for (const auto& distributedConnect : distributedConnectAbilityMap_) {
2527             const std::list<ConnectAbilitySession> sessionsList = distributedConnect.second;
2528             DumpSessionsLocked(sessionsList, info);
2529         }
2530     } else {
2531         info += "  <none info>\n";
2532     }
2533 }
2534 
DumpSessionsLocked(const std::list<ConnectAbilitySession> & sessionsList,std::string & info)2535 void DistributedSchedService::DumpSessionsLocked(const std::list<ConnectAbilitySession>& sessionsList,
2536     std::string& info)
2537 {
2538     for (const auto& session : sessionsList) {
2539         info += "  ";
2540         info += "SourceDeviceId: ";
2541         info += session.GetSourceDeviceId();
2542         info += ", ";
2543         info += "DestinationDeviceId: ";
2544         info += session.GetDestinationDeviceId();
2545         info += ", ";
2546         info += "CallerUid: ";
2547         info += std::to_string(session.GetCallerInfo().uid);
2548         info += ", ";
2549         info += "CallerPid: ";
2550         info += std::to_string(session.GetCallerInfo().pid);
2551         info += ", ";
2552         info += "CallerType: ";
2553         info += std::to_string(session.GetCallerInfo().callerType);
2554         DumpElementLocked(session.GetElementsList(), info);
2555         info += "\n";
2556     }
2557 }
2558 
DumpElementLocked(const std::list<AppExecFwk::ElementName> & elementsList,std::string & info)2559 void DistributedSchedService::DumpElementLocked(const std::list<AppExecFwk::ElementName>& elementsList,
2560     std::string& info)
2561 {
2562     for (const auto& element : elementsList) {
2563         info += ", ";
2564         info += "BundleName: ";
2565         info += element.GetBundleName();
2566         info += ", ";
2567         info += "AbilityName: ";
2568         info += element.GetAbilityName();
2569     }
2570 }
2571 
2572 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
GetMissionInfos(const std::string & deviceId,int32_t numMissions,std::vector<MissionInfo> & missionInfos)2573 int32_t DistributedSchedService::GetMissionInfos(const std::string& deviceId, int32_t numMissions,
2574     std::vector<MissionInfo>& missionInfos)
2575 {
2576     return DistributedSchedMissionManager::GetInstance().GetMissionInfos(deviceId, numMissions, missionInfos);
2577 }
2578 
NotifyMissionsChangedFromRemote(const std::vector<DstbMissionInfo> & missionInfos,const CallerInfo & callerInfo)2579 int32_t DistributedSchedService::NotifyMissionsChangedFromRemote(const std::vector<DstbMissionInfo>& missionInfos,
2580     const CallerInfo& callerInfo)
2581 {
2582     return DistributedSchedMissionManager::GetInstance()
2583         .NotifyMissionsChangedFromRemote(callerInfo, missionInfos);
2584 }
2585 
GetRemoteMissionSnapshotInfo(const std::string & networkId,int32_t missionId,std::unique_ptr<MissionSnapshot> & missionSnapshot)2586 int32_t DistributedSchedService::GetRemoteMissionSnapshotInfo(const std::string& networkId, int32_t missionId,
2587     std::unique_ptr<MissionSnapshot>& missionSnapshot)
2588 {
2589     return DistributedSchedMissionManager::GetInstance()
2590         .GetRemoteMissionSnapshotInfo(networkId, missionId, missionSnapshot);
2591 }
2592 
RegisterMissionListener(const std::u16string & devId,const sptr<IRemoteObject> & obj)2593 int32_t DistributedSchedService::RegisterMissionListener(const std::u16string& devId,
2594     const sptr<IRemoteObject>& obj)
2595 {
2596     return DistributedSchedMissionManager::GetInstance().RegisterMissionListener(devId, obj);
2597 }
2598 
RegisterOnListener(const std::string & type,const sptr<IRemoteObject> & obj)2599 int32_t DistributedSchedService::RegisterOnListener(const std::string& type,
2600     const sptr<IRemoteObject>& obj)
2601 {
2602     return DMSContinueRecvMgr::GetInstance().RegisterOnListener(type, obj);
2603 }
2604 
RegisterOffListener(const std::string & type,const sptr<IRemoteObject> & obj)2605 int32_t DistributedSchedService::RegisterOffListener(const std::string& type,
2606     const sptr<IRemoteObject>& obj)
2607 {
2608     return DMSContinueRecvMgr::GetInstance().RegisterOffListener(type, obj);
2609 }
2610 
UnRegisterMissionListener(const std::u16string & devId,const sptr<IRemoteObject> & obj)2611 int32_t DistributedSchedService::UnRegisterMissionListener(const std::u16string& devId,
2612     const sptr<IRemoteObject>& obj)
2613 {
2614     return DistributedSchedMissionManager::GetInstance().UnRegisterMissionListener(devId, obj);
2615 }
2616 
StartSyncRemoteMissions(const std::string & devId,bool fixConflict,int64_t tag)2617 int32_t DistributedSchedService::StartSyncRemoteMissions(const std::string& devId, bool fixConflict, int64_t tag)
2618 {
2619     return DistributedSchedMissionManager::GetInstance().StartSyncRemoteMissions(devId, fixConflict, tag);
2620 }
2621 
StopSyncRemoteMissions(const std::string & devId)2622 int32_t DistributedSchedService::StopSyncRemoteMissions(const std::string& devId)
2623 {
2624     return DistributedSchedMissionManager::GetInstance().StopSyncRemoteMissions(devId, false, true);
2625 }
2626 
StartSyncMissionsFromRemote(const CallerInfo & callerInfo,std::vector<DstbMissionInfo> & missionInfos)2627 int32_t DistributedSchedService::StartSyncMissionsFromRemote(const CallerInfo& callerInfo,
2628     std::vector<DstbMissionInfo>& missionInfos)
2629 {
2630     return DistributedSchedMissionManager::GetInstance().StartSyncMissionsFromRemote(callerInfo, missionInfos);
2631 }
2632 
StopSyncMissionsFromRemote(const CallerInfo & callerInfo)2633 int32_t DistributedSchedService::StopSyncMissionsFromRemote(const CallerInfo& callerInfo)
2634 {
2635     DistributedSchedMissionManager::GetInstance().StopSyncMissionsFromRemote(callerInfo.sourceDeviceId);
2636     return ERR_NONE;
2637 }
2638 
SetMissionContinueState(int32_t missionId,const AAFwk::ContinueState & state)2639 int32_t DistributedSchedService::SetMissionContinueState(int32_t missionId, const AAFwk::ContinueState &state)
2640 {
2641     return DMSContinueSendMgr::GetInstance().SetMissionContinueState(missionId, state);
2642 }
2643 #endif
2644 
RegisterDSchedEventListener(const DSchedEventType & type,const sptr<IRemoteObject> & callback)2645 int32_t DistributedSchedService::RegisterDSchedEventListener(const DSchedEventType& type,
2646     const sptr<IRemoteObject>& callback)
2647 {
2648     if (dschedContinuation_ == nullptr || collaborateCbMgr_ == nullptr) {
2649         HILOGE("object null!");
2650         return INVALID_PARAMETERS_ERR;
2651     }
2652     bool ret = false;
2653     switch (type) {
2654         case DMS_CONTINUE:
2655             ret = dschedContinuation_->PushCallback(callback);
2656             break;
2657         case DMS_COLLABORATION:
2658             ret = collaborateCbMgr_->PushCallback(callback);
2659             break;
2660         case DMS_ALL:
2661             ret = dschedContinuation_->PushCallback(callback) && collaborateCbMgr_->PushCallback(callback);
2662             break;
2663         default:
2664             HILOGE("Not support register Dms event listener with event type: %{public}d.", type);
2665             return INVALID_PARAMETERS_ERR;
2666     }
2667 
2668     if (!ret) {
2669         HILOGE("The callback does not exist, type: %{public}d", type);
2670         return CALLBACK_HAS_NOT_REGISTERED;
2671     }
2672     HILOGD("Push %{public}d callback success.", type);
2673     return ERR_OK;
2674 }
2675 
UnRegisterDSchedEventListener(const DSchedEventType & type,const sptr<IRemoteObject> & callback)2676 int32_t DistributedSchedService::UnRegisterDSchedEventListener(const DSchedEventType& type,
2677     const sptr<IRemoteObject>& callback)
2678 {
2679     if (dschedContinuation_ == nullptr || collaborateCbMgr_ == nullptr) {
2680         HILOGE("object null!");
2681         return INVALID_PARAMETERS_ERR;
2682     }
2683     bool result = 0;
2684     switch (type) {
2685         case DMS_CONTINUE:
2686             result = dschedContinuation_->CleanupCallback(callback);
2687             break;
2688         case DMS_COLLABORATION:
2689             result = collaborateCbMgr_->CleanupCallback(callback);
2690             break;
2691         case DMS_ALL:
2692             result = dschedContinuation_->CleanupCallback(callback) && collaborateCbMgr_->CleanupCallback(callback);
2693             break;
2694         default:
2695             break;
2696     }
2697 
2698     if (!result) {
2699         HILOGI("The callback does not exist,type: %{public}d", type);
2700     } else {
2701         HILOGI("Clearing the callback succeeded.");
2702     }
2703     return 0;
2704 }
2705 
GetContinueInfo(std::string & dstNetworkId,std::string & srcNetworkId)2706 int32_t DistributedSchedService::GetContinueInfo(std::string& dstNetworkId, std::string& srcNetworkId)
2707 {
2708     HILOGI("GetContinueInfo called");
2709     if (dschedContinuation_ == nullptr) {
2710         HILOGE("continuation object null!");
2711         return INVALID_PARAMETERS_ERR;
2712     }
2713     dstNetworkId = dschedContinuation_->continueInfo_.dstNetworkId_;
2714     srcNetworkId = dschedContinuation_->continueInfo_.srcNetworkId_;
2715     HILOGI("GetContinueInfo dstNetworkId: %{public}s, srcNetworkId: %{public}s",
2716         GetAnonymStr(dstNetworkId).c_str(), GetAnonymStr(srcNetworkId).c_str());
2717     return 0;
2718 }
2719 
GetDSchedEventInfo(const DSchedEventType & type,std::vector<EventNotify> & events)2720 int32_t DistributedSchedService::GetDSchedEventInfo(const DSchedEventType &type, std::vector<EventNotify> &events)
2721 {
2722     int32_t callingUid = CheckCallingUid() ? DEFAULT_REQUEST_CODE : IPCSkeleton::GetCallingUid();
2723     HILOGI("GetDSchedEventInfo called, uid %{public}d, dms eventType %{public}d.", callingUid, type);
2724     switch (type) {
2725         case DMS_CONTINUE:
2726             GetContinueEventInfo(callingUid, events);
2727             break;
2728         case DMS_COLLABORATION:
2729             GetCollaborateEventInfo(callingUid, events);
2730             break;
2731         case DMS_ALL:
2732             GetContinueEventInfo(callingUid, events);
2733             GetCollaborateEventInfo(callingUid, events);
2734             break;
2735         default:
2736             HILOGI("Get dms event info not support eventType %{public}d.", type);
2737             return INVALID_PARAMETERS_ERR;
2738     }
2739     HILOGI("GetDSchedEventInfo end, uid %{public}d, eventType %{public}d, events size %{public}zu.",
2740         callingUid, type, events.size());
2741     return ERR_OK;
2742 }
2743 
CheckCallingUid()2744 bool DistributedSchedService::CheckCallingUid()
2745 {
2746     // never allow non-system uid for distributed request
2747     auto callingUid = IPCSkeleton::GetCallingUid();
2748     return callingUid < HID_HAP;
2749 }
2750 
GetContinueEventInfo(int32_t callingUid,std::vector<EventNotify> & events)2751 void DistributedSchedService::GetContinueEventInfo(int32_t callingUid, std::vector<EventNotify> &events)
2752 {
2753     if (callingUid == DEFAULT_REQUEST_CODE && dschedContinuation_ != nullptr) {
2754         events.emplace_back(dschedContinuation_->continueEvent_);
2755         return;
2756     }
2757 
2758     std::vector<std::string> bundleNames;
2759     if (!BundleManagerInternal::GetBundleNameListFromBms(callingUid, bundleNames)) {
2760         HILOGE("Get bundle name from Bms failed");
2761         return;
2762     }
2763     for (const auto &bundleName : bundleNames) {
2764         HILOGD("Get bundle name %{public}s from Bms.", bundleName.c_str());
2765         if (bundleName == dschedContinuation_->continueEvent_.srcBundleName_ ||
2766             bundleName == dschedContinuation_->continueEvent_.destBundleName_) {
2767             events.emplace_back(dschedContinuation_->continueEvent_);
2768         }
2769     }
2770 }
2771 
GetCollaborateEventInfo(int32_t callingUid,std::vector<EventNotify> & events)2772 void DistributedSchedService::GetCollaborateEventInfo(int32_t callingUid, std::vector<EventNotify> &events)
2773 {
2774     if (callingUid == DEFAULT_REQUEST_CODE) {
2775         GetCollaborateEventsByCallers(callingUid, "", events);
2776         GetCollaborateEventsByCallees(callingUid, "", events);
2777         return;
2778     }
2779 
2780     std::string callingBundleName;
2781     if (!BundleManagerInternal::GetSpecifyBundleNameFromBms(callingUid, callingBundleName)) {
2782         HILOGE("Get specify bundle name for from Bms fail, uid %{public}d.", callingUid);
2783         return;
2784     }
2785     GetCollaborateEventsByCallers(callingUid, callingBundleName, events);
2786     GetCollaborateEventsByCallees(callingUid, callingBundleName, events);
2787 }
2788 
GetCollaborateEventsByCallers(int32_t callingUid,const std::string & callingBundleName,std::vector<EventNotify> & events)2789 void DistributedSchedService::GetCollaborateEventsByCallers(int32_t callingUid, const std::string &callingBundleName,
2790     std::vector<EventNotify> &events)
2791 {
2792     std::lock_guard<std::mutex> autoLock(callerLock_);
2793     for (const auto &iter : callerMap_) {
2794         for (const auto &connectSession : iter.second) {
2795             auto bundleNames = connectSession.GetCallerInfo().bundleNames;
2796             if (callingUid != DEFAULT_REQUEST_CODE && callingUid != connectSession.GetCallerInfo().uid &&
2797                 std::count(bundleNames.begin(), bundleNames.end(), callingBundleName) == 0) {
2798                 HILOGE("Connect session callerInfo uid %{public}d is different from callingUid %{public}d, "
2799                     "callingbundle %{public}s.", connectSession.GetCallerInfo().uid,
2800                     callingUid, callingBundleName.c_str());
2801                 continue;
2802             }
2803             for (const auto &element : connectSession.GetElementsList()) {
2804                 EventNotify tempEvent;
2805                 GetCurSrcCollaborateEvent(connectSession.GetCallerInfo(), element,
2806                     DMS_DSCHED_EVENT_PROCESSING, ERR_OK, tempEvent);
2807                 events.emplace_back(tempEvent);
2808             }
2809         }
2810     }
2811 }
2812 
GetCollaborateEventsByCallees(int32_t callingUid,const std::string & callingBundleName,std::vector<EventNotify> & events)2813 void DistributedSchedService::GetCollaborateEventsByCallees(int32_t callingUid, const std::string &callingBundleName,
2814     std::vector<EventNotify> &events)
2815 {
2816     std::lock_guard<std::mutex> autoLock(calleeLock_);
2817     for (const auto &iter : calleeMap_) {
2818         if (callingUid != DEFAULT_REQUEST_CODE && callingBundleName != iter.second.element.GetBundleName()) {
2819             HILOGE("Connect session calleeInfo destBundleName %{public}s is different from "
2820                 "callingBundleName %{public}s, callingUid %{public}d.", iter.second.element.GetBundleName().c_str(),
2821                 callingBundleName.c_str(), callingUid);
2822             continue;
2823         }
2824 
2825         EventNotify tempEvent;
2826         GetCurDestCollaborateEvent(iter.second.callerInfo, iter.second.element,
2827             DMS_DSCHED_EVENT_PROCESSING, ERR_OK, tempEvent);
2828         events.emplace_back(tempEvent);
2829     }
2830 }
2831 
OnRemoteDied(const wptr<IRemoteObject> & remote)2832 void CallerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
2833 {
2834     HILOGI("CallerDeathRecipient OnRemoteDied called");
2835     DistributedSchedAdapter::GetInstance().ProcessCallerDied(remote.promote(), deviceType_);
2836 }
2837 
SetCallerInfo(int32_t callerUid,std::string localDeviceId,uint32_t accessToken,CallerInfo & callerInfo)2838 int32_t DistributedSchedService::SetCallerInfo(
2839     int32_t callerUid, std::string localDeviceId, uint32_t accessToken, CallerInfo& callerInfo)
2840 {
2841     callerInfo.uid = callerUid;
2842     callerInfo.callerType = CALLER_TYPE_HARMONY;
2843     callerInfo.sourceDeviceId = localDeviceId;
2844     callerInfo.accessToken = accessToken;
2845     if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
2846         HILOGE("GetCallerAppIdFromBms failed");
2847         return INVALID_PARAMETERS_ERR;
2848     }
2849     if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
2850         HILOGE("GetBundleNameListFromBms failed");
2851         return INVALID_PARAMETERS_ERR;
2852     }
2853     callerInfo.extraInfoJson[DMS_VERSION_ID] = DMS_VERSION;
2854     return ERR_OK;
2855 }
2856 
StartRemoteFreeInstall(const OHOS::AAFwk::Want & want,int32_t callerUid,int32_t requestCode,uint32_t accessToken,const sptr<IRemoteObject> & callback)2857 int32_t DistributedSchedService::StartRemoteFreeInstall(const OHOS::AAFwk::Want& want, int32_t callerUid,
2858     int32_t requestCode, uint32_t accessToken, const sptr<IRemoteObject>& callback)
2859 {
2860     HILOGI("called");
2861     std::string localDeviceId;
2862     std::string deviceId = want.GetElement().GetDeviceID();
2863     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, deviceId)) {
2864         HILOGE("check deviceId failed");
2865         return INVALID_PARAMETERS_ERR;
2866     }
2867     sptr<IDistributedSched> remoteDms = GetRemoteDms(deviceId);
2868     if (remoteDms == nullptr) {
2869         HILOGE("get remoteDms failed");
2870         return INVALID_PARAMETERS_ERR;
2871     }
2872     if (dmsCallbackTask_ == nullptr) {
2873         HILOGE("callbackTask object null!");
2874         return INVALID_REMOTE_PARAMETERS_ERR;
2875     }
2876     int64_t taskId = dmsCallbackTask_->GenerateTaskId();
2877     LaunchType launchType = LaunchType::FREEINSTALL_START;
2878     if (((want.GetFlags() & AAFwk::Want::FLAG_ABILITY_CONTINUATION) != 0)) {
2879         launchType = LaunchType::FREEINSTALL_CONTINUE;
2880     }
2881     if (dmsCallbackTask_->PushCallback(taskId, callback, deviceId, launchType, want) != ERR_OK) {
2882         HILOGE("Push callback failed!");
2883         return INVALID_REMOTE_PARAMETERS_ERR;
2884     }
2885     if (launchType == LaunchType::FREEINSTALL_CONTINUE) {
2886         dmsCallbackTask_->SetContinuationMissionMap(taskId, want.GetIntParam("sessionId", -1));
2887     }
2888 
2889     CallerInfo callerInfo;
2890     if (SetCallerInfo(callerUid, localDeviceId, accessToken, callerInfo) != ERR_OK) {
2891         HILOGE("SetCallerInfo failed");
2892         return INVALID_PARAMETERS_ERR;
2893     }
2894     AccountInfo accountInfo = {};
2895     if ((DistributedSchedPermission::GetInstance().GetAccountInfo(deviceId, callerInfo, accountInfo)) != ERR_OK) {
2896         HILOGE("GetAccountInfo failed");
2897         return INVALID_PARAMETERS_ERR;
2898     }
2899     AAFwk::Want* newWant = const_cast<Want*>(&want);
2900     newWant->SetParam(DMS_SRC_NETWORK_ID, localDeviceId);
2901     FreeInstallInfo info = {*newWant, requestCode, callerInfo, accountInfo};
2902     int32_t result = remoteDms->StartFreeInstallFromRemote(info, taskId);
2903     if (result != ERR_OK) {
2904         HILOGE("result = %{public}d", result);
2905         CallbackTaskItem item = dmsCallbackTask_->PopCallback(taskId);
2906         NotifyFreeInstallResult(item, result);
2907     }
2908     return result;
2909 }
2910 
StartFreeInstallFromRemote(const FreeInstallInfo & info,int64_t taskId)2911 int32_t DistributedSchedService::StartFreeInstallFromRemote(const FreeInstallInfo& info, int64_t taskId)
2912 {
2913     HILOGI("begin taskId : %{public} " PRId64 ". ", taskId);
2914     std::string localDeviceId;
2915     std::string deviceId = info.want.GetElement().GetDeviceID();
2916     if (!GetLocalDeviceId(localDeviceId) ||
2917         !CheckDeviceIdFromRemote(localDeviceId, deviceId, info.callerInfo.sourceDeviceId)) {
2918         HILOGE("check deviceId failed");
2919         return INVALID_REMOTE_PARAMETERS_ERR;
2920     }
2921 
2922     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->Connect();
2923     if (err != ERR_OK) {
2924         HILOGE("connect ability server failed %{public}d", err);
2925         return err;
2926     }
2927     int32_t activeAccountId = -1;
2928     err = QueryOsAccount(activeAccountId);
2929     if (err != ERR_OK) {
2930         return err;
2931     }
2932 
2933     sptr<DmsFreeInstallCallback> callback(new DmsFreeInstallCallback(taskId, info));
2934     err = AAFwk::AbilityManagerClient::GetInstance()->FreeInstallAbilityFromRemote(
2935         info.want, callback, activeAccountId, info.requestCode);
2936     if (err != ERR_OK) {
2937         HILOGE("FreeInstallAbilityFromRemote failed %{public}d", err);
2938     }
2939     return err;
2940 }
2941 
NotifyCompleteFreeInstall(const FreeInstallInfo & info,int64_t taskId,int32_t resultCode)2942 int32_t DistributedSchedService::NotifyCompleteFreeInstall(
2943     const FreeInstallInfo& info, int64_t taskId, int32_t resultCode)
2944 {
2945     HILOGI("taskId = %{public}" PRId64 ".", taskId);
2946     if (taskId <= 0) {
2947         HILOGE("taskId invalid!");
2948         return INVALID_PARAMETERS_ERR;
2949     }
2950     if (resultCode != ERR_OK) {
2951         HILOGE("free install failed, resultCode : %{public}d", resultCode);
2952         return HandleRemoteNotify(info, taskId, resultCode);
2953     }
2954     int32_t result = StartLocalAbility(info, taskId, resultCode);
2955     return HandleRemoteNotify(info, taskId, result);
2956 }
2957 
StartLocalAbility(const FreeInstallInfo & info,int64_t taskId,int32_t resultCode)2958 int32_t DistributedSchedService::StartLocalAbility(const FreeInstallInfo& info, int64_t taskId, int32_t resultCode)
2959 {
2960     std::string localDeviceId;
2961     if (!GetLocalDeviceId(localDeviceId)) {
2962         HILOGE("get local deviceId failed");
2963         return INVALID_REMOTE_PARAMETERS_ERR;
2964     }
2965     int32_t result = CheckTargetPermission(info.want, info.callerInfo, info.accountInfo, START_PERMISSION, true);
2966     if (result != ERR_OK) {
2967         HILOGE("CheckTargetPermission failed!!");
2968         return result;
2969     }
2970 
2971     AAFwk::Want* want = const_cast<Want*>(&info.want);
2972     want->RemoveFlags(OHOS::AAFwk::Want::FLAG_INSTALL_ON_DEMAND);
2973     return StartAbility(*want, info.requestCode);
2974 }
2975 
StartAbility(const OHOS::AAFwk::Want & want,int32_t requestCode)2976 int32_t DistributedSchedService::StartAbility(const OHOS::AAFwk::Want& want, int32_t requestCode)
2977 {
2978     if (!dataShareManager.IsCurrentContinueSwitchOn()) {
2979         HILOGE("ContinueSwitch status is off");
2980         return DMS_PERMISSION_DENIED;
2981     }
2982     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->Connect();
2983     if (err != ERR_OK) {
2984         HILOGE("connect ability server failed %{public}d", err);
2985         return err;
2986     }
2987     int32_t activeAccountId = -1;
2988     err = QueryOsAccount(activeAccountId);
2989     if (err != ERR_OK) {
2990         return err;
2991     }
2992     if (want.GetBoolParam(Want::PARAM_RESV_FOR_RESULT, false)) {
2993         HILOGI("StartAbilityForResult start, flag is %{public}d", want.GetFlags());
2994         sptr<IRemoteObject> dmsTokenCallback(new DmsTokenCallback());
2995         err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, dmsTokenCallback, requestCode,
2996             activeAccountId);
2997     } else {
2998         HILOGI("StartAbility start, flag is %{public}d", want.GetFlags());
2999         if (DmsContinueTime::GetInstance().GetPull()) {
3000             int64_t begin = GetTickCount();
3001             DmsContinueTime::GetInstance().SetDurationBegin(DMSDURATION_STARTABILITY, begin);
3002         }
3003         DmsContinueTime::GetInstance().SetDstAbilityName(want.GetElement().GetAbilityName());
3004         DmsContinueTime::GetInstance().SetDstBundleName(want.GetElement().GetBundleName());
3005         DmsRadar::GetInstance().ClickIconDmsStartAbility("StartAbility", err);
3006         err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, requestCode, activeAccountId);
3007     }
3008     if (err != ERR_OK) {
3009         HILOGE("StartAbility failed %{public}d", err);
3010     }
3011     return err;
3012 }
3013 
HandleRemoteNotify(const FreeInstallInfo & info,int64_t taskId,int32_t resultCode)3014 int32_t DistributedSchedService::HandleRemoteNotify(const FreeInstallInfo& info, int64_t taskId, int32_t resultCode)
3015 {
3016     HILOGI("begin taskId = %{public}" PRId64 ", resultCode = %{public}d", taskId, resultCode);
3017     sptr<IDistributedSched> remoteDms = GetRemoteDms(info.callerInfo.sourceDeviceId);
3018     if (remoteDms == nullptr) {
3019         HILOGE("get remote dms null!");
3020         return INVALID_PARAMETERS_ERR;
3021     }
3022     if (taskId <= 0) {
3023         HILOGE("taskId invalid!");
3024         return INVALID_PARAMETERS_ERR;
3025     }
3026     return remoteDms->NotifyCompleteFreeInstallFromRemote(taskId, resultCode);
3027 }
3028 
NotifyCompleteFreeInstallFromRemote(int64_t taskId,int32_t resultCode)3029 int32_t DistributedSchedService::NotifyCompleteFreeInstallFromRemote(int64_t taskId, int32_t resultCode)
3030 {
3031     HILOGI("begin taskId = %{public}" PRId64 ", resultCode = %{public}d", taskId, resultCode);
3032     if (dmsCallbackTask_ == nullptr || dschedContinuation_ == nullptr) {
3033         HILOGE("callbackTask object null!");
3034         return INVALID_REMOTE_PARAMETERS_ERR;
3035     }
3036 
3037     LaunchType launchType = dmsCallbackTask_->GetLaunchType(taskId);
3038     CallbackTaskItem item = dmsCallbackTask_->PopCallback(taskId);
3039     if (launchType == LaunchType::FREEINSTALL_START) {
3040         return NotifyFreeInstallResult(item, resultCode);
3041     }
3042 
3043     if (resultCode == ERR_OK) {
3044         HILOGD("continue free install success, waiting for continue result callback.");
3045         dmsCallbackTask_->PopContinuationMissionMap(taskId);
3046         return ERR_OK;
3047     }
3048 
3049     int32_t missionId = dmsCallbackTask_->GetContinuaionMissionId(taskId);
3050     NotifyContinuationCallbackResult(missionId, CONTINUE_FREE_INSTALL_FAILED);
3051     dmsCallbackTask_->PopContinuationMissionMap(taskId);
3052     return ERR_OK;
3053 }
3054 
NotifyFreeInstallResult(const CallbackTaskItem item,int32_t resultCode)3055 int32_t DistributedSchedService::NotifyFreeInstallResult(const CallbackTaskItem item, int32_t resultCode)
3056 {
3057     HILOGI("taskId : %{public} " PRId64 ". ", item.taskId);
3058     if (item.callback == nullptr) {
3059         HILOGE("item callback null!");
3060         return INVALID_REMOTE_PARAMETERS_ERR;
3061     }
3062     MessageParcel data;
3063     if (!data.WriteInterfaceToken(ATOMIC_SERVICE_STATUS_CALLBACK_TOKEN)) {
3064         HILOGE("Write interface token failed.");
3065         return INVALID_REMOTE_PARAMETERS_ERR;
3066     }
3067 
3068     if (!data.WriteInt32(resultCode)) {
3069         HILOGE("Write resultCode error.");
3070         return INVALID_REMOTE_PARAMETERS_ERR;
3071     }
3072 
3073     if (!data.WriteParcelable(&item.want)) {
3074         HILOGE("Write want error.");
3075         return INVALID_REMOTE_PARAMETERS_ERR;
3076     }
3077 
3078     int32_t userId = 0;
3079     if (!data.WriteInt32(userId)) {
3080         HILOGE("Write userId error.");
3081         return INVALID_REMOTE_PARAMETERS_ERR;
3082     }
3083 
3084     MessageParcel reply;
3085     MessageOption option;
3086     return item.callback->SendRequest(IASS_CALLBACK_ON_REMOTE_FREE_INSTALL_DONE, data, reply, option);
3087 }
3088 
RegisterAppStateObserver(const OHOS::AAFwk::Want & want,const CallerInfo & callerInfo,const sptr<IRemoteObject> & srcConnect,const sptr<IRemoteObject> & callbackWrapper)3089 bool DistributedSchedService::RegisterAppStateObserver(const OHOS::AAFwk::Want& want, const CallerInfo& callerInfo,
3090     const sptr<IRemoteObject>& srcConnect, const sptr<IRemoteObject>& callbackWrapper)
3091 {
3092     HILOGD("register app state observer called");
3093     int32_t connectToken = want.GetIntParam(DMS_CONNECT_TOKEN, DEFAULT_DMS_CONNECT_TOKEN);
3094     HILOGD("Get connectToken = %{private}s", GetAnonymStr(std::to_string(connectToken)).c_str());
3095     if (connectToken == DEFAULT_DMS_CONNECT_TOKEN) {
3096         return false;
3097     }
3098     sptr<AppExecFwk::IAppMgr> appObject = GetAppManager();
3099     if (appObject == nullptr) {
3100         HILOGE("failed to get app manager service");
3101         return false;
3102     }
3103     sptr<AppStateObserver> appStateObserver;
3104     std::string bundleName = want.GetElement().GetBundleName();
3105     {
3106         std::lock_guard<std::mutex> autoLock(registerMutex_);
3107         if (!bundleNameMap_.count(bundleName)) {
3108             std::vector<std::string> bundleNameList = {bundleName};
3109             appStateObserver = sptr<AppStateObserver>(new (std::nothrow) AppStateObserver());
3110             bundleNameMap_[bundleName] = appStateObserver;
3111             int ret = appObject->RegisterApplicationStateObserver(appStateObserver, bundleNameList);
3112             if (ret != ERR_OK) {
3113                 HILOGE("failed to register application state observer, ret = %{public}d", ret);
3114                 return false;
3115             }
3116         }
3117         appStateObserver = bundleNameMap_[bundleName];
3118     }
3119     HILOGI("register application state observer success");
3120     {
3121         std::lock_guard<std::mutex> autoLock(observerLock_);
3122         Want* newWant = const_cast<Want*>(&want);
3123         newWant->RemoveParam(DMS_MISSION_ID);
3124         newWant->RemoveParam(DMS_CONNECT_TOKEN);
3125         observerMap_[callbackWrapper] = {appStateObserver, callerInfo.sourceDeviceId, connectToken,
3126             want.GetElement().GetBundleName(), want.GetElement().GetAbilityName(), srcConnect};
3127         HILOGI("add observerMap_ success");
3128     }
3129     return true;
3130 }
3131 
UnregisterAppStateObserver(const sptr<IRemoteObject> & callbackWrapper)3132 void DistributedSchedService::UnregisterAppStateObserver(const sptr<IRemoteObject>& callbackWrapper)
3133 {
3134     HILOGD("unregister app state observer called");
3135     if (callbackWrapper == nullptr) {
3136         HILOGD("callbackWrapper is nullptr");
3137         return;
3138     }
3139     bool unRegisterFlag = true;
3140     std::string bundleName;
3141     sptr<AppStateObserver> appStateObserver;
3142     {
3143         std::lock_guard<std::mutex> autoLock(observerLock_);
3144         auto it = observerMap_.find(callbackWrapper);
3145         if (it == observerMap_.end()) {
3146             HILOGE("state observer not found");
3147             return;
3148         }
3149         appStateObserver = it->second.appStateObserver;
3150         bundleName = it->second.dstBundleName;
3151         observerMap_.erase(it);
3152         for (auto iter = observerMap_.begin(); iter != observerMap_.end(); iter++) {
3153             if (iter->second.dstBundleName == bundleName) {
3154                 unRegisterFlag = false;
3155                 break;
3156             }
3157         }
3158         HILOGI("remove app state observer success");
3159     }
3160     if (unRegisterFlag) {
3161         {
3162             std::lock_guard<std::mutex> autoLock(registerMutex_);
3163             bundleNameMap_.erase(bundleName);
3164         }
3165         sptr<AppExecFwk::IAppMgr> appObject = GetAppManager();
3166         if (appObject == nullptr) {
3167             HILOGE("failed to get app manager service");
3168             return;
3169         }
3170         int ret = appObject->UnregisterApplicationStateObserver(appStateObserver);
3171         if (ret != ERR_OK) {
3172             HILOGE("failed to unregister application state observer, ret = %{public}d", ret);
3173             return;
3174         }
3175     }
3176     HILOGI("unregister application state observer success");
3177 }
3178 
GetAppManager()3179 sptr<AppExecFwk::IAppMgr> DistributedSchedService::GetAppManager()
3180 {
3181     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
3182     if (samgr == nullptr) {
3183         HILOGE("system ability manager is nullptr.");
3184         return nullptr;
3185     }
3186 
3187     sptr<AppExecFwk::IAppMgr> appObject =
3188         iface_cast<AppExecFwk::IAppMgr>(samgr->GetSystemAbility(APP_MGR_SERVICE_ID));
3189     if (appObject == nullptr) {
3190         HILOGE("failed to get app manager service");
3191         return nullptr;
3192     }
3193     return appObject;
3194 }
3195 
NotifyStateChanged(int32_t abilityState,AppExecFwk::ElementName & element,const sptr<IRemoteObject> & token)3196 int32_t DistributedSchedService::NotifyStateChanged(int32_t abilityState, AppExecFwk::ElementName& element,
3197     const sptr<IRemoteObject>& token)
3198 {
3199     std::string srcDeviceId = "";
3200     int32_t connectToken = 0;
3201     {
3202         std::lock_guard<std::mutex> autoLock(observerLock_);
3203         for (auto iter = observerMap_.begin(); iter != observerMap_.end(); iter++) {
3204             if (iter->second.dstBundleName == element.GetBundleName() &&
3205                 iter->second.dstAbilityName == element.GetAbilityName() && token == iter->second.token) {
3206                 srcDeviceId = iter->second.srcDeviceId;
3207                 connectToken = iter->second.connectToken;
3208                 HILOGD("get srcDeviceId and missionId success");
3209                 break;
3210             }
3211         }
3212     }
3213     HILOGD("Get connectToken = %{private}s", GetAnonymStr(std::to_string(connectToken)).c_str());
3214     std::string localDeviceId;
3215     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, srcDeviceId)) {
3216         HILOGE("check deviceId failed");
3217         return INVALID_PARAMETERS_ERR;
3218     }
3219     sptr<IDistributedSched> remoteDms = GetRemoteDms(srcDeviceId);
3220     if (remoteDms == nullptr) {
3221         HILOGE("get remoteDms failed");
3222         return INVALID_PARAMETERS_ERR;
3223     }
3224     element.SetDeviceID(localDeviceId);
3225     return remoteDms->NotifyStateChangedFromRemote(abilityState, connectToken, element);
3226 }
3227 
NotifyStateChangedFromRemote(int32_t abilityState,int32_t connectToken,const AppExecFwk::ElementName & element)3228 int32_t DistributedSchedService::NotifyStateChangedFromRemote(int32_t abilityState, int32_t connectToken,
3229     const AppExecFwk::ElementName& element)
3230 {
3231     HILOGD("Get connectToken = %{private}s", GetAnonymStr(std::to_string(connectToken)).c_str());
3232     sptr<IRemoteObject> connect;
3233     {
3234         std::lock_guard<std::mutex> autoLock(callLock_);
3235         for (auto iter = callMap_.begin(); iter != callMap_.end(); iter++) {
3236             if (iter->second.connectToken == connectToken) {
3237                 connect = iter->first;
3238                 break;
3239             }
3240         }
3241         HILOGD("get connect success");
3242     }
3243     if (connect == nullptr) {
3244         HILOGE("NotifyStateChangedFromRemote connect is null");
3245         return INVALID_PARAMETERS_ERR;
3246     }
3247     MessageParcel data;
3248     if (!data.WriteInterfaceToken(CONNECTION_CALLBACK_INTERFACE_TOKEN)) {
3249         HILOGE("Write interface token failed.");
3250         return INVALID_PARAMETERS_ERR;
3251     }
3252     PARCEL_WRITE_HELPER(data, Parcelable, &element);
3253     PARCEL_WRITE_HELPER(data, Int32, abilityState);
3254     MessageParcel reply;
3255     MessageOption option(MessageOption::TF_ASYNC);
3256     HILOGD("ON_REMOTE_STATE_CHANGED start");
3257     int32_t result = connect->SendRequest(IAbilityConnection::ON_REMOTE_STATE_CHANGED, data, reply, option);
3258     HILOGD("ON_REMOTE_STATE_CHANGED end, %{public}d", result);
3259     return ERR_OK;
3260 }
3261 
CheckTargetPermission(const OHOS::AAFwk::Want & want,const CallerInfo & callerInfo,const AccountInfo & accountInfo,int32_t flag,bool needQueryExtension)3262 int32_t DistributedSchedService::CheckTargetPermission(const OHOS::AAFwk::Want& want,
3263     const CallerInfo& callerInfo, const AccountInfo& accountInfo, int32_t flag,
3264     bool needQueryExtension)
3265 {
3266     DistributedSchedPermission& permissionInstance = DistributedSchedPermission::GetInstance();
3267     AppExecFwk::AbilityInfo targetAbility;
3268     bool result = permissionInstance.GetTargetAbility(want, targetAbility, needQueryExtension);
3269     if (!result) {
3270         HILOGE("GetTargetAbility can not find the target ability");
3271         return INVALID_PARAMETERS_ERR;
3272     }
3273     HILOGD("target ability info bundleName:%{public}s abilityName:%{public}s visible:%{public}d",
3274         targetAbility.bundleName.c_str(), targetAbility.name.c_str(), targetAbility.visible);
3275     HILOGD("callerType:%{public}d accountType:%{public}d callerUid:%{public}d AccessTokenID:%{public}s",
3276         callerInfo.callerType, accountInfo.accountType, callerInfo.uid,
3277         GetAnonymStr(std::to_string(callerInfo.accessToken)).c_str());
3278     if (flag == START_PERMISSION) {
3279         HILOGD("start CheckStartPermission");
3280         return permissionInstance.CheckStartPermission(want, callerInfo, accountInfo, targetAbility, true);
3281     } else if (flag == CALL_PERMISSION) {
3282         HILOGD("Collaboration start check get caller permission");
3283         return permissionInstance.CheckGetCallerPermission(want, callerInfo, accountInfo, targetAbility);
3284     } else if (flag == SEND_RESULT_PERMISSION) {
3285         HILOGD("Collaboration start check send result permission");
3286         return permissionInstance.CheckSendResultPermission(want, callerInfo, accountInfo, targetAbility);
3287     }
3288     HILOGE("CheckTargetPermission denied!!");
3289     return DMS_PERMISSION_DENIED;
3290 }
3291 
CheckTargetPermission4DiffBundle(const OHOS::AAFwk::Want & want,const CallerInfo & callerInfo,const AccountInfo & accountInfo,int32_t flag,bool needQueryExtension)3292 int32_t DistributedSchedService::CheckTargetPermission4DiffBundle(const OHOS::AAFwk::Want& want,
3293     const CallerInfo& callerInfo, const AccountInfo& accountInfo, int32_t flag,
3294     bool needQueryExtension)
3295 {
3296     DistributedSchedPermission& permissionInstance = DistributedSchedPermission::GetInstance();
3297     AppExecFwk::AbilityInfo targetAbility;
3298     bool result = permissionInstance.GetTargetAbility(want, targetAbility, needQueryExtension);
3299     if (!result) {
3300         HILOGE("GetTargetAbility can not find the target ability");
3301         return INVALID_PARAMETERS_ERR;
3302     }
3303     HILOGD("target ability info bundleName:%{public}s abilityName:%{public}s visible:%{public}d",
3304         targetAbility.bundleName.c_str(), targetAbility.name.c_str(), targetAbility.visible);
3305     HILOGD("callerType:%{public}d accountType:%{public}d callerUid:%{public}d AccessTokenID:%{public}s",
3306         callerInfo.callerType, accountInfo.accountType, callerInfo.uid,
3307         GetAnonymStr(std::to_string(callerInfo.accessToken)).c_str());
3308     if (flag == START_PERMISSION) {
3309         HILOGD("start CheckStartPermission");
3310         return permissionInstance.CheckStartPermission(want, callerInfo, accountInfo, targetAbility, false);
3311     } else if (flag == CALL_PERMISSION) {
3312         HILOGD("Collaboration start check get caller permission");
3313         return permissionInstance.CheckGetCallerPermission(want, callerInfo, accountInfo, targetAbility);
3314     } else if (flag == SEND_RESULT_PERMISSION) {
3315         HILOGD("Collaboration start check send result permission");
3316         return permissionInstance.CheckSendResultPermission(want, callerInfo, accountInfo, targetAbility);
3317     }
3318     HILOGE("CheckTargetPermission denied!!");
3319     return DMS_PERMISSION_DENIED;
3320 }
3321 
StopRemoteExtensionAbility(const OHOS::AAFwk::Want & want,int32_t callerUid,uint32_t accessToken,int32_t extensionType)3322 int32_t DistributedSchedService::StopRemoteExtensionAbility(const OHOS::AAFwk::Want& want, int32_t callerUid,
3323     uint32_t accessToken, int32_t extensionType)
3324 {
3325     std::string localDeviceId;
3326     std::string deviceId = want.GetDeviceId();
3327     if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, deviceId)) {
3328         HILOGE("CheckDeviceId failed");
3329         return INVALID_PARAMETERS_ERR;
3330     }
3331     sptr<IDistributedSched> remoteDms = GetRemoteDms(deviceId);
3332     if (remoteDms == nullptr) {
3333         HILOGE("GetRemoteDms failed");
3334         return INVALID_PARAMETERS_ERR;
3335     }
3336     CallerInfo callerInfo;
3337     callerInfo.sourceDeviceId = localDeviceId;
3338     callerInfo.uid = callerUid;
3339     callerInfo.accessToken = accessToken;
3340     if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
3341         HILOGE("GetCallerAppIdFromBms failed");
3342         return INVALID_PARAMETERS_ERR;
3343     }
3344     if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
3345         HILOGE("GetBundleNameListFromBms failed");
3346         return INVALID_PARAMETERS_ERR;
3347     }
3348     AccountInfo accountInfo = {};
3349     if ((DistributedSchedPermission::GetInstance().GetAccountInfo(deviceId, callerInfo, accountInfo)) != ERR_OK) {
3350         HILOGE("GetAccountInfo failed");
3351         return INVALID_PARAMETERS_ERR;
3352     }
3353     AAFwk::Want remoteWant = want;
3354     remoteWant.SetParam(DMS_SRC_NETWORK_ID, localDeviceId);
3355     return remoteDms->StopExtensionAbilityFromRemote(remoteWant, callerInfo, accountInfo, extensionType);
3356 }
3357 
StopExtensionAbilityFromRemote(const OHOS::AAFwk::Want & remoteWant,const CallerInfo & callerInfo,const AccountInfo & accountInfo,int32_t extensionType)3358 int32_t DistributedSchedService::StopExtensionAbilityFromRemote(const OHOS::AAFwk::Want& remoteWant,
3359     const CallerInfo& callerInfo, const AccountInfo& accountInfo, int32_t extensionType)
3360 {
3361     std::string localDeviceId;
3362     std::string destinationDeviceId = remoteWant.GetElement().GetDeviceID();
3363     if (!GetLocalDeviceId(localDeviceId) ||
3364         !CheckDeviceIdFromRemote(localDeviceId, destinationDeviceId, callerInfo.sourceDeviceId)) {
3365         HILOGE("check deviceId failed");
3366         return INVALID_REMOTE_PARAMETERS_ERR;
3367     }
3368 
3369     int32_t permissionValid = CheckTargetPermission(remoteWant, callerInfo, accountInfo, START_PERMISSION, true);
3370     if (permissionValid != ERR_OK) {
3371         HILOGE("CheckTargetPermission failed!!");
3372         return DMS_PERMISSION_DENIED;
3373     }
3374     Want want = remoteWant;
3375     want.RemoveParam(DMS_SRC_NETWORK_ID);
3376     sptr<IRemoteObject> callerToken(new DmsTokenCallback());
3377 
3378     int32_t activeAccountId = -1;
3379     ErrCode err = QueryOsAccount(activeAccountId);
3380     if (err != ERR_OK) {
3381         return err;
3382     }
3383 
3384     return AAFwk::AbilityManagerClient::GetInstance()->StopExtensionAbility(
3385         want, callerToken, activeAccountId, static_cast<AppExecFwk::ExtensionAbilityType>(extensionType));
3386 }
3387 
SetCleanMissionFlag(const OHOS::AAFwk::Want & want,int32_t missionId)3388 void DistributedSchedService::SetCleanMissionFlag(const OHOS::AAFwk::Want& want, int32_t missionId)
3389 {
3390     auto value =  want.GetParams().GetParam(SUPPORT_CONTINUE_SOURCE_EXIT_KEY);
3391     IBoolean *ao = IBoolean::Query(value);
3392     bool isCleanMission = true;
3393     if (ao != nullptr) {
3394         isCleanMission = AAFwk::Boolean::Unbox(ao);
3395     }
3396     if (dschedContinuation_ == nullptr) {
3397         HILOGW("continuation object null!");
3398         return;
3399     }
3400     dschedContinuation_->SetCleanMissionFlag(missionId, isCleanMission);
3401 }
3402 } // namespace DistributedSchedule
3403 } // namespace OHOS