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