1 /*
2  * Copyright (c) 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 "start_ability_utils.h"
17 
18 #include "ability_record.h"
19 #include "ability_util.h"
20 #include "app_utils.h"
21 #include "global_constant.h"
22 #include "hitrace_meter.h"
23 #include "startup_util.h"
24 
25 namespace OHOS {
26 namespace AAFwk {
27 namespace {
28 constexpr const char* SCREENSHOT_BUNDLE_NAME = "com.huawei.ohos.screenshot";
29 constexpr const char* SCREENSHOT_ABILITY_NAME = "com.huawei.ohos.screenshot.ServiceExtAbility";
30 constexpr int32_t ERMS_ISALLOW_RESULTCODE = 10;
31 constexpr const char* SHELL_ASSISTANT_BUNDLENAME = "com.huawei.shell_assistant";
32 constexpr int32_t BROKER_UID = 5557;
33 constexpr const char* PARAM_RESV_ANCO_CALLER_UID = "ohos.anco.param.callerUid";
34 constexpr const char* PARAM_RESV_ANCO_CALLER_BUNDLENAME = "ohos.anco.param.callerBundleName";
35 }
36 thread_local std::shared_ptr<StartAbilityInfo> StartAbilityUtils::startAbilityInfo;
37 thread_local std::shared_ptr<StartAbilityInfo> StartAbilityUtils::callerAbilityInfo;
38 thread_local bool StartAbilityUtils::skipCrowTest = false;
39 thread_local bool StartAbilityUtils::skipStartOther = false;
40 thread_local bool StartAbilityUtils::skipErms = false;
41 thread_local int32_t StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE;
42 thread_local bool StartAbilityUtils::isWantWithAppCloneIndex = false;
43 thread_local bool StartAbilityUtils::ermsSupportBackToCallerFlag = false;
44 
GetAppIndex(const Want & want,sptr<IRemoteObject> callerToken,int32_t & appIndex)45 bool StartAbilityUtils::GetAppIndex(const Want &want, sptr<IRemoteObject> callerToken, int32_t &appIndex)
46 {
47     auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
48     if (abilityRecord && abilityRecord->GetAppIndex() > AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX &&
49         abilityRecord->GetApplicationInfo().bundleName == want.GetElement().GetBundleName()) {
50         appIndex = abilityRecord->GetAppIndex();
51         return true;
52     }
53     TAG_LOGI(AAFwkTag::ABILITYMGR, "appCloneIndex: %{public}d.", want.GetIntParam(Want::PARAM_APP_CLONE_INDEX_KEY, 0));
54     return AbilityRuntime::StartupUtil::GetAppIndex(want, appIndex);
55 }
56 
GetApplicationInfo(const std::string & bundleName,int32_t userId,AppExecFwk::ApplicationInfo & appInfo)57 bool StartAbilityUtils::GetApplicationInfo(const std::string &bundleName, int32_t userId,
58     AppExecFwk::ApplicationInfo &appInfo)
59 {
60     if (StartAbilityUtils::startAbilityInfo &&
61         StartAbilityUtils::startAbilityInfo->GetAppBundleName() == bundleName) {
62         appInfo = StartAbilityUtils::startAbilityInfo->abilityInfo.applicationInfo;
63     } else {
64         if (bundleName.empty()) {
65             return false;
66         }
67         auto bms = AbilityUtil::GetBundleManagerHelper();
68         CHECK_POINTER_AND_RETURN(bms, false);
69         bool result = IN_PROCESS_CALL(
70             bms->GetApplicationInfo(bundleName, AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO,
71                 userId, appInfo)
72         );
73         if (!result) {
74             TAG_LOGW(AAFwkTag::ABILITYMGR, "Get app info from bms failed: %{public}s", bundleName.c_str());
75             return false;
76         }
77     }
78     return true;
79 }
80 
GetCallerAbilityInfo(const sptr<IRemoteObject> & callerToken,AppExecFwk::AbilityInfo & abilityInfo)81 bool StartAbilityUtils::GetCallerAbilityInfo(const sptr<IRemoteObject> &callerToken,
82     AppExecFwk::AbilityInfo &abilityInfo)
83 {
84     if (StartAbilityUtils::callerAbilityInfo) {
85         abilityInfo = StartAbilityUtils::callerAbilityInfo->abilityInfo;
86     } else {
87         if (callerToken == nullptr) {
88             return false;
89         }
90         auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
91         if (abilityRecord == nullptr) {
92             return false;
93         }
94         abilityInfo = abilityRecord->GetAbilityInfo();
95     }
96     return true;
97 }
98 
GetCloneAppIndexes(const std::string & bundleName,int32_t userId)99 std::vector<int32_t> StartAbilityUtils::GetCloneAppIndexes(const std::string &bundleName, int32_t userId)
100 {
101     std::vector<int32_t> appIndexes;
102     auto bms = AbilityUtil::GetBundleManagerHelper();
103     CHECK_POINTER_AND_RETURN(bms, appIndexes);
104     IN_PROCESS_CALL_WITHOUT_RET(bms->GetCloneAppIndexes(bundleName, appIndexes, userId));
105     return appIndexes;
106 }
107 
CheckAppProvisionMode(const std::string & bundleName,int32_t userId)108 int32_t StartAbilityUtils::CheckAppProvisionMode(const std::string& bundleName, int32_t userId)
109 {
110     AppExecFwk::ApplicationInfo appInfo;
111     if (!GetApplicationInfo(bundleName, userId, appInfo)) {
112         TAG_LOGE(AAFwkTag::ABILITYMGR, "Get application info failed: %{public}s", bundleName.c_str());
113         return ERR_INVALID_VALUE;
114     }
115     if (appInfo.appProvisionType != AppExecFwk::Constants::APP_PROVISION_TYPE_DEBUG) {
116         return ERR_NOT_IN_APP_PROVISION_MODE;
117     }
118     return ERR_OK;
119 }
120 
CheckAppProvisionMode(const Want & want,int32_t userId)121 int32_t StartAbilityUtils::CheckAppProvisionMode(const Want& want, int32_t userId)
122 {
123     auto abilityInfo = StartAbilityUtils::startAbilityInfo;
124     if (!abilityInfo || abilityInfo->GetAppBundleName() != want.GetElement().GetBundleName()) {
125         int32_t appIndex = 0;
126         if (!AbilityRuntime::StartupUtil::GetAppIndex(want, appIndex)) {
127             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid app clone index");
128             return ERR_APP_CLONE_INDEX_INVALID;
129         }
130         abilityInfo = StartAbilityInfo::CreateStartAbilityInfo(want, userId, appIndex);
131     }
132     CHECK_POINTER_AND_RETURN(abilityInfo, GET_ABILITY_SERVICE_FAILED);
133     if (abilityInfo->status != ERR_OK) {
134         TAG_LOGE(AAFwkTag::ABILITYMGR, "unexpected abilityInfo status=%{public}d", abilityInfo->status);
135         return abilityInfo->status;
136     }
137     if ((abilityInfo->abilityInfo).applicationInfo.appProvisionType !=
138         AppExecFwk::Constants::APP_PROVISION_TYPE_DEBUG) {
139         TAG_LOGE(AAFwkTag::ABILITYMGR, "window options are not supported in non-app-provision mode.");
140         return ERR_NOT_IN_APP_PROVISION_MODE;
141     }
142     return ERR_OK;
143 }
144 
StartAbilityInfoWrap(const Want & want,int32_t validUserId,int32_t appIndex,const sptr<IRemoteObject> & callerToken,bool isExtension)145 StartAbilityInfoWrap::StartAbilityInfoWrap(const Want &want, int32_t validUserId, int32_t appIndex,
146     const sptr<IRemoteObject> &callerToken, bool isExtension)
147 {
148     if (StartAbilityUtils::startAbilityInfo != nullptr) {
149         TAG_LOGW(AAFwkTag::ABILITYMGR, "startAbilityInfo has been created");
150     }
151     // This is for special goal and could be removed later.
152     auto element = want.GetElement();
153     if (element.GetAbilityName() == SCREENSHOT_ABILITY_NAME &&
154         element.GetBundleName() == SCREENSHOT_BUNDLE_NAME) {
155         isExtension = true;
156         StartAbilityUtils::skipErms = true;
157     }
158     Want localWant = want;
159     if (!StartAbilityUtils::IsCallFromAncoShellOrBroker(callerToken)) {
160         TAG_LOGD(AAFwkTag::ABILITYMGR, "not call from anco or broker.");
161         localWant.RemoveParam(PARAM_RESV_ANCO_CALLER_UID);
162         localWant.RemoveParam(PARAM_RESV_ANCO_CALLER_BUNDLENAME);
163         localWant.RemoveParam(Want::PARAM_RESV_CALLER_TOKEN);
164         localWant.RemoveParam(Want::PARAM_RESV_CALLER_UID);
165         localWant.RemoveParam(Want::PARAM_RESV_CALLER_BUNDLE_NAME);
166         localWant.SetParam(Want::PARAM_RESV_CALLER_TOKEN, static_cast<int32_t>(IPCSkeleton::GetCallingTokenID()));
167         localWant.SetParam(Want::PARAM_RESV_CALLER_UID, IPCSkeleton::GetCallingUid());
168     }
169     if (isExtension) {
170         StartAbilityUtils::startAbilityInfo = StartAbilityInfo::CreateStartExtensionInfo(localWant,
171             validUserId, appIndex);
172     } else {
173         StartAbilityUtils::startAbilityInfo = StartAbilityInfo::CreateStartAbilityInfo(localWant,
174             validUserId, appIndex);
175     }
176     if (StartAbilityUtils::startAbilityInfo != nullptr &&
177         StartAbilityUtils::startAbilityInfo->abilityInfo.type == AppExecFwk::AbilityType::EXTENSION) {
178         StartAbilityUtils::skipCrowTest = true;
179         StartAbilityUtils::skipStartOther = true;
180     }
181 
182     if (StartAbilityUtils::callerAbilityInfo != nullptr) {
183         TAG_LOGW(AAFwkTag::ABILITYMGR, "callerAbilityInfo has been created");
184     }
185     StartAbilityUtils::callerAbilityInfo = StartAbilityInfo::CreateCallerAbilityInfo(callerToken);
186 
187     StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE;
188     StartAbilityUtils::isWantWithAppCloneIndex = false;
189     if (want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY) && appIndex >= 0 &&
190         appIndex < AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) {
191         StartAbilityUtils::isWantWithAppCloneIndex = true;
192     }
193 }
StartAbilityInfoWrap()194 StartAbilityInfoWrap::StartAbilityInfoWrap()
195 {
196     StartAbilityUtils::startAbilityInfo.reset();
197     StartAbilityUtils::callerAbilityInfo.reset();
198     StartAbilityUtils::skipCrowTest = false;
199     StartAbilityUtils::skipStartOther = false;
200     StartAbilityUtils::skipErms = false;
201     StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE;
202     StartAbilityUtils::isWantWithAppCloneIndex = false;
203 }
204 
~StartAbilityInfoWrap()205 StartAbilityInfoWrap::~StartAbilityInfoWrap()
206 {
207     StartAbilityUtils::startAbilityInfo.reset();
208     StartAbilityUtils::callerAbilityInfo.reset();
209     StartAbilityUtils::skipCrowTest = false;
210     StartAbilityUtils::skipStartOther = false;
211     StartAbilityUtils::skipErms = false;
212     StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE;
213     StartAbilityUtils::isWantWithAppCloneIndex = false;
214 }
215 
SetStartAbilityInfo(const AppExecFwk::AbilityInfo & abilityInfo)216 void StartAbilityInfoWrap::SetStartAbilityInfo(const AppExecFwk::AbilityInfo& abilityInfo)
217 {
218     if (StartAbilityUtils::startAbilityInfo != nullptr) {
219         return;
220     }
221     StartAbilityUtils::startAbilityInfo = std::make_shared<StartAbilityInfo>();
222     StartAbilityUtils::startAbilityInfo->abilityInfo = abilityInfo;
223 }
224 
CreateStartAbilityInfo(const Want & want,int32_t userId,int32_t appIndex)225 std::shared_ptr<StartAbilityInfo> StartAbilityInfo::CreateStartAbilityInfo(const Want &want, int32_t userId,
226     int32_t appIndex)
227 {
228     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
229     auto bms = AbilityUtil::GetBundleManagerHelper();
230     CHECK_POINTER_AND_RETURN(bms, nullptr);
231     auto abilityInfoFlag = AbilityRuntime::StartupUtil::BuildAbilityInfoFlag() |
232         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL;
233     auto request = std::make_shared<StartAbilityInfo>();
234     if (appIndex > 0 && appIndex <= AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) {
235         IN_PROCESS_CALL_WITHOUT_RET(bms->QueryCloneAbilityInfo(want.GetElement(), abilityInfoFlag, appIndex,
236             request->abilityInfo, userId));
237         if (request->abilityInfo.name.empty() || request->abilityInfo.bundleName.empty()) {
238             FindExtensionInfo(want, abilityInfoFlag, userId, appIndex, request);
239         }
240         return request;
241     }
242     if (appIndex == 0) {
243         IN_PROCESS_CALL_WITHOUT_RET(bms->QueryAbilityInfo(want, abilityInfoFlag, userId, request->abilityInfo));
244     } else {
245         IN_PROCESS_CALL_WITHOUT_RET(bms->GetSandboxAbilityInfo(want, appIndex,
246             abilityInfoFlag, userId, request->abilityInfo));
247     }
248     if (request->abilityInfo.name.empty() || request->abilityInfo.bundleName.empty()) {
249         // try to find extension
250         std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
251         if (appIndex == 0) {
252             IN_PROCESS_CALL_WITHOUT_RET(bms->QueryExtensionAbilityInfos(want, abilityInfoFlag,
253                 userId, extensionInfos));
254         } else {
255             IN_PROCESS_CALL_WITHOUT_RET(bms->GetSandboxExtAbilityInfos(want, appIndex,
256                 abilityInfoFlag, userId, extensionInfos));
257         }
258         if (extensionInfos.size() <= 0) {
259             TAG_LOGE(AAFwkTag::ABILITYMGR, "Get extension info failed.");
260             request->status = RESOLVE_ABILITY_ERR;
261             return request;
262         }
263 
264         AppExecFwk::ExtensionAbilityInfo extensionInfo = extensionInfos.front();
265         if (extensionInfo.bundleName.empty() || extensionInfo.name.empty()) {
266             TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionInfo empty.");
267             request->status = RESOLVE_ABILITY_ERR;
268             return request;
269         }
270         request->extensionProcessMode = extensionInfo.extensionProcessMode;
271         // For compatibility translates to AbilityInfo
272         AbilityRuntime::StartupUtil::InitAbilityInfoFromExtension(extensionInfo, request->abilityInfo);
273     }
274     return request;
275 }
276 
CreateStartExtensionInfo(const Want & want,int32_t userId,int32_t appIndex)277 std::shared_ptr<StartAbilityInfo> StartAbilityInfo::CreateStartExtensionInfo(const Want &want, int32_t userId,
278     int32_t appIndex)
279 {
280     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
281     auto bms = AbilityUtil::GetBundleManagerHelper();
282     CHECK_POINTER_AND_RETURN(bms, nullptr);
283     auto abilityInfoFlag = AbilityRuntime::StartupUtil::BuildAbilityInfoFlag() |
284         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL;
285     auto abilityInfo = std::make_shared<StartAbilityInfo>();
286     if (appIndex > 0 && appIndex <= AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) {
287         FindExtensionInfo(want, abilityInfoFlag, userId, appIndex, abilityInfo);
288         return abilityInfo;
289     }
290 
291     std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
292     if (appIndex == 0) {
293         IN_PROCESS_CALL_WITHOUT_RET(bms->QueryExtensionAbilityInfos(want, abilityInfoFlag, userId, extensionInfos));
294     } else {
295         IN_PROCESS_CALL_WITHOUT_RET(bms->GetSandboxExtAbilityInfos(want, appIndex,
296             abilityInfoFlag, userId, extensionInfos));
297     }
298     if (extensionInfos.size() <= 0) {
299         TAG_LOGE(AAFwkTag::ABILITYMGR, "CreateStartExtensionInfo error. Get extension info failed.");
300         abilityInfo->status = RESOLVE_ABILITY_ERR;
301         return abilityInfo;
302     }
303 
304     AppExecFwk::ExtensionAbilityInfo extensionInfo = extensionInfos.front();
305     if (extensionInfo.bundleName.empty() || extensionInfo.name.empty()) {
306         TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionInfo empty.");
307         abilityInfo->status = RESOLVE_ABILITY_ERR;
308         return abilityInfo;
309     }
310     abilityInfo->extensionProcessMode = extensionInfo.extensionProcessMode;
311     // For compatibility translates to AbilityInfo
312     AbilityRuntime::StartupUtil::InitAbilityInfoFromExtension(extensionInfo, abilityInfo->abilityInfo);
313 
314     return abilityInfo;
315 }
316 
FindExtensionInfo(const Want & want,int32_t flags,int32_t userId,int32_t appIndex,std::shared_ptr<StartAbilityInfo> abilityInfo)317 void StartAbilityInfo::FindExtensionInfo(const Want &want, int32_t flags, int32_t userId,
318     int32_t appIndex, std::shared_ptr<StartAbilityInfo> abilityInfo)
319 {
320     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
321     CHECK_POINTER_LOG(abilityInfo, "abilityInfo is invalid.");
322     auto bms = AbilityUtil::GetBundleManagerHelper();
323     CHECK_POINTER_LOG(bms, "bms is invalid.");
324     AppExecFwk::ExtensionAbilityInfo extensionInfo;
325     IN_PROCESS_CALL_WITHOUT_RET(bms->QueryCloneExtensionAbilityInfoWithAppIndex(want.GetElement(),
326         flags, appIndex, extensionInfo, userId));
327     if (extensionInfo.bundleName.empty() || extensionInfo.name.empty()) {
328         TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionInfo empty.");
329         abilityInfo->status = RESOLVE_ABILITY_ERR;
330         return;
331     }
332     if (AbilityRuntime::StartupUtil::IsSupportAppClone(extensionInfo.type)) {
333         abilityInfo->extensionProcessMode = extensionInfo.extensionProcessMode;
334         // For compatibility translates to AbilityInfo
335         AbilityRuntime::StartupUtil::InitAbilityInfoFromExtension(extensionInfo, abilityInfo->abilityInfo);
336     } else {
337         abilityInfo->status = ERR_APP_CLONE_INDEX_INVALID;
338     }
339 }
340 
CreateCallerAbilityInfo(const sptr<IRemoteObject> & callerToken)341 std::shared_ptr<StartAbilityInfo> StartAbilityInfo::CreateCallerAbilityInfo(const sptr<IRemoteObject> &callerToken)
342 {
343     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
344     if (callerToken == nullptr) {
345         TAG_LOGD(AAFwkTag::ABILITYMGR, "not call from context.");
346         return nullptr;
347     }
348     auto abilityRecord = Token::GetAbilityRecordByToken(callerToken);
349     if (abilityRecord == nullptr) {
350         TAG_LOGE(AAFwkTag::ABILITYMGR, "can not find abilityRecord");
351         return nullptr;
352     }
353     auto request = std::make_shared<StartAbilityInfo>();
354     request->abilityInfo = abilityRecord->GetAbilityInfo();
355     return request;
356 }
357 
IsCallFromAncoShellOrBroker(const sptr<IRemoteObject> & callerToken)358 bool StartAbilityUtils::IsCallFromAncoShellOrBroker(const sptr<IRemoteObject> &callerToken)
359 {
360     auto callingUid = IPCSkeleton::GetCallingUid();
361     if (callingUid == BROKER_UID) {
362         return true;
363     }
364     AppExecFwk::AbilityInfo callerAbilityInfo;
365     if (GetCallerAbilityInfo(callerToken, callerAbilityInfo)) {
366         return callerAbilityInfo.bundleName == SHELL_ASSISTANT_BUNDLENAME;
367     }
368     return false;
369 }
370 }
371 }