• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "extension_record_factory.h"
17 
18 #include "ability_util.h"
19 #include "app_utils.h"
20 #include "multi_instance_utils.h"
21 
22 namespace OHOS {
23 namespace AbilityRuntime {
24 using namespace OHOS::AppExecFwk;
25 namespace {
26 const std::map<AppExecFwk::ExtensionAbilityType, ExtensionRecordConfig> EXTENSION_RECORD_CONFIG_MAP = {
27     { AppExecFwk::ExtensionAbilityType::EMBEDDED_UI,
28       { PROCESS_MODE_BUNDLE, PROCESS_MODE_SUPPORT_DEFAULT | PROCESS_MODE_HOST_SPECIFIED |
29         PROCESS_MODE_HOST_INSTANCE | PROCESS_MODE_CUSTOM,
30         PRE_CHECK_FLAG_CALLED_WITHIN_THE_BUNDLE | PRE_CHECK_FLAG_MULTIPLE_PROCESSES }},
31     { AppExecFwk::ExtensionAbilityType::STATUS_BAR_VIEW,
32       { PROCESS_MODE_BUNDLE, PROCESS_MODE_SUPPORT_DEFAULT | PROCESS_MODE_RUN_WITH_MAIN_PROCESS,
33         PRE_CHECK_FLAG_NONE }},
34     { AppExecFwk::ExtensionAbilityType::AWC_WEBPAGE,
35       { PROCESS_MODE_BUNDLE, PROCESS_MODE_SUPPORT_DEFAULT | PROCESS_MODE_RUN_WITH_MAIN_PROCESS,
36         PRE_CHECK_FLAG_NONE }},
37     { AppExecFwk::ExtensionAbilityType::AWC_NEWSFEED,
38       { PROCESS_MODE_BUNDLE, PROCESS_MODE_SUPPORT_DEFAULT | PROCESS_MODE_RUN_WITH_MAIN_PROCESS,
39         PRE_CHECK_FLAG_NONE }},
40     { AppExecFwk::ExtensionAbilityType::LIVE_FORM, { PROCESS_MODE_BUNDLE, PROCESS_MODE_BUNDLE, PRE_CHECK_FLAG_NONE }},
41 };
42 
GetPreCheckFlag(ExtensionAbilityType type)43 uint32_t GetPreCheckFlag(ExtensionAbilityType type)
44 {
45     auto iter = EXTENSION_RECORD_CONFIG_MAP.find(type);
46     if (iter == EXTENSION_RECORD_CONFIG_MAP.end()) {
47         return PRE_CHECK_FLAG_NONE;
48     }
49     return iter->second.preCheckFlag;
50 }
51 }
52 
53 ExtensionRecordFactory::ExtensionRecordFactory() = default;
54 
55 ExtensionRecordFactory::~ExtensionRecordFactory() = default;
56 
NeedReuse(const AAFwk::AbilityRequest & abilityRequest,int32_t & extensionRecordId)57 bool ExtensionRecordFactory::NeedReuse(const AAFwk::AbilityRequest &abilityRequest, int32_t &extensionRecordId)
58 {
59     return false;
60 }
61 
PreCheck(const AAFwk::AbilityRequest & abilityRequest,const std::string & hostBundleName)62 int32_t ExtensionRecordFactory::PreCheck(const AAFwk::AbilityRequest &abilityRequest, const std::string &hostBundleName)
63 {
64     uint32_t preCheckFlag = GetPreCheckFlag(abilityRequest.extensionType);
65     if (preCheckFlag == 0) {
66         return ERR_OK;
67     }
68     if (preCheckFlag & PRE_CHECK_FLAG_CALLED_WITHIN_THE_BUNDLE) {
69         if (hostBundleName != abilityRequest.abilityInfo.applicationName) {
70             TAG_LOGW(AAFwkTag::ABILITYMGR, "not called");
71             return ERR_INVALID_VALUE;
72         }
73 
74         // There may exist preload extension, the session info is nullptr
75         if (abilityRequest.sessionInfo != nullptr) {
76             auto callerToken = abilityRequest.sessionInfo->callerToken;
77             auto callerAbilityRecord = AAFwk::Token::GetAbilityRecordByToken(callerToken);
78             CHECK_POINTER_AND_RETURN(callerAbilityRecord, ERR_INVALID_VALUE);
79             AppExecFwk::AbilityInfo abilityInfo = callerAbilityRecord->GetAbilityInfo();
80             if (abilityInfo.type != AbilityType::PAGE) {
81                 TAG_LOGW(AAFwkTag::ABILITYMGR, "not UIAbility");
82                 return ERR_INVALID_VALUE;
83             }
84         }
85     }
86     if (preCheckFlag & PRE_CHECK_FLAG_MULTIPLE_PROCESSES) {
87         if (!AppUtils::GetInstance().IsMultiProcessModel()) {
88             TAG_LOGW(AAFwkTag::ABILITYMGR, "not multi process model");
89             return ERR_INVALID_VALUE;
90         }
91     }
92     return ERR_OK;
93 }
94 
GetExtensionProcessMode(const AAFwk::AbilityRequest & abilityRequest,bool & isHostSpecified)95 uint32_t ExtensionRecordFactory::GetExtensionProcessMode(
96     const AAFwk::AbilityRequest &abilityRequest, bool &isHostSpecified)
97 {
98     ExtensionRecordConfig config;
99     auto iter = EXTENSION_RECORD_CONFIG_MAP.find(abilityRequest.extensionType);
100     if (iter != EXTENSION_RECORD_CONFIG_MAP.end()) {
101         config = iter->second;
102     }
103 
104     // check host specified
105     isHostSpecified = false;
106     if (config.processModeSupport & PROCESS_MODE_HOST_SPECIFIED) {
107         if (abilityRequest.want.HasParameter(PROCESS_MODE_HOST_SPECIFIED_KEY)) {
108             isHostSpecified = true;
109             return PROCESS_MODE_HOST_SPECIFIED;
110         }
111     }
112 
113     if (config.processModeSupport & PROCESS_MODE_HOST_INSTANCE) {
114         if (abilityRequest.want.HasParameter(PROCESS_MODE_HOST_INSTANCE_KEY)) {
115             bool hostInstance = abilityRequest.want.GetBoolParam(PROCESS_MODE_HOST_INSTANCE_KEY, false);
116             if (hostInstance) {
117                 return PROCESS_MODE_INSTANCE;
118             }
119         }
120     }
121 
122     if (config.processModeSupport & PROCESS_MODE_CUSTOM) {
123         if (!abilityRequest.customProcess.empty()) {
124             return PROCESS_MODE_CUSTOM;
125         }
126     }
127 
128     if (abilityRequest.extensionProcessMode == ExtensionProcessMode::UNDEFINED) {
129         return config.processModeDefault;
130     }
131     uint32_t inputProcessMode = 1 << static_cast<int32_t>(abilityRequest.extensionProcessMode);
132     if (config.processModeSupport & inputProcessMode) {
133         return inputProcessMode;
134     }
135     return config.processModeDefault;
136 }
137 
CreateRecord(const AAFwk::AbilityRequest & abilityRequest,std::shared_ptr<ExtensionRecord> & extensionRecord)138 int32_t ExtensionRecordFactory::CreateRecord(
139     const AAFwk::AbilityRequest &abilityRequest, std::shared_ptr<ExtensionRecord> &extensionRecord)
140 {
141     auto abilityRecord = AAFwk::AbilityRecord::CreateAbilityRecord(abilityRequest);
142     if (abilityRecord == nullptr) {
143         TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityRecord create failed");
144         return ERR_NULL_OBJECT;
145     }
146     if (AAFwk::MultiInstanceUtils::IsMultiInstanceApp(abilityRequest.appInfo)) {
147         abilityRecord->SetInstanceKey(AAFwk::MultiInstanceUtils::GetValidExtensionInstanceKey(abilityRequest));
148     }
149     extensionRecord = std::make_shared<ExtensionRecord>(abilityRecord);
150     extensionRecord->processMode_ = GetExtensionProcessMode(abilityRequest, extensionRecord->isHostSpecified_);
151     return ERR_OK;
152 }
153 } // namespace AbilityRuntime
154 } // namespace OHOS
155