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