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 .want = want,
177 .userId = userId,
178 .requestCode = requestCode,
179 .callerToken = callerToken,
180 .specifyTokenId = param->specifyTokenId,
181 .isOpenAtomicServiceShortUrl = param->isOpenAtomicServiceShortUrl,
182 .originalWant = param->originalWant,
183 .startOptions = param->startOptions
184 };
185 if (!param->isAsync) {
186 auto promise = std::make_shared<std::promise<int32_t>>();
187 info.promise = promise;
188 }
189 auto identity = IPCSkeleton::ResetCallingIdentity();
190 info.identity = identity;
191 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", identity.c_str());
192 IPCSkeleton::SetCallingIdentity(identity);
193 return info;
194 }
195
StartRemoteFreeInstall(const Want & want,int requestCode,int32_t validUserId,const sptr<IRemoteObject> & callerToken)196 int FreeInstallManager::StartRemoteFreeInstall(const Want &want, int requestCode, int32_t validUserId,
197 const sptr<IRemoteObject> &callerToken)
198 {
199 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
200 if (!want.GetBoolParam(Want::PARAM_RESV_FOR_RESULT, false)) {
201 TAG_LOGI(AAFwkTag::FREE_INSTALL, "StartAbility freeInstall");
202 return RemoteFreeInstall(want, validUserId, requestCode, callerToken);
203 }
204 int32_t missionId = DelayedSingleton<AbilityManagerService>::GetInstance()->
205 GetMissionIdByAbilityToken(callerToken);
206 if (missionId < 0) {
207 return ERR_INVALID_VALUE;
208 }
209 Want* newWant = const_cast<Want*>(&want);
210 newWant->SetParam(DMS_MISSION_ID, missionId);
211 return RemoteFreeInstall(*newWant, validUserId, requestCode, callerToken);
212 }
213
NotifyDmsCallback(const Want & want,int resultCode)214 int FreeInstallManager::NotifyDmsCallback(const Want &want, int resultCode)
215 {
216 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
217 std::lock_guard<ffrt::mutex> autoLock(distributedFreeInstallLock_);
218 if (dmsFreeInstallCbs_.empty()) {
219 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null dms callback");
220 return ERR_INVALID_VALUE;
221 }
222
223 MessageParcel reply;
224 MessageOption option;
225
226 for (auto it = dmsFreeInstallCbs_.begin(); it != dmsFreeInstallCbs_.end();) {
227 std::string abilityName = (*it).want.GetElement().GetAbilityName();
228 if (want.GetElement().GetAbilityName().compare(abilityName) == 0) {
229 TAG_LOGI(AAFwkTag::FREE_INSTALL, "Handle DMS");
230 MessageParcel data;
231 AAFwk::ExtendMaxIpcCapacityForInnerWant(data);
232 if (!data.WriteInterfaceToken(DMS_FREE_INSTALL_CALLBACK_TOKEN)) {
233 TAG_LOGE(AAFwkTag::FREE_INSTALL, "write interface token failed");
234 return ERR_INVALID_VALUE;
235 }
236
237 if (!data.WriteInt32(resultCode)) {
238 TAG_LOGE(AAFwkTag::FREE_INSTALL, "write resultCode error");
239 return ERR_INVALID_VALUE;
240 }
241
242 if (!data.WriteParcelable(&((*it).want))) {
243 TAG_LOGE(AAFwkTag::FREE_INSTALL, "want write failed");
244 return INNER_ERR;
245 }
246
247 if (!data.WriteInt32((*it).requestCode)) {
248 TAG_LOGE(AAFwkTag::FREE_INSTALL, "write resultCode error");
249 return ERR_INVALID_VALUE;
250 }
251
252 (*it).dmsCallback->SendRequest(IDMS_CALLBACK_ON_FREE_INSTALL_DONE, data, reply, option);
253 it = dmsFreeInstallCbs_.erase(it);
254 } else {
255 it++;
256 }
257 }
258
259 return reply.ReadInt32();
260 }
261
NotifyFreeInstallResult(int32_t recordId,const Want & want,int resultCode,bool isAsync)262 void FreeInstallManager::NotifyFreeInstallResult(int32_t recordId, const Want &want, int resultCode, bool isAsync)
263 {
264 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
265 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
266 if (freeInstallList_.empty()) {
267 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null app callback");
268 return;
269 }
270
271 bool isFromRemote = want.GetBoolParam(FROM_REMOTE_KEY, false);
272 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
273 FreeInstallInfo &freeInstallInfo = *it;
274 std::string bundleName = freeInstallInfo.want.GetElement().GetBundleName();
275 std::string abilityName = freeInstallInfo.want.GetElement().GetAbilityName();
276 std::string startTime = freeInstallInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME);
277 std::string url = freeInstallInfo.want.GetUriString();
278 if (want.GetElement().GetBundleName().compare(bundleName) != 0 ||
279 want.GetElement().GetAbilityName().compare(abilityName) != 0 ||
280 want.GetStringParam(Want::PARAM_RESV_START_TIME).compare(startTime) != 0 ||
281 want.GetUriString().compare(url) != 0) {
282 it++;
283 continue;
284 }
285
286 if (!isAsync && freeInstallInfo.promise == nullptr) {
287 it++;
288 continue;
289 }
290 freeInstallInfo.isFreeInstallFinished = true;
291 freeInstallInfo.resultCode = resultCode;
292 HandleFreeInstallResult(recordId, freeInstallInfo, resultCode, isAsync);
293 it = freeInstallList_.erase(it);
294 }
295 }
296
HandleOnFreeInstallSuccess(int32_t recordId,FreeInstallInfo & freeInstallInfo,bool isAsync)297 void FreeInstallManager::HandleOnFreeInstallSuccess(int32_t recordId, FreeInstallInfo &freeInstallInfo, bool isAsync)
298 {
299 TAG_LOGI(AAFwkTag::FREE_INSTALL, "install success");
300 freeInstallInfo.isInstalled = true;
301
302 if (isAsync) {
303 std::string startTime = freeInstallInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME);
304 std::string bundleName = freeInstallInfo.want.GetElement().GetBundleName();
305 std::string abilityName = freeInstallInfo.want.GetElement().GetAbilityName();
306 if (freeInstallInfo.isPreStartMissionCalled) {
307 StartAbilityByPreInstall(recordId, freeInstallInfo, bundleName, abilityName, startTime);
308 return;
309 }
310 if (freeInstallInfo.isOpenAtomicServiceShortUrl) {
311 StartAbilityByConvertedWant(freeInstallInfo, startTime);
312 return;
313 }
314 StartAbilityByFreeInstall(freeInstallInfo, bundleName, abilityName, startTime);
315 return;
316 }
317 freeInstallInfo.promise->set_value(ERR_OK);
318 }
319
HandleOnFreeInstallFail(int32_t recordId,FreeInstallInfo & freeInstallInfo,int resultCode,bool isAsync)320 void FreeInstallManager::HandleOnFreeInstallFail(int32_t recordId, FreeInstallInfo &freeInstallInfo, int resultCode,
321 bool isAsync)
322 {
323 TAG_LOGI(AAFwkTag::FREE_INSTALL, "install failed");
324 freeInstallInfo.isInstalled = false;
325
326 if (isAsync) {
327 if (freeInstallInfo.isPreStartMissionCalled &&
328 freeInstallInfo.want.HasParameter(KEY_SESSION_ID) &&
329 !freeInstallInfo.want.GetStringParam(KEY_SESSION_ID).empty() &&
330 freeInstallInfo.isStartUIAbilityBySCBCalled) {
331 DelayedSingleton<AbilityManagerService>::GetInstance()->NotifySCBToHandleAtomicServiceException(
332 freeInstallInfo.want.GetStringParam(KEY_SESSION_ID),
333 resultCode, "free install failed");
334 }
335 std::string startTime = freeInstallInfo.want.GetStringParam(Want::PARAM_RESV_START_TIME);
336 if (freeInstallInfo.isOpenAtomicServiceShortUrl
337 && resultCode != CONCURRENT_TASKS_WAITING_FOR_RETRY) {
338 StartAbilityByOriginalWant(freeInstallInfo, startTime);
339 return;
340 }
341
342 std::string bundleName = freeInstallInfo.want.GetElement().GetBundleName();
343 std::string abilityName = freeInstallInfo.want.GetElement().GetAbilityName();
344 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinished(
345 recordId, bundleName, abilityName, startTime, resultCode);
346 return;
347 }
348 freeInstallInfo.promise->set_value(resultCode);
349 }
350
HandleFreeInstallResult(int32_t recordId,FreeInstallInfo & freeInstallInfo,int resultCode,bool isAsync)351 void FreeInstallManager::HandleFreeInstallResult(int32_t recordId, FreeInstallInfo &freeInstallInfo, int resultCode,
352 bool isAsync)
353 {
354 if (resultCode == ERR_OK) {
355 HandleOnFreeInstallSuccess(recordId, freeInstallInfo, isAsync);
356 return;
357 }
358 HandleOnFreeInstallFail(recordId, freeInstallInfo, resultCode, isAsync);
359 }
360
StartAbilityByFreeInstall(FreeInstallInfo & info,std::string & bundleName,std::string & abilityName,std::string & startTime)361 void FreeInstallManager::StartAbilityByFreeInstall(FreeInstallInfo &info, std::string &bundleName,
362 std::string &abilityName, std::string &startTime)
363 {
364 info.want.SetFlags(info.want.GetFlags() ^ Want::FLAG_INSTALL_ON_DEMAND);
365 auto identity = IPCSkeleton::ResetCallingIdentity();
366 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", info.identity.c_str());
367 IPCSkeleton::SetCallingIdentity(info.identity);
368 int32_t result = ERR_OK;
369 if (info.want.GetElement().GetAbilityName().empty()) {
370 result = UpdateElementName(info.want, info.userId);
371 }
372 if (result == ERR_OK) {
373 if (info.startOptions == nullptr) {
374 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbilityByFreeInstall(info.want,
375 info.callerToken, info.userId, info.requestCode);
376 } else {
377 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartUIAbilityForOptionWrap(info.want,
378 *info.startOptions, info.callerToken, false, info.userId, info.requestCode);
379 }
380 }
381 IPCSkeleton::SetCallingIdentity(identity);
382 int32_t recordId = GetRecordIdByToken(info.callerToken);
383 TAG_LOGI(AAFwkTag::FREE_INSTALL, "result: %{public}d", result);
384 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinished(
385 recordId, bundleName, abilityName, startTime, result);
386 }
387
StartAbilityByPreInstall(int32_t recordId,FreeInstallInfo & info,std::string & bundleName,std::string & abilityName,std::string & startTime)388 void FreeInstallManager::StartAbilityByPreInstall(int32_t recordId, FreeInstallInfo &info, std::string &bundleName,
389 std::string &abilityName, std::string &startTime)
390 {
391 info.want.SetFlags(info.want.GetFlags() ^ Want::FLAG_INSTALL_ON_DEMAND);
392 auto identity = IPCSkeleton::ResetCallingIdentity();
393 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", info.identity.c_str());
394 IPCSkeleton::SetCallingIdentity(info.identity);
395 int32_t result = ERR_OK;
396 if (info.want.GetElement().GetAbilityName().empty()) {
397 result = UpdateElementName(info.want, info.userId);
398 }
399 if (result == ERR_OK) {
400 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartUIAbilityByPreInstall(info);
401 }
402 if (result != ERR_OK && result != ATOMIC_SERVICE_MINIMIZED && info.isStartUIAbilityBySCBCalled) {
403 TAG_LOGE(AAFwkTag::FREE_INSTALL, "StartUIAbilityByPreInstall failed: %{public}d", result);
404 DelayedSingleton<AbilityManagerService>::GetInstance()->NotifySCBToHandleAtomicServiceException(
405 info.want.GetStringParam(KEY_SESSION_ID),
406 result, "start ability failed");
407 }
408 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", identity.c_str());
409 IPCSkeleton::SetCallingIdentity(identity);
410 TAG_LOGI(AAFwkTag::FREE_INSTALL, "preInstall result: %{public}d", result);
411 if (info.isOpenAtomicServiceShortUrl) {
412 auto url = info.want.GetUriString();
413 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinishedByUrl(recordId,
414 startTime, url, result);
415 return;
416 }
417 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinished(
418 recordId, bundleName, abilityName, startTime, result);
419 }
420
StartAbilityByConvertedWant(FreeInstallInfo & info,const std::string & startTime)421 void FreeInstallManager::StartAbilityByConvertedWant(FreeInstallInfo &info, const std::string &startTime)
422 {
423 info.want.SetFlags(info.want.GetFlags() ^ Want::FLAG_INSTALL_ON_DEMAND);
424 auto identity = IPCSkeleton::ResetCallingIdentity();
425 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", info.identity.c_str());
426 IPCSkeleton::SetCallingIdentity(info.identity);
427 int32_t result = ERR_OK;
428 if (info.want.GetElement().GetAbilityName().empty()) {
429 result = UpdateElementName(info.want, info.userId);
430 }
431 if (result == ERR_OK) {
432 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbility(info.want,
433 info.callerToken, info.userId, info.requestCode);
434 }
435 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", identity.c_str());
436 IPCSkeleton::SetCallingIdentity(identity);
437 auto url = info.want.GetUriString();
438 int32_t recordId = GetRecordIdByToken(info.callerToken);
439 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinishedByUrl(recordId,
440 startTime, url, result);
441 }
442
StartAbilityByOriginalWant(FreeInstallInfo & info,const std::string & startTime)443 void FreeInstallManager::StartAbilityByOriginalWant(FreeInstallInfo &info, const std::string &startTime)
444 {
445 auto identity = IPCSkeleton::ResetCallingIdentity();
446 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", info.identity.c_str());
447 IPCSkeleton::SetCallingIdentity(info.identity);
448 int result = ERR_INVALID_VALUE;
449 if (info.originalWant) {
450 TAG_LOGI(AAFwkTag::FREE_INSTALL, "StartAbility by originalWant");
451 result = DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbility(*(info.originalWant),
452 info.callerToken, info.userId, info.requestCode);
453 } else {
454 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null original want");
455 }
456 TAG_LOGD(AAFwkTag::FREE_INSTALL, "identity: %{public}s", identity.c_str());
457 IPCSkeleton::SetCallingIdentity(identity);
458 TAG_LOGI(AAFwkTag::FREE_INSTALL, "startAbility result: %{public}d", result);
459 auto url = info.want.GetUriString();
460 int32_t recordId = GetRecordIdByToken(info.callerToken);
461 DelayedSingleton<FreeInstallObserverManager>::GetInstance()->OnInstallFinishedByUrl(recordId,
462 startTime, url, result);
463 }
464
UpdateElementName(Want & want,int32_t userId) const465 int32_t FreeInstallManager::UpdateElementName(Want &want, int32_t userId) const
466 {
467 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
468 CHECK_POINTER_AND_RETURN(bundleMgrHelper, ERR_INVALID_VALUE);
469 Want launchWant;
470 TAG_LOGD(AAFwkTag::FREE_INSTALL, "bundleName: %{public}s, userId: %{public}d", want.GetBundle().c_str(), userId);
471 auto errCode = IN_PROCESS_CALL(bundleMgrHelper->GetLaunchWantForBundle(want.GetBundle(), launchWant, userId));
472 if (errCode != ERR_OK) {
473 return errCode;
474 }
475 want.SetElement(launchWant.GetElement());
476 return ERR_OK;
477 }
478
FreeInstallAbilityFromRemote(const Want & want,const sptr<IRemoteObject> & callback,int32_t userId,int requestCode)479 int FreeInstallManager::FreeInstallAbilityFromRemote(const Want &want, const sptr<IRemoteObject> &callback,
480 int32_t userId, int requestCode)
481 {
482 if (callback == nullptr) {
483 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null callback");
484 return ERR_INVALID_VALUE;
485 }
486
487 FreeInstallInfo info = {
488 .want = want,
489 .userId = userId,
490 .requestCode = requestCode,
491 .dmsCallback = callback
492 };
493
494 {
495 std::lock_guard<ffrt::mutex> autoLock(distributedFreeInstallLock_);
496 dmsFreeInstallCbs_.push_back(info);
497 }
498
499 auto result = StartFreeInstall(info.want, info.userId, info.requestCode, nullptr);
500 if (result != ERR_OK) {
501 TAG_LOGE(AAFwkTag::FREE_INSTALL, "StartFreeInstall code: %{public}d", result);
502 NotifyDmsCallback(info.want, result);
503 }
504 return result;
505 }
506
ConnectFreeInstall(const Want & want,int32_t userId,const sptr<IRemoteObject> & callerToken,const std::string & localDeviceId)507 int FreeInstallManager::ConnectFreeInstall(const Want &want, int32_t userId,
508 const sptr<IRemoteObject> &callerToken, const std::string& localDeviceId)
509 {
510 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
511 CHECK_POINTER_AND_RETURN(bundleMgrHelper, GET_ABILITY_SERVICE_FAILED);
512 std::string wantDeviceId = want.GetElement().GetDeviceID();
513 if (!(localDeviceId == wantDeviceId || wantDeviceId.empty())) {
514 TAG_LOGE(AAFwkTag::FREE_INSTALL, "deviceID empty");
515 return INVALID_PARAMETERS_ERR;
516 }
517
518 auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall();
519 if (!isSaCall) {
520 std::string wantAbilityName = want.GetElement().GetAbilityName();
521 std::string wantBundleName = want.GetElement().GetBundleName();
522 if (wantBundleName.empty() || wantAbilityName.empty()) {
523 TAG_LOGE(AAFwkTag::FREE_INSTALL, "wantBundleName or wantAbilityName empty.");
524 return INVALID_PARAMETERS_ERR;
525 }
526 int callerUid = IPCSkeleton::GetCallingUid();
527 std::string localBundleName;
528 auto res = IN_PROCESS_CALL(bundleMgrHelper->GetNameForUid(callerUid, localBundleName));
529 if (res != ERR_OK || localBundleName != wantBundleName) {
530 TAG_LOGE(AAFwkTag::FREE_INSTALL, "not local BundleName");
531 return INVALID_PARAMETERS_ERR;
532 }
533 }
534
535 AppExecFwk::AbilityInfo abilityInfo;
536 std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
537 TAG_LOGD(AAFwkTag::FREE_INSTALL,
538 "bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s, userId: %{public}d",
539 want.GetElement().GetBundleName().c_str(), want.GetElement().GetModuleName().c_str(),
540 want.GetElement().GetAbilityName().c_str(), userId);
541 if (!IN_PROCESS_CALL(bundleMgrHelper->QueryAbilityInfo(
542 want, AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION, userId, abilityInfo)) &&
543 !IN_PROCESS_CALL(bundleMgrHelper->QueryExtensionAbilityInfos(
544 want, AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION, userId, extensionInfos))) {
545 TAG_LOGI(AAFwkTag::FREE_INSTALL, "try to StartFreeInstall");
546 int result = StartFreeInstall(want, userId, DEFAULT_INVAL_VALUE, callerToken);
547 if (result) {
548 TAG_LOGE(AAFwkTag::FREE_INSTALL, "startFreeInstall error");
549 return result;
550 }
551 }
552 return ERR_OK;
553 }
554
GetTimeStamp()555 std::time_t FreeInstallManager::GetTimeStamp()
556 {
557 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
558 std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
559 std::time_t timestamp = tp.time_since_epoch().count();
560 return timestamp;
561 }
562
OnInstallFinished(int32_t recordId,int resultCode,const Want & want,int32_t userId,bool isAsync)563 void FreeInstallManager::OnInstallFinished(int32_t recordId, int resultCode, const Want &want,
564 int32_t userId, bool isAsync)
565 {
566 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
567 TAG_LOGI(AAFwkTag::FREE_INSTALL, "resultCode: %{public}d", resultCode);
568
569 if (!InsightIntentExecuteParam::IsInsightIntentExecute(want)) {
570 NotifyDmsCallback(want, resultCode);
571 NotifyFreeInstallResult(recordId, want, resultCode, isAsync);
572 } else {
573 NotifyInsightIntentFreeInstallResult(want, resultCode);
574 }
575
576 PostUpgradeAtomicServiceTask(resultCode, want, userId);
577 }
578
PostUpgradeAtomicServiceTask(int resultCode,const Want & want,int32_t userId)579 void FreeInstallManager::PostUpgradeAtomicServiceTask(int resultCode, const Want &want, int32_t userId)
580 {
581 TAG_LOGI(AAFwkTag::FREE_INSTALL, "called");
582 std::weak_ptr<FreeInstallManager> thisWptr(shared_from_this());
583 if (resultCode == ERR_OK) {
584 auto updateAtmoicServiceTask = [want, userId, thisWptr, &timeStampMap = timeStampMap_]() {
585 auto sptr = thisWptr.lock();
586 TAG_LOGD(AAFwkTag::FREE_INSTALL,
587 "bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s, userId: %{public}d",
588 want.GetElement().GetBundleName().c_str(), want.GetElement().GetModuleName().c_str(),
589 want.GetElement().GetAbilityName().c_str(), userId);
590 std::string nameKey = want.GetElement().GetBundleName() + want.GetElement().GetModuleName();
591 if (timeStampMap.find(nameKey) == timeStampMap.end() ||
592 sptr->GetTimeStamp() - timeStampMap[nameKey] > UPDATE_ATOMOIC_SERVICE_TASK_TIMER) {
593 auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
594 CHECK_POINTER(bundleMgrHelper);
595 bundleMgrHelper->UpgradeAtomicService(want, userId);
596 timeStampMap.emplace(nameKey, sptr->GetTimeStamp());
597 }
598 };
599
600 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
601 CHECK_POINTER_LOG(handler, "Fail to get Ability task handler.");
602 handler->SubmitTask(updateAtmoicServiceTask, "UpdateAtmoicServiceTask");
603 }
604 }
605
OnRemoteInstallFinished(int32_t recordId,int resultCode,const Want & want,int32_t userId)606 void FreeInstallManager::OnRemoteInstallFinished(int32_t recordId, int resultCode, const Want &want, int32_t userId)
607 {
608 TAG_LOGI(AAFwkTag::FREE_INSTALL, "finished resultCode:%{public}d", resultCode);
609 NotifyFreeInstallResult(recordId, want, resultCode);
610 }
611
AddFreeInstallObserver(const sptr<IRemoteObject> & callerToken,const sptr<AbilityRuntime::IFreeInstallObserver> & observer)612 int FreeInstallManager::AddFreeInstallObserver(const sptr<IRemoteObject> &callerToken,
613 const sptr<AbilityRuntime::IFreeInstallObserver> &observer)
614 {
615 TAG_LOGI(AAFwkTag::FREE_INSTALL, "called");
616 auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
617 if (abilityRecord != nullptr) {
618 return DelayedSingleton<FreeInstallObserverManager>::GetInstance()->AddObserver(abilityRecord->GetRecordId(),
619 observer);
620 }
621 if (AAFwk::PermissionVerification::GetInstance()->IsSACall()) {
622 return DelayedSingleton<FreeInstallObserverManager>::GetInstance()->AddObserver(-1, observer);
623 }
624 return CHECK_PERMISSION_FAILED;
625 }
626
RemoveFreeInstallInfo(const std::string & bundleName,const std::string & abilityName,const std::string & startTime)627 void FreeInstallManager::RemoveFreeInstallInfo(const std::string &bundleName, const std::string &abilityName,
628 const std::string &startTime)
629 {
630 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
631 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
632 if ((*it).want.GetElement().GetBundleName() == bundleName &&
633 (*it).want.GetElement().GetAbilityName() == abilityName &&
634 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) {
635 it = freeInstallList_.erase(it);
636 } else {
637 it++;
638 }
639 }
640 }
641
VerifyStartFreeInstallPermission(const sptr<IRemoteObject> & callerToken)642 bool FreeInstallManager::VerifyStartFreeInstallPermission(const sptr<IRemoteObject> &callerToken)
643 {
644 auto isSaCall = AAFwk::PermissionVerification::GetInstance()->IsSACall();
645 if (isSaCall || IsTopAbility(callerToken)) {
646 return true;
647 }
648
649 if (AAFwk::PermissionVerification::GetInstance()->VerifyCallingPermission(
650 PermissionConstants::PERMISSION_START_ABILITIES_FROM_BACKGROUND)) {
651 return true;
652 }
653
654 return false;
655 }
656
GetRecordIdByToken(const sptr<IRemoteObject> & callerToken)657 int32_t FreeInstallManager::GetRecordIdByToken(const sptr<IRemoteObject> &callerToken)
658 {
659 auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
660 int recordId = -1;
661 if (abilityRecord != nullptr) {
662 recordId = abilityRecord->GetRecordId();
663 }
664 return recordId;
665 }
666
SetAppRunningState(Want & want)667 int FreeInstallManager::SetAppRunningState(Want &want)
668 {
669 auto appMgr = AppMgrUtil::GetAppMgr();
670 if (appMgr == nullptr) {
671 TAG_LOGE(AAFwkTag::FREE_INSTALL, "null appMgr");
672 return ERR_INVALID_VALUE;
673 }
674
675 bool isAppRunning = appMgr->GetAppRunningStateByBundleName(want.GetElement().GetBundleName());
676 TAG_LOGI(AAFwkTag::FREE_INSTALL, "isAppRunning:%{public}d", static_cast<int>(isAppRunning));
677 want.SetParam(KEY_IS_APP_RUNNING, isAppRunning);
678 return ERR_OK;
679 }
680
GetFreeInstallTaskInfo(const std::string & bundleName,const std::string & abilityName,const std::string & startTime,FreeInstallInfo & taskInfo)681 bool FreeInstallManager::GetFreeInstallTaskInfo(const std::string& bundleName, const std::string& abilityName,
682 const std::string& startTime, FreeInstallInfo& taskInfo)
683 {
684 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
685 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
686 if ((*it).want.GetElement().GetBundleName() == bundleName &&
687 (*it).want.GetElement().GetAbilityName() == abilityName &&
688 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) {
689 taskInfo = *it;
690 return true;
691 }
692 it++;
693 }
694 return false;
695 }
696
GetFreeInstallTaskInfo(const std::string & sessionId,FreeInstallInfo & taskInfo)697 bool FreeInstallManager::GetFreeInstallTaskInfo(const std::string& sessionId, FreeInstallInfo& taskInfo)
698 {
699 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
700 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
701 if ((*it).want.GetStringParam(KEY_SESSION_ID) == sessionId) {
702 taskInfo = *it;
703 return true;
704 }
705 it++;
706 }
707 return false;
708 }
709
SetSCBCallStatus(const std::string & bundleName,const std::string & abilityName,const std::string & startTime,bool scbCallStatus)710 void FreeInstallManager::SetSCBCallStatus(const std::string& bundleName, const std::string& abilityName,
711 const std::string& startTime, bool scbCallStatus)
712 {
713 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
714 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
715 if ((*it).want.GetElement().GetBundleName() == bundleName &&
716 (*it).want.GetElement().GetAbilityName() == abilityName &&
717 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) {
718 (*it).isStartUIAbilityBySCBCalled = scbCallStatus;
719 return;
720 }
721 it++;
722 }
723 }
724
SetPreStartMissionCallStatus(const std::string & bundleName,const std::string & abilityName,const std::string & startTime,bool preStartMissionCallStatus)725 void FreeInstallManager::SetPreStartMissionCallStatus(const std::string& bundleName, const std::string& abilityName,
726 const std::string& startTime, bool preStartMissionCallStatus)
727 {
728 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
729 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
730 if ((*it).want.GetElement().GetBundleName() == bundleName &&
731 (*it).want.GetElement().GetAbilityName() == abilityName &&
732 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) {
733 (*it).isPreStartMissionCalled = preStartMissionCallStatus;
734 return;
735 }
736 it++;
737 }
738 }
739
SetFreeInstallTaskSessionId(const std::string & bundleName,const std::string & abilityName,const std::string & startTime,const std::string & sessionId)740 void FreeInstallManager::SetFreeInstallTaskSessionId(const std::string& bundleName, const std::string& abilityName,
741 const std::string& startTime, const std::string& sessionId)
742 {
743 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
744 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
745 if ((*it).want.GetElement().GetBundleName() == bundleName &&
746 (*it).want.GetElement().GetAbilityName() == abilityName &&
747 (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME) == startTime) {
748 (*it).want.SetParam(KEY_SESSION_ID, sessionId);
749 return;
750 }
751 it++;
752 }
753 }
754
NotifyInsightIntentFreeInstallResult(const Want & want,int resultCode)755 void FreeInstallManager::NotifyInsightIntentFreeInstallResult(const Want &want, int resultCode)
756 {
757 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
758 TAG_LOGI(AAFwkTag::FREE_INSTALL, "insight install result:%{public}d", resultCode);
759 if (resultCode != ERR_OK) {
760 RemoveFreeInstallInfo(want.GetElement().GetBundleName(), want.GetElement().GetAbilityName(),
761 want.GetStringParam(Want::PARAM_RESV_START_TIME));
762 NotifyInsightIntentExecuteDone(want, ERR_INVALID_VALUE);
763 return;
764 }
765
766 std::lock_guard<ffrt::mutex> lock(freeInstallListLock_);
767 if (freeInstallList_.empty()) {
768 TAG_LOGI(AAFwkTag::FREE_INSTALL, "list empty");
769 return;
770 }
771
772 for (auto it = freeInstallList_.begin(); it != freeInstallList_.end();) {
773 std::string bundleName = (*it).want.GetElement().GetBundleName();
774 std::string abilityName = (*it).want.GetElement().GetAbilityName();
775 std::string startTime = (*it).want.GetStringParam(Want::PARAM_RESV_START_TIME);
776 if (want.GetElement().GetBundleName().compare(bundleName) != 0 ||
777 want.GetElement().GetAbilityName().compare(abilityName) != 0 ||
778 want.GetStringParam(Want::PARAM_RESV_START_TIME).compare(startTime) != 0) {
779 it++;
780 continue;
781 }
782
783 auto moduleName = (*it).want.GetElement().GetModuleName();
784 auto insightIntentName = (*it).want.GetStringParam(AppExecFwk::INSIGHT_INTENT_EXECUTE_PARAM_NAME);
785 auto executeMode = static_cast<AppExecFwk::ExecuteMode>(
786 it->want.GetIntParam(AppExecFwk::INSIGHT_INTENT_EXECUTE_PARAM_MODE, 0));
787 std::string srcEntry;
788 auto ret = AbilityRuntime::InsightIntentUtils::GetSrcEntry(it->want.GetElement(), insightIntentName,
789 executeMode, srcEntry);
790 if (ret != ERR_OK || srcEntry.empty()) {
791 TAG_LOGE(AAFwkTag::FREE_INSTALL, "failed. bundleName: %{public}s, "
792 "moduleName: %{public}s, insightIntentName: %{public}s", bundleName.c_str(), moduleName.c_str(),
793 insightIntentName.c_str());
794 NotifyInsightIntentExecuteDone(want, ERR_INVALID_VALUE);
795 } else {
796 (*it).want.SetParam(AppExecFwk::INSIGHT_INTENT_SRC_ENTRY, srcEntry);
797 StartAbilityByFreeInstall(*it, bundleName, abilityName, startTime);
798 }
799
800 it = freeInstallList_.erase(it);
801 }
802 }
803
NotifyInsightIntentExecuteDone(const Want & want,int resultCode)804 void FreeInstallManager::NotifyInsightIntentExecuteDone(const Want &want, int resultCode)
805 {
806 InsightIntentExecuteParam executeParam;
807 InsightIntentExecuteParam::GenerateFromWant(want, executeParam);
808 AppExecFwk::InsightIntentExecuteResult result;
809 auto ret = DelayedSingleton<InsightIntentExecuteManager>::GetInstance()->ExecuteIntentDone(
810 executeParam.insightIntentId_, resultCode, result);
811 if (ret != ERR_OK) {
812 TAG_LOGE(AAFwkTag::FREE_INSTALL, "failed with %{public}d", ret);
813 }
814 }
815 } // namespace AAFwk
816 } // namespace OHOS
817