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