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