1 /*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "free_install_manager.h"
17
18 #include "ability_manager_service.h"
19 #include "ability_util.h"
20 #include "atomic_service_status_callback.h"
21 #include "distributed_client.h"
22 #include "hitrace_meter.h"
23 #include "insight_intent_execute_manager.h"
24 #include "insight_intent_utils.h"
25 #include "ipc_capacity_wrap.h"
26 #include "permission_constants.h"
27 #include "utils/app_mgr_util.h"
28 #include "uri_utils.h"
29
30 namespace OHOS {
31 namespace AAFwk {
32 const std::u16string DMS_FREE_INSTALL_CALLBACK_TOKEN = u"ohos.DistributedSchedule.IDmsFreeInstallCallback";
33 const std::string DMS_MISSION_ID = "dmsMissionId";
34 const std::string PARAM_FREEINSTALL_APPID = "ohos.freeinstall.params.callingAppId";
35 const std::string PARAM_FREEINSTALL_BUNDLENAMES = "ohos.freeinstall.params.callingBundleNames";
36 const std::string PARAM_FREEINSTALL_UID = "ohos.freeinstall.params.callingUid";
37 constexpr uint32_t IDMS_CALLBACK_ON_FREE_INSTALL_DONE = 0;
38 constexpr uint32_t UPDATE_ATOMOIC_SERVICE_TASK_TIMER = 24 * 60 * 60 * 1000; /* 24h */
39 constexpr const char* KEY_IS_APP_RUNNING = "com.ohos.param.isAppRunning";
40
FreeInstallManager(const std::weak_ptr<AbilityManagerService> & server)41 FreeInstallManager::FreeInstallManager(const std::weak_ptr<AbilityManagerService> &server)
42 : server_(server)
43 {
44 }
45
IsTopAbility(const sptr<IRemoteObject> & callerToken)46 bool FreeInstallManager::IsTopAbility(const sptr<IRemoteObject> &callerToken)
47 {
48 auto server = server_.lock();
49 CHECK_POINTER_AND_RETURN_LOG(server, false, "Get server failed!");
50 AppExecFwk::ElementName elementName = IN_PROCESS_CALL(server->GetTopAbility());
51 if (elementName.GetBundleName().empty() || elementName.GetAbilityName().empty()) {
52 TAG_LOGE(AAFwkTag::FREE_INSTALL, "GetBundleName or GetAbilityName empty");
53 return false;
54 }
55
56 auto caller = Token::GetAbilityRecordByToken(callerToken);
57 if (caller == nullptr) {
58 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null caller");
59 return false;
60 }
61
62 auto type = caller->GetAbilityInfo().type;
63 if (type == AppExecFwk::AbilityType::SERVICE || type == AppExecFwk::AbilityType::EXTENSION) {
64 TAG_LOGE(AAFwkTag::FREE_INSTALL, "service or extension");
65 return true;
66 }
67
68 AppExecFwk::ElementName callerElementName = caller->GetElementName();
69 std::string callerBundleName = callerElementName.GetBundleName();
70 std::string callerAbilityName = callerElementName.GetAbilityName();
71 std::string callerModuleName = callerElementName.GetModuleName();
72 if (elementName.GetBundleName().compare(callerBundleName) == 0 &&
73 elementName.GetAbilityName().compare(callerAbilityName) == 0 &&
74 elementName.GetModuleName().compare(callerModuleName) == 0) {
75 TAG_LOGI(AAFwkTag::FREE_INSTALL, "top ability");
76 return true;
77 }
78
79 return false;
80 }
81
StartFreeInstall(const Want & want,int32_t userId,int requestCode,const sptr<IRemoteObject> & callerToken,std::shared_ptr<FreeInstallParams> param)82 int FreeInstallManager::StartFreeInstall(const Want &want, int32_t userId, int requestCode,
83 const sptr<IRemoteObject> &callerToken, std::shared_ptr<FreeInstallParams> param)
84 {
85 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
86 if (!VerifyStartFreeInstallPermission(callerToken)) {
87 return NOT_TOP_ABILITY;
88 }
89 FreeInstallInfo info = BuildFreeInstallInfo(want, userId, requestCode, callerToken, param);
90 {
91 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
92 freeInstallList_.push_back(info);
93 }
94 bool isAsync = param != nullptr ? param->isAsync : false;
95 int32_t recordId = GetRecordIdByToken(callerToken);
96 sptr<AtomicServiceStatusCallback> callback = new AtomicServiceStatusCallback(weak_from_this(), isAsync, recordId);
97 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
98 CHECK_POINTER_AND_RETURN(bundleMgrHelper, GET_ABILITY_SERVICE_FAILED);
99 AppExecFwk::AbilityInfo abilityInfo = {};
100 constexpr auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION;
101 info.want.SetParam(PARAM_FREEINSTALL_UID, IPCSkeleton::GetCallingUid());
102
103 int result = SetAppRunningState(info.want);
104 if (result != ERR_OK) {
105 TAG_LOGE(AAFwkTag::FREE_INSTALL, "setAppRunningState failed");
106 return result;
107 }
108
109 if (IN_PROCESS_CALL(bundleMgrHelper->QueryAbilityInfo(info.want, flag, info.userId, abilityInfo, callback))) {
110 TAG_LOGI(AAFwkTag::FREE_INSTALL, "app installed");
111 }
112 std::string callingAppId = info.want.GetStringParam(PARAM_FREEINSTALL_APPID);
113 std::vector<std::string> callingBundleNames = info.want.GetStringArrayParam(PARAM_FREEINSTALL_BUNDLENAMES);
114 if (callingAppId.empty() && callingBundleNames.empty()) {
115 TAG_LOGI(AAFwkTag::FREE_INSTALL, "callingAppId and callingBundleNames empty");
116 }
117 info.want.RemoveParam(PARAM_FREEINSTALL_APPID);
118 info.want.RemoveParam(PARAM_FREEINSTALL_BUNDLENAMES);
119
120 if (isAsync) {
121 return ERR_OK;
122 } else {
123 auto future = info.promise->get_future();
124 std::future_status status = future.wait_for(std::chrono::milliseconds(DELAY_LOCAL_FREE_INSTALL_TIMEOUT));
125 if (status == std::future_status::timeout) {
126 RemoveFreeInstallInfo(info.want.GetElement().GetBundleName(), info.want.GetElement().GetAbilityName(),
127 info.want.GetStringParam(Want::PARAM_RESV_START_TIME));
128 return FREE_INSTALL_TIMEOUT;
129 }
130 return future.get();
131 }
132 }
133
RemoteFreeInstall(const Want & want,int32_t userId,int requestCode,const sptr<IRemoteObject> & callerToken)134 int FreeInstallManager::RemoteFreeInstall(const Want &want, int32_t userId, int requestCode,
135 const sptr<IRemoteObject> &callerToken)
136 {
137 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
138 bool isFromRemote = want.GetBoolParam(FROM_REMOTE_KEY, false);
139 auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall();
140 if (!isSaCall && !isFromRemote && !IsTopAbility(callerToken)) {
141 return NOT_TOP_ABILITY;
142 }
143 FreeInstallInfo info = BuildFreeInstallInfo(want, userId, requestCode, callerToken);
144 {
145 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
146 freeInstallList_.push_back(info);
147 }
148 int32_t recordId = GetRecordIdByToken(callerToken);
149 sptr<AtomicServiceStatusCallback> callback = new AtomicServiceStatusCallback(weak_from_this(), false, recordId);
150 int32_t callerUid = IPCSkeleton::GetCallingUid();
151 uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
152 #ifdef SUPPORT_UPMS
153 UriUtils::GetInstance().CheckUriPermission(accessToken, info.want);
154 #endif // SUPPORT_UPMS
155 DistributedClient dmsClient;
156 auto result = dmsClient.StartRemoteFreeInstall(info.want, callerUid, info.requestCode, accessToken, callback);
157 if (result != ERR_NONE) {
158 return result;
159 }
160 auto remoteFuture = info.promise->get_future();
161 std::future_status remoteStatus = remoteFuture.wait_for(std::chrono::milliseconds(
162 DELAY_REMOTE_FREE_INSTALL_TIMEOUT));
163 if (remoteStatus == std::future_status::timeout) {
164 return FREE_INSTALL_TIMEOUT;
165 }
166 return remoteFuture.get();
167 }
168
BuildFreeInstallInfo(const Want & want,int32_t userId,int requestCode,const sptr<IRemoteObject> & callerToken,std::shared_ptr<FreeInstallParams> param)169 FreeInstallInfo FreeInstallManager::BuildFreeInstallInfo(const Want &want, int32_t userId, int requestCode,
170 const sptr<IRemoteObject> &callerToken, std::shared_ptr<FreeInstallParams> param)
171 {
172 if (param == nullptr) {
173 param = std::make_shared<FreeInstallParams>();
174 }
175 FreeInstallInfo info = {
176 .isOpenAtomicServiceShortUrl = param->isOpenAtomicServiceShortUrl,
177 .specifyTokenId = param->specifyTokenId,
178 .userId = userId,
179 .requestCode = requestCode,
180 .callerToken = callerToken,
181 .originalWant = param->originalWant,
182 .startOptions = param->startOptions,
183 .want = want
184 };
185 if (param->startOptions != nullptr && !param->startOptions->requestId_.empty()) {
186 TAG_LOGD(AAFwkTag::FREE_INSTALL, "set requestId:%{public}s", param->startOptions->requestId_.c_str());
187 info.want.SetParam(KEY_REQUEST_ID, param->startOptions->requestId_);
188 }
189 if (!param->isAsync) {
190 auto promise = std::make_shared<std::promise<int32_t>>();
191 info.promise = promise;
192 }
193 auto identity = IPCSkeleton::ResetCallingIdentity();
194 info.identity = identity;
195 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", identity.c_str());
196 IPCSkeleton::SetCallingIdentity(identity);
197 return info;
198 }
199
StartRemoteFreeInstall(const Want & want,int requestCode,int32_t validUserId,const sptr<IRemoteObject> & callerToken)200 int FreeInstallManager::StartRemoteFreeInstall(const Want &want, int requestCode, int32_t validUserId,
201 const sptr<IRemoteObject> &callerToken)
202 {
203 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
204 if (!want.GetBoolParam(Want::PARAM_RESV_FOR_RESULT, false)) {
205 TAG_LOGI(AAFwkTag::FREE_INSTALL, "StartAbility freeInstall");
206 return RemoteFreeInstall(want, validUserId, requestCode, callerToken);
207 }
208 int32_t missionId = DelayedSingleton<AbilityManagerService>::GetInstance()->
209 GetMissionIdByAbilityToken(callerToken);
210 if (missionId < 0) {
211 return ERR_INVALID_VALUE;
212 }
213 Want* newWant = const_cast<Want*>(&want);
214 newWant->SetParam(DMS_MISSION_ID, missionId);
215 return RemoteFreeInstall(*newWant, validUserId, requestCode, callerToken);
216 }
217
NotifyDmsCallback(const Want & want,int resultCode)218 int FreeInstallManager::NotifyDmsCallback(const Want &want, int resultCode)
219 {
220 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
221 std::lock_guard<ffrt::mutex> autoLock(distributedFreeInstallLock_);
222 if (dmsFreeInstallCbs_.empty()) {
223 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null dms callback");
224 return ERR_INVALID_VALUE;
225 }
226
227 MessageParcel reply;
228 MessageOption option;
229
230 for (auto it = dmsFreeInstallCbs_.begin(); it != dmsFreeInstallCbs_.end();) {
231 std::string abilityName = (*it).want.GetElement().GetAbilityName();
232 if (want.GetElement().GetAbilityName().compare(abilityName) == 0) {
233 TAG_LOGI(AAFwkTag::FREE_INSTALL, "Handle DMS");
234 MessageParcel data;
235 AAFwk::ExtendMaxIpcCapacityForInnerWant(data);
236 if (!data.WriteInterfaceToken(DMS_FREE_INSTALL_CALLBACK_TOKEN)) {
237 TAG_LOGE(AAFwkTag::FREE_INSTALL, "write interface token failed");
238 return ERR_INVALID_VALUE;
239 }
240
241 if (!data.WriteInt32(resultCode)) {
242 TAG_LOGE(AAFwkTag::FREE_INSTALL, "write resultCode error");
243 return ERR_INVALID_VALUE;
244 }
245
246 if (!data.WriteParcelable(&((*it).want))) {
247 TAG_LOGE(AAFwkTag::FREE_INSTALL, "want write failed");
248 return INNER_ERR;
249 }
250
251 if (!data.WriteInt32((*it).requestCode)) {
252 TAG_LOGE(AAFwkTag::FREE_INSTALL, "write resultCode error");
253 return ERR_INVALID_VALUE;
254 }
255
256 (*it).dmsCallback->SendRequest(IDMS_CALLBACK_ON_FREE_INSTALL_DONE, data, reply, option);
257 it = dmsFreeInstallCbs_.erase(it);
258 } else {
259 it++;
260 }
261 }
262
263 return reply.ReadInt32();
264 }
265
NotifyFreeInstallResult(int32_t recordId,const Want & want,int resultCode,bool isAsync)266 void FreeInstallManager::NotifyFreeInstallResult(int32_t recordId, const Want &want, int resultCode, bool isAsync)
267 {
268 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
269 FreeInstallInfo info;
270 bool found = false;
271 {
272 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
273 if (freeInstallList_.empty()) {
274 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null app callback");
275 return;
276 }
277
278 bool isFromRemote = want.GetBoolParam(FROM_REMOTE_KEY, false);
279 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
280 FreeInstallInfo &freeInstallInfo = *it;
281 std::string bundleName = freeInstallInfo.want.GetElement().GetBundleName();
282 std::string abilityName = freeInstallInfo.want.GetElement().GetAbilityName();
283 std::string startTime = freeInstallInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME);
284 std::string url = freeInstallInfo.want.GetUriString();
285 if (want.GetElement().GetBundleName().compare(bundleName) != 0 ||
286 want.GetElement().GetAbilityName().compare(abilityName) != 0 ||
287 want.GetStringParam(Want::PARAM_RESV_START_TIME).compare(startTime) != 0 ||
288 want.GetUriString().compare(url) != 0) {
289 it++;
290 continue;
291 }
292
293 if (!isAsync && freeInstallInfo.promise == nullptr) {
294 it++;
295 continue;
296 }
297 freeInstallInfo.isFreeInstallFinished = true;
298 freeInstallInfo.resultCode = resultCode;
299 found = true;
300 info = freeInstallInfo;
301 freeInstallList_.erase(it);
302 break;
303 }
304 }
305 if (found) {
306 HandleFreeInstallResult(recordId, info, resultCode, isAsync);
307 return;
308 }
309 TAG_LOGE(AAFwkTag::FREE_INSTALL, "not found freeInstallInfo");
310 }
311
HandleOnFreeInstallSuccess(int32_t recordId,FreeInstallInfo & freeInstallInfo,bool isAsync)312 void FreeInstallManager::HandleOnFreeInstallSuccess(int32_t recordId, FreeInstallInfo &freeInstallInfo, bool isAsync)
313 {
314 TAG_LOGI(AAFwkTag::FREE_INSTALL, "install success");
315 freeInstallInfo.isInstalled = true;
316
317 if (isAsync) {
318 std::string startTime = freeInstallInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME);
319 std::string bundleName = freeInstallInfo.want.GetElement().GetBundleName();
320 std::string abilityName = freeInstallInfo.want.GetElement().GetAbilityName();
321 if (freeInstallInfo.isPreStartMissionCalled) {
322 StartAbilityByPreInstall(recordId, freeInstallInfo, bundleName, abilityName, startTime);
323 return;
324 }
325 if (freeInstallInfo.isOpenAtomicServiceShortUrl) {
326 StartAbilityByConvertedWant(freeInstallInfo, startTime);
327 return;
328 }
329 StartAbilityByFreeInstall(freeInstallInfo, bundleName, abilityName, startTime);
330 return;
331 }
332 freeInstallInfo.promise->set_value(ERR_OK);
333 }
334
HandleOnFreeInstallFail(int32_t recordId,FreeInstallInfo & freeInstallInfo,int resultCode,bool isAsync)335 void FreeInstallManager::HandleOnFreeInstallFail(int32_t recordId, FreeInstallInfo &freeInstallInfo, int resultCode,
336 bool isAsync)
337 {
338 TAG_LOGI(AAFwkTag::FREE_INSTALL, "install failed");
339 freeInstallInfo.isInstalled = false;
340
341 if (freeInstallInfo.startOptions != nullptr && !freeInstallInfo.startOptions->requestId_.empty()) {
342 auto abilityRecord = Token::GetAbilityRecordByToken(freeInstallInfo.callerToken);
343 if (abilityRecord == nullptr) {
344 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null ability record");
345 return;
346 }
347 abilityRecord->NotifyAbilityRequestFailure(freeInstallInfo.startOptions->requestId_,
348 freeInstallInfo.want.GetElement(), "Free installation failed", resultCode);
349 }
350
351 if (isAsync) {
352 if (freeInstallInfo.isPreStartMissionCalled &&
353 freeInstallInfo.want.HasParameter(KEY_SESSION_ID) &&
354 !freeInstallInfo.want.GetStringParam(KEY_SESSION_ID).empty() &&
355 freeInstallInfo.isStartUIAbilityBySCBCalled) {
356 DelayedSingleton<AbilityManagerService>::GetInstance()->NotifySCBToHandleAtomicServiceException(
357 freeInstallInfo.want.GetStringParam(KEY_SESSION_ID),
358 resultCode, "free install failed");
359 }
360 std::string startTime = freeInstallInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME);
361 if (freeInstallInfo.isOpenAtomicServiceShortUrl
362 && resultCode != CONCURRENT_TASKS_WAITING_FOR_RETRY) {
363 StartAbilityByOriginalWant(freeInstallInfo, startTime);
364 return;
365 }
366
367 std::string bundleName = freeInstallInfo.want.GetElement().GetBundleName();
368 std::string abilityName = freeInstallInfo.want.GetElement().GetAbilityName();
369 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinished(
370 recordId, bundleName, abilityName, startTime, resultCode);
371 return;
372 }
373 freeInstallInfo.promise->set_value(resultCode);
374 }
375
HandleFreeInstallResult(int32_t recordId,FreeInstallInfo & freeInstallInfo,int resultCode,bool isAsync)376 void FreeInstallManager::HandleFreeInstallResult(int32_t recordId, FreeInstallInfo &freeInstallInfo, int resultCode,
377 bool isAsync)
378 {
379 if (resultCode == ERR_OK) {
380 HandleOnFreeInstallSuccess(recordId, freeInstallInfo, isAsync);
381 return;
382 }
383 HandleOnFreeInstallFail(recordId, freeInstallInfo, resultCode, isAsync);
384 }
385
StartAbilityByFreeInstall(FreeInstallInfo & info,std::string & bundleName,std::string & abilityName,std::string & startTime)386 void FreeInstallManager::StartAbilityByFreeInstall(FreeInstallInfo &info, std::string &bundleName,
387 std::string &abilityName, std::string &startTime)
388 {
389 info.want.SetFlags(info.want.GetFlags() ^ Want::FLAG_INSTALL_ON_DEMAND);
390 auto identity = IPCSkeleton::ResetCallingIdentity();
391 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", info.identity.c_str());
392 IPCSkeleton::SetCallingIdentity(info.identity);
393 int32_t result = ERR_OK;
394 if (info.want.GetElement().GetAbilityName().empty()) {
395 result = UpdateElementName(info.want, info.userId);
396 }
397 if (result == ERR_OK) {
398 if (info.startOptions == nullptr) {
399 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbilityByFreeInstall(info.want,
400 info.callerToken, info.userId, info.requestCode);
401 } else {
402 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartUIAbilityForOptionWrap(info.want,
403 *info.startOptions, info.callerToken, false, info.userId, info.requestCode);
404 }
405 }
406 IPCSkeleton::SetCallingIdentity(identity);
407 int32_t recordId = GetRecordIdByToken(info.callerToken);
408 TAG_LOGI(AAFwkTag::FREE_INSTALL, "result: %{public}d", result);
409 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinished(
410 recordId, bundleName, abilityName, startTime, result);
411 }
412
StartAbilityByPreInstall(int32_t recordId,FreeInstallInfo & info,std::string & bundleName,std::string & abilityName,std::string & startTime)413 void FreeInstallManager::StartAbilityByPreInstall(int32_t recordId, FreeInstallInfo &info, std::string &bundleName,
414 std::string &abilityName, std::string &startTime)
415 {
416 info.want.SetFlags(info.want.GetFlags() ^ Want::FLAG_INSTALL_ON_DEMAND);
417 auto identity = IPCSkeleton::ResetCallingIdentity();
418 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", info.identity.c_str());
419 IPCSkeleton::SetCallingIdentity(info.identity);
420 int32_t result = ERR_OK;
421 if (info.want.GetElement().GetAbilityName().empty()) {
422 result = UpdateElementName(info.want, info.userId);
423 }
424 if (result == ERR_OK) {
425 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartUIAbilityByPreInstall(info);
426 }
427 if (result != ERR_OK && result != ATOMIC_SERVICE_MINIMIZED && info.isStartUIAbilityBySCBCalled) {
428 TAG_LOGE(AAFwkTag::FREE_INSTALL, "StartUIAbilityByPreInstall failed: %{public}d", result);
429 DelayedSingleton<AbilityManagerService>::GetInstance()->NotifySCBToHandleAtomicServiceException(
430 info.want.GetStringParam(KEY_SESSION_ID),
431 result, "start ability failed");
432 }
433 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", identity.c_str());
434 IPCSkeleton::SetCallingIdentity(identity);
435 TAG_LOGI(AAFwkTag::FREE_INSTALL, "preInstall result: %{public}d", result);
436 if (info.isOpenAtomicServiceShortUrl) {
437 auto url = info.want.GetUriString();
438 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinishedByUrl(recordId,
439 startTime, url, result);
440 return;
441 }
442 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinished(
443 recordId, bundleName, abilityName, startTime, result);
444 }
445
StartAbilityByConvertedWant(FreeInstallInfo & info,const std::string & startTime)446 void FreeInstallManager::StartAbilityByConvertedWant(FreeInstallInfo &info, const std::string &startTime)
447 {
448 info.want.SetFlags(info.want.GetFlags() ^ Want::FLAG_INSTALL_ON_DEMAND);
449 auto identity = IPCSkeleton::ResetCallingIdentity();
450 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", info.identity.c_str());
451 IPCSkeleton::SetCallingIdentity(info.identity);
452 int32_t result = ERR_OK;
453 if (info.want.GetElement().GetAbilityName().empty()) {
454 result = UpdateElementName(info.want, info.userId);
455 }
456 if (result == ERR_OK) {
457 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbility(info.want,
458 info.callerToken, info.userId, info.requestCode);
459 }
460 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", identity.c_str());
461 IPCSkeleton::SetCallingIdentity(identity);
462 auto url = info.want.GetUriString();
463 int32_t recordId = GetRecordIdByToken(info.callerToken);
464 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinishedByUrl(recordId,
465 startTime, url, result);
466 }
467
StartAbilityByOriginalWant(FreeInstallInfo & info,const std::string & startTime)468 void FreeInstallManager::StartAbilityByOriginalWant(FreeInstallInfo &info, const std::string &startTime)
469 {
470 auto identity = IPCSkeleton::ResetCallingIdentity();
471 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", info.identity.c_str());
472 IPCSkeleton::SetCallingIdentity(info.identity);
473 int result = ERR_INVALID_VALUE;
474 if (info.originalWant) {
475 TAG_LOGI(AAFwkTag::FREE_INSTALL, "StartAbility by originalWant");
476 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbility(*(info.originalWant),
477 info.callerToken, info.userId, info.requestCode);
478 } else {
479 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null original want");
480 }
481 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", identity.c_str());
482 IPCSkeleton::SetCallingIdentity(identity);
483 TAG_LOGI(AAFwkTag::FREE_INSTALL, "startAbility result: %{public}d", result);
484 auto url = info.want.GetUriString();
485 int32_t recordId = GetRecordIdByToken(info.callerToken);
486 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinishedByUrl(recordId,
487 startTime, url, result);
488 }
489
UpdateElementName(Want & want,int32_t userId) const490 int32_t FreeInstallManager::UpdateElementName(Want &want, int32_t userId) const
491 {
492 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
493 CHECK_POINTER_AND_RETURN(bundleMgrHelper, ERR_INVALID_VALUE);
494 Want launchWant;
495 TAG_LOGD(AAFwkTag::FREE_INSTALL, "bundleName: %{public}s, userId: %{public}d", want.GetBundle().c_str(), userId);
496 auto errCode = IN_PROCESS_CALL(bundleMgrHelper->GetLaunchWantForBundle(want.GetBundle(), launchWant, userId));
497 if (errCode != ERR_OK) {
498 return errCode;
499 }
500 want.SetElement(launchWant.GetElement());
501 return ERR_OK;
502 }
503
FreeInstallAbilityFromRemote(const Want & want,const sptr<IRemoteObject> & callback,int32_t userId,int requestCode)504 int FreeInstallManager::FreeInstallAbilityFromRemote(const Want &want, const sptr<IRemoteObject> &callback,
505 int32_t userId, int requestCode)
506 {
507 if (callback == nullptr) {
508 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null callback");
509 return ERR_INVALID_VALUE;
510 }
511
512 FreeInstallInfo info = {
513 .userId = userId,
514 .requestCode = requestCode,
515 .dmsCallback = callback,
516 .want = want
517 };
518
519 {
520 std::lock_guard<ffrt::mutex> autoLock(distributedFreeInstallLock_);
521 dmsFreeInstallCbs_.push_back(info);
522 }
523
524 auto result = StartFreeInstall(info.want, info.userId, info.requestCode, nullptr);
525 if (result != ERR_OK) {
526 TAG_LOGE(AAFwkTag::FREE_INSTALL, "StartFreeInstall code: %{public}d", result);
527 NotifyDmsCallback(info.want, result);
528 }
529 return result;
530 }
531
ConnectFreeInstall(const Want & want,int32_t userId,const sptr<IRemoteObject> & callerToken,const std::string & localDeviceId)532 int FreeInstallManager::ConnectFreeInstall(const Want &want, int32_t userId,
533 const sptr<IRemoteObject> &callerToken, const std::string& localDeviceId)
534 {
535 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
536 CHECK_POINTER_AND_RETURN(bundleMgrHelper, GET_ABILITY_SERVICE_FAILED);
537 std::string wantDeviceId = want.GetElement().GetDeviceID();
538 if (!(localDeviceId == wantDeviceId || wantDeviceId.empty())) {
539 TAG_LOGE(AAFwkTag::FREE_INSTALL, "deviceID empty");
540 return INVALID_PARAMETERS_ERR;
541 }
542
543 auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall();
544 if (!isSaCall) {
545 std::string wantAbilityName = want.GetElement().GetAbilityName();
546 std::string wantBundleName = want.GetElement().GetBundleName();
547 if (wantBundleName.empty() || wantAbilityName.empty()) {
548 TAG_LOGE(AAFwkTag::FREE_INSTALL, "wantBundleName or wantAbilityName empty.");
549 return INVALID_PARAMETERS_ERR;
550 }
551 int callerUid = IPCSkeleton::GetCallingUid();
552 std::string localBundleName;
553 auto res = IN_PROCESS_CALL(bundleMgrHelper->GetNameForUid(callerUid, localBundleName));
554 if (res != ERR_OK || localBundleName != wantBundleName) {
555 TAG_LOGE(AAFwkTag::FREE_INSTALL, "not local BundleName");
556 return INVALID_PARAMETERS_ERR;
557 }
558 }
559
560 AppExecFwk::AbilityInfo abilityInfo;
561 std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
562 TAG_LOGD(AAFwkTag::FREE_INSTALL,
563 "bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s, userId: %{public}d",
564 want.GetElement().GetBundleName().c_str(), want.GetElement().GetModuleName().c_str(),
565 want.GetElement().GetAbilityName().c_str(), userId);
566 if (!IN_PROCESS_CALL(bundleMgrHelper->QueryAbilityInfo(
567 want, AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION, userId, abilityInfo)) &&
568 !IN_PROCESS_CALL(bundleMgrHelper->QueryExtensionAbilityInfos(
569 want, AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION, userId, extensionInfos))) {
570 TAG_LOGI(AAFwkTag::FREE_INSTALL, "try to StartFreeInstall");
571 int result = StartFreeInstall(want, userId, DEFAULT_INVAL_VALUE, callerToken);
572 if (result) {
573 TAG_LOGE(AAFwkTag::FREE_INSTALL, "startFreeInstall error");
574 return result;
575 }
576 }
577 return ERR_OK;
578 }
579
GetTimeStamp()580 std::time_t FreeInstallManager::GetTimeStamp()
581 {
582 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
583 std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
584 std::time_t timestamp = tp.time_since_epoch().count();
585 return timestamp;
586 }
587
OnInstallFinished(int32_t recordId,int resultCode,const Want & want,int32_t userId,bool isAsync)588 void FreeInstallManager::OnInstallFinished(int32_t recordId, int resultCode, const Want &want,
589 int32_t userId, bool isAsync)
590 {
591 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
592 TAG_LOGI(AAFwkTag::FREE_INSTALL, "resultCode: %{public}d", resultCode);
593
594 if (!InsightIntentExecuteParam::IsInsightIntentExecute(want)) {
595 NotifyDmsCallback(want, resultCode);
596 NotifyFreeInstallResult(recordId, want, resultCode, isAsync);
597 } else {
598 NotifyInsightIntentFreeInstallResult(want, resultCode);
599 }
600
601 PostUpgradeAtomicServiceTask(resultCode, want, userId);
602 }
603
PostUpgradeAtomicServiceTask(int resultCode,const Want & want,int32_t userId)604 void FreeInstallManager::PostUpgradeAtomicServiceTask(int resultCode, const Want &want, int32_t userId)
605 {
606 TAG_LOGI(AAFwkTag::FREE_INSTALL, "called");
607 std::weak_ptr<FreeInstallManager> thisWptr(shared_from_this());
608 if (resultCode == ERR_OK) {
609 auto updateAtmoicServiceTask = [want, userId, thisWptr, &timeStampMap = timeStampMap_]() {
610 auto sptr = thisWptr.lock();
611 TAG_LOGD(AAFwkTag::FREE_INSTALL,
612 "bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s, userId: %{public}d",
613 want.GetElement().GetBundleName().c_str(), want.GetElement().GetModuleName().c_str(),
614 want.GetElement().GetAbilityName().c_str(), userId);
615 std::string nameKey = want.GetElement().GetBundleName() + want.GetElement().GetModuleName();
616 if (timeStampMap.find(nameKey) == timeStampMap.end() ||
617 sptr->GetTimeStamp() - timeStampMap[nameKey] > UPDATE_ATOMOIC_SERVICE_TASK_TIMER) {
618 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
619 CHECK_POINTER(bundleMgrHelper);
620 bundleMgrHelper->UpgradeAtomicService(want, userId);
621 timeStampMap.emplace(nameKey, sptr->GetTimeStamp());
622 }
623 };
624
625 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
626 CHECK_POINTER_LOG(handler, "Fail to get Ability task handler.");
627 handler->SubmitTask(updateAtmoicServiceTask, "UpdateAtmoicServiceTask");
628 }
629 }
630
OnRemoteInstallFinished(int32_t recordId,int resultCode,const Want & want,int32_t userId)631 void FreeInstallManager::OnRemoteInstallFinished(int32_t recordId, int resultCode, const Want &want, int32_t userId)
632 {
633 TAG_LOGI(AAFwkTag::FREE_INSTALL, "finished resultCode:%{public}d", resultCode);
634 NotifyFreeInstallResult(recordId, want, resultCode);
635 }
636
AddFreeInstallObserver(const sptr<IRemoteObject> & callerToken,const sptr<AbilityRuntime::IFreeInstallObserver> & observer)637 int FreeInstallManager::AddFreeInstallObserver(const sptr<IRemoteObject> &callerToken,
638 const sptr<AbilityRuntime::IFreeInstallObserver> &observer)
639 {
640 TAG_LOGI(AAFwkTag::FREE_INSTALL, "called");
641 auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
642 if (abilityRecord != nullptr) {
643 return DelayedSingleton<FreeInstallObserverManager>::GetInstance()->AddObserver(abilityRecord->GetRecordId(),
644 observer);
645 }
646 if (AAFwk::PermissionVerification::GetInstance()->IsSACall()) {
647 return DelayedSingleton<FreeInstallObserverManager>::GetInstance()->AddObserver(-1, observer);
648 }
649 return CHECK_PERMISSION_FAILED;
650 }
651
RemoveFreeInstallInfo(const std::string & bundleName,const std::string & abilityName,const std::string & startTime)652 void FreeInstallManager::RemoveFreeInstallInfo(const std::string &bundleName, const std::string &abilityName,
653 const std::string &startTime)
654 {
655 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
656 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
657 if ((*it).want.GetElement().GetBundleName() == bundleName &&
658 (*it).want.GetElement().GetAbilityName() == abilityName &&
659 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) {
660 it = freeInstallList_.erase(it);
661 } else {
662 it++;
663 }
664 }
665 }
666
VerifyStartFreeInstallPermission(const sptr<IRemoteObject> & callerToken)667 bool FreeInstallManager::VerifyStartFreeInstallPermission(const sptr<IRemoteObject> &callerToken)
668 {
669 auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall();
670 if (isSaCall || IsTopAbility(callerToken)) {
671 return true;
672 }
673
674 if (AAFwk::PermissionVerification::GetInstance()->VerifyCallingPermission(
675 PermissionConstants::PERMISSION_START_ABILITIES_FROM_BACKGROUND)) {
676 return true;
677 }
678
679 return false;
680 }
681
GetRecordIdByToken(const sptr<IRemoteObject> & callerToken)682 int32_t FreeInstallManager::GetRecordIdByToken(const sptr<IRemoteObject> &callerToken)
683 {
684 auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
685 int recordId = -1;
686 if (abilityRecord != nullptr) {
687 recordId = abilityRecord->GetRecordId();
688 }
689 return recordId;
690 }
691
SetAppRunningState(Want & want)692 int FreeInstallManager::SetAppRunningState(Want &want)
693 {
694 auto appMgr = AppMgrUtil::GetAppMgr();
695 if (appMgr == nullptr) {
696 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null appMgr");
697 return ERR_NULL_APP_MGR_CLIENT;
698 }
699
700 bool isAppRunning = appMgr->GetAppRunningStateByBundleName(want.GetElement().GetBundleName());
701 TAG_LOGI(AAFwkTag::FREE_INSTALL, "isAppRunning:%{public}d", static_cast<int>(isAppRunning));
702 want.SetParam(KEY_IS_APP_RUNNING, isAppRunning);
703 return ERR_OK;
704 }
705
GetFreeInstallTaskInfo(const std::string & bundleName,const std::string & abilityName,const std::string & startTime,FreeInstallInfo & taskInfo)706 bool FreeInstallManager::GetFreeInstallTaskInfo(const std::string& bundleName, const std::string& abilityName,
707 const std::string& startTime, FreeInstallInfo& taskInfo)
708 {
709 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
710 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
711 if ((*it).want.GetElement().GetBundleName() == bundleName &&
712 (*it).want.GetElement().GetAbilityName() == abilityName &&
713 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) {
714 taskInfo = *it;
715 return true;
716 }
717 it++;
718 }
719 return false;
720 }
721
GetFreeInstallTaskInfo(const std::string & sessionId,FreeInstallInfo & taskInfo)722 bool FreeInstallManager::GetFreeInstallTaskInfo(const std::string& sessionId, FreeInstallInfo& taskInfo)
723 {
724 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
725 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
726 if ((*it).want.GetStringParam(KEY_SESSION_ID) == sessionId) {
727 taskInfo = *it;
728 return true;
729 }
730 it++;
731 }
732 return false;
733 }
734
SetSCBCallStatus(const std::string & bundleName,const std::string & abilityName,const std::string & startTime,bool scbCallStatus)735 void FreeInstallManager::SetSCBCallStatus(const std::string& bundleName, const std::string& abilityName,
736 const std::string& startTime, bool scbCallStatus)
737 {
738 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
739 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
740 if ((*it).want.GetElement().GetBundleName() == bundleName &&
741 (*it).want.GetElement().GetAbilityName() == abilityName &&
742 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) {
743 (*it).isStartUIAbilityBySCBCalled = scbCallStatus;
744 return;
745 }
746 it++;
747 }
748 }
749
SetPreStartMissionCallStatus(const std::string & bundleName,const std::string & abilityName,const std::string & startTime,bool preStartMissionCallStatus)750 void FreeInstallManager::SetPreStartMissionCallStatus(const std::string& bundleName, const std::string& abilityName,
751 const std::string& startTime, bool preStartMissionCallStatus)
752 {
753 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
754 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
755 if ((*it).want.GetElement().GetBundleName() == bundleName &&
756 (*it).want.GetElement().GetAbilityName() == abilityName &&
757 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) {
758 (*it).isPreStartMissionCalled = preStartMissionCallStatus;
759 return;
760 }
761 it++;
762 }
763 }
764
SetFreeInstallTaskSessionId(const std::string & bundleName,const std::string & abilityName,const std::string & startTime,const std::string & sessionId)765 void FreeInstallManager::SetFreeInstallTaskSessionId(const std::string& bundleName, const std::string& abilityName,
766 const std::string& startTime, const std::string& sessionId)
767 {
768 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
769 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
770 if ((*it).want.GetElement().GetBundleName() == bundleName &&
771 (*it).want.GetElement().GetAbilityName() == abilityName &&
772 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) {
773 (*it).want.SetParam(KEY_SESSION_ID, sessionId);
774 return;
775 }
776 it++;
777 }
778 }
779
NotifyInsightIntentFreeInstallResult(const Want & want,int resultCode)780 void FreeInstallManager::NotifyInsightIntentFreeInstallResult(const Want &want, int resultCode)
781 {
782 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
783 TAG_LOGI(AAFwkTag::FREE_INSTALL, "insight install result:%{public}d", resultCode);
784 if (resultCode != ERR_OK) {
785 RemoveFreeInstallInfo(want.GetElement().GetBundleName(), want.GetElement().GetAbilityName(),
786 want.GetStringParam(Want::PARAM_RESV_START_TIME));
787 NotifyInsightIntentExecuteDone(want, ERR_INVALID_VALUE);
788 return;
789 }
790
791 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
792 if (freeInstallList_.empty()) {
793 TAG_LOGI(AAFwkTag::FREE_INSTALL, "list empty");
794 return;
795 }
796
797 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
798 std::string bundleName = (*it).want.GetElement().GetBundleName();
799 std::string abilityName = (*it).want.GetElement().GetAbilityName();
800 std::string startTime = (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME);
801 if (want.GetElement().GetBundleName().compare(bundleName) != 0 ||
802 want.GetElement().GetAbilityName().compare(abilityName) != 0 ||
803 want.GetStringParam(Want::PARAM_RESV_START_TIME).compare(startTime) != 0) {
804 it++;
805 continue;
806 }
807
808 auto moduleName = (*it).want.GetElement().GetModuleName();
809 auto insightIntentName = (*it).want.GetStringParam(AppExecFwk::INSIGHT_INTENT_EXECUTE_PARAM_NAME);
810 auto executeMode = static_cast<AppExecFwk::ExecuteMode>(
811 it->want.GetIntParam(AppExecFwk::INSIGHT_INTENT_EXECUTE_PARAM_MODE, 0));
812 std::string srcEntry;
813 auto ret = AbilityRuntime::InsightIntentUtils::GetSrcEntry(it->want.GetElement(), insightIntentName,
814 executeMode, srcEntry);
815 if (ret != ERR_OK || srcEntry.empty()) {
816 TAG_LOGE(AAFwkTag::FREE_INSTALL, "failed. bundleName: %{public}s, "
817 "moduleName: %{public}s, insightIntentName: %{public}s", bundleName.c_str(), moduleName.c_str(),
818 insightIntentName.c_str());
819 NotifyInsightIntentExecuteDone(want, ERR_INVALID_VALUE);
820 } else {
821 (*it).want.SetParam(AppExecFwk::INSIGHT_INTENT_SRC_ENTRY, srcEntry);
822 StartAbilityByFreeInstall(*it, bundleName, abilityName, startTime);
823 }
824
825 it = freeInstallList_.erase(it);
826 }
827 }
828
NotifyInsightIntentExecuteDone(const Want & want,int resultCode)829 void FreeInstallManager::NotifyInsightIntentExecuteDone(const Want &want, int resultCode)
830 {
831 InsightIntentExecuteParam executeParam;
832 InsightIntentExecuteParam::GenerateFromWant(want, executeParam);
833 AppExecFwk::InsightIntentExecuteResult result;
834 auto ret = DelayedSingleton<InsightIntentExecuteManager>::GetInstance()->ExecuteIntentDone(
835 executeParam.insightIntentId_, resultCode, result);
836 if (ret != ERR_OK) {
837 TAG_LOGE(AAFwkTag::FREE_INSTALL, "failed with %{public}d", ret);
838 }
839 }
840 } // namespace AAFwk
841 } // namespace OHOS
842