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