1eace7efcSopenharmony_ci/*
2eace7efcSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3eace7efcSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4eace7efcSopenharmony_ci * you may not use this file except in compliance with the License.
5eace7efcSopenharmony_ci * You may obtain a copy of the License at
6eace7efcSopenharmony_ci *
7eace7efcSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8eace7efcSopenharmony_ci *
9eace7efcSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10eace7efcSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11eace7efcSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12eace7efcSopenharmony_ci * See the License for the specific language governing permissions and
13eace7efcSopenharmony_ci * limitations under the License.
14eace7efcSopenharmony_ci */
15eace7efcSopenharmony_ci
16eace7efcSopenharmony_ci#include "app_preloader.h"
17eace7efcSopenharmony_ci
18eace7efcSopenharmony_ci#include <string>
19eace7efcSopenharmony_ci
20eace7efcSopenharmony_ci#include "ability_manager_errors.h"
21eace7efcSopenharmony_ci#include "in_process_call_wrapper.h"
22eace7efcSopenharmony_ci#include "hilog_tag_wrapper.h"
23eace7efcSopenharmony_ci#include "hitrace_meter.h"
24eace7efcSopenharmony_ci#include "res_sched_client.h"
25eace7efcSopenharmony_ci#include "res_type.h"
26eace7efcSopenharmony_ci#include "startup_util.h"
27eace7efcSopenharmony_ci
28eace7efcSopenharmony_cinamespace OHOS {
29eace7efcSopenharmony_cinamespace AppExecFwk {
30eace7efcSopenharmony_ciAppPreloader::AppPreloader(std::shared_ptr<RemoteClientManager> remoteClientManager)
31eace7efcSopenharmony_ci{
32eace7efcSopenharmony_ci    remoteClientManager_ = remoteClientManager;
33eace7efcSopenharmony_ci}
34eace7efcSopenharmony_ci
35eace7efcSopenharmony_cibool AppPreloader::PreCheck(const std::string &bundleName, PreloadMode preloadMode)
36eace7efcSopenharmony_ci{
37eace7efcSopenharmony_ci    HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
38eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::APPMGR, "PreloadApplication PreCheck, bundleName: %{public}s, preloadMode:%{public}d",
39eace7efcSopenharmony_ci        bundleName.c_str(), preloadMode);
40eace7efcSopenharmony_ci    if (preloadMode == PreloadMode::PRE_MAKE) {
41eace7efcSopenharmony_ci        return true;
42eace7efcSopenharmony_ci    }
43eace7efcSopenharmony_ci    int32_t mode = static_cast<int32_t>(preloadMode);
44eace7efcSopenharmony_ci    auto allow = ResourceSchedule::ResSchedClient::GetInstance().IsAllowedAppPreload(bundleName, mode);
45eace7efcSopenharmony_ci    if (!allow) {
46eace7efcSopenharmony_ci        TAG_LOGI(AAFwkTag::APPMGR, "BundleName: %{public}s not allow preload", bundleName.c_str());
47eace7efcSopenharmony_ci        return false;
48eace7efcSopenharmony_ci    }
49eace7efcSopenharmony_ci    return true;
50eace7efcSopenharmony_ci}
51eace7efcSopenharmony_ci
52eace7efcSopenharmony_ciint32_t AppPreloader::GeneratePreloadRequest(const std::string &bundleName, int32_t userId, int32_t appIndex,
53eace7efcSopenharmony_ci    PreloadRequest &request)
54eace7efcSopenharmony_ci{
55eace7efcSopenharmony_ci    HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
56eace7efcSopenharmony_ci    TAG_LOGD(AAFwkTag::APPMGR, "PreloadApplication GeneratePreloadRequest");
57eace7efcSopenharmony_ci
58eace7efcSopenharmony_ci    AAFwk::Want launchWant;
59eace7efcSopenharmony_ci    if (!GetLaunchWant(bundleName, userId, launchWant)) {
60eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "GetLaunchWant failed");
61eace7efcSopenharmony_ci        return AAFwk::ERR_TARGET_BUNDLE_NOT_EXIST;
62eace7efcSopenharmony_ci    }
63eace7efcSopenharmony_ci
64eace7efcSopenharmony_ci    AbilityInfo abilityInfo;
65eace7efcSopenharmony_ci    if (!GetLaunchAbilityInfo(launchWant, userId, abilityInfo)) {
66eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "GetLaunchAbilityInfo failed");
67eace7efcSopenharmony_ci        return AAFwk::ERR_GET_LAUNCH_ABILITY_INFO_FAILED;
68eace7efcSopenharmony_ci    }
69eace7efcSopenharmony_ci
70eace7efcSopenharmony_ci    if (!CheckPreloadConditions(abilityInfo)) {
71eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "CheckPreloadConditions failed");
72eace7efcSopenharmony_ci        return AAFwk::ERR_CHECK_PRELOAD_CONDITIONS_FAILED;
73eace7efcSopenharmony_ci    }
74eace7efcSopenharmony_ci
75eace7efcSopenharmony_ci    BundleInfo bundleInfo;
76eace7efcSopenharmony_ci    HapModuleInfo hapModuleInfo;
77eace7efcSopenharmony_ci    if (!GetBundleAndHapInfo(bundleName, userId, abilityInfo, bundleInfo, hapModuleInfo)) {
78eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "GetBundleAndHapInfo failed");
79eace7efcSopenharmony_ci        return AAFwk::GET_BUNDLE_INFO_FAILED;
80eace7efcSopenharmony_ci    }
81eace7efcSopenharmony_ci
82eace7efcSopenharmony_ci    request.abilityInfo =  std::make_shared<AbilityInfo>(abilityInfo);
83eace7efcSopenharmony_ci    request.appInfo = std::make_shared<ApplicationInfo>(abilityInfo.applicationInfo);
84eace7efcSopenharmony_ci    request.want = std::make_shared<AAFwk::Want>(launchWant);
85eace7efcSopenharmony_ci    request.bundleInfo = bundleInfo;
86eace7efcSopenharmony_ci    request.hapModuleInfo = hapModuleInfo;
87eace7efcSopenharmony_ci    request.appIndex = appIndex;
88eace7efcSopenharmony_ci
89eace7efcSopenharmony_ci    return ERR_OK;
90eace7efcSopenharmony_ci}
91eace7efcSopenharmony_ci
92eace7efcSopenharmony_cibool AppPreloader::GetLaunchWant(const std::string &bundleName, int32_t userId, AAFwk::Want &launchWant)
93eace7efcSopenharmony_ci{
94eace7efcSopenharmony_ci    HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
95eace7efcSopenharmony_ci    auto bundleMgrHelper = GetBundleManagerHelper();
96eace7efcSopenharmony_ci    if (!bundleMgrHelper) {
97eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "null bundleMgrHelper");
98eace7efcSopenharmony_ci        return false;
99eace7efcSopenharmony_ci    }
100eace7efcSopenharmony_ci
101eace7efcSopenharmony_ci    auto errCode = IN_PROCESS_CALL(bundleMgrHelper->GetLaunchWantForBundle(bundleName, launchWant, userId));
102eace7efcSopenharmony_ci    if (errCode != ERR_OK) {
103eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "errCode: %{public}d", errCode);
104eace7efcSopenharmony_ci        return false;
105eace7efcSopenharmony_ci    }
106eace7efcSopenharmony_ci    return true;
107eace7efcSopenharmony_ci}
108eace7efcSopenharmony_ci
109eace7efcSopenharmony_cibool AppPreloader::GetLaunchAbilityInfo(const AAFwk::Want &want, int32_t userId, AbilityInfo &abilityInfo)
110eace7efcSopenharmony_ci{
111eace7efcSopenharmony_ci    HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
112eace7efcSopenharmony_ci    auto bundleMgrHelper = GetBundleManagerHelper();
113eace7efcSopenharmony_ci    if (!bundleMgrHelper) {
114eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "null bundleMgrHelper");
115eace7efcSopenharmony_ci        return false;
116eace7efcSopenharmony_ci    }
117eace7efcSopenharmony_ci
118eace7efcSopenharmony_ci    auto abilityInfoFlag = AbilityRuntime::StartupUtil::BuildAbilityInfoFlag();
119eace7efcSopenharmony_ci    if (!IN_PROCESS_CALL(bundleMgrHelper->QueryAbilityInfo(want, abilityInfoFlag, userId, abilityInfo))) {
120eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "GetLaunchAbilityInfo failed");
121eace7efcSopenharmony_ci        return false;
122eace7efcSopenharmony_ci    }
123eace7efcSopenharmony_ci
124eace7efcSopenharmony_ci    return true;
125eace7efcSopenharmony_ci}
126eace7efcSopenharmony_ci
127eace7efcSopenharmony_cibool AppPreloader::GetBundleAndHapInfo(const std::string &bundleName, int32_t userId,
128eace7efcSopenharmony_ci    const AbilityInfo &abilityInfo, BundleInfo &bundleInfo, HapModuleInfo &hapModuleInfo)
129eace7efcSopenharmony_ci{
130eace7efcSopenharmony_ci    HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
131eace7efcSopenharmony_ci    auto bundleMgrHelper = GetBundleManagerHelper();
132eace7efcSopenharmony_ci    if (!bundleMgrHelper) {
133eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "null bundleMgrHelper");
134eace7efcSopenharmony_ci        return false;
135eace7efcSopenharmony_ci    }
136eace7efcSopenharmony_ci
137eace7efcSopenharmony_ci    auto flags = BundleFlag::GET_BUNDLE_DEFAULT | BundleFlag::GET_BUNDLE_WITH_REQUESTED_PERMISSION;
138eace7efcSopenharmony_ci    if (!IN_PROCESS_CALL(bundleMgrHelper->GetBundleInfo(bundleName,
139eace7efcSopenharmony_ci        static_cast<BundleFlag>(flags),
140eace7efcSopenharmony_ci        bundleInfo, userId))) {
141eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "GetBundleInfo failed");
142eace7efcSopenharmony_ci        return false;
143eace7efcSopenharmony_ci    }
144eace7efcSopenharmony_ci
145eace7efcSopenharmony_ci    if (!IN_PROCESS_CALL(bundleMgrHelper->GetHapModuleInfo(abilityInfo, userId, hapModuleInfo))) {
146eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "GetHapModuleInfo failed");
147eace7efcSopenharmony_ci        return false;
148eace7efcSopenharmony_ci    }
149eace7efcSopenharmony_ci    return true;
150eace7efcSopenharmony_ci}
151eace7efcSopenharmony_ci
152eace7efcSopenharmony_cibool AppPreloader::CheckPreloadConditions(const AbilityInfo &abilityInfo)
153eace7efcSopenharmony_ci{
154eace7efcSopenharmony_ci    if (abilityInfo.type != AppExecFwk::AbilityType::PAGE || !abilityInfo.isStageBasedModel) {
155eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "AbilityType is not UIAbility");
156eace7efcSopenharmony_ci        return false;
157eace7efcSopenharmony_ci    }
158eace7efcSopenharmony_ci    ApplicationInfo appInfo = abilityInfo.applicationInfo;
159eace7efcSopenharmony_ci    if (abilityInfo.name.empty() || appInfo.name.empty()) {
160eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "abilityInfo or appInfo name is empty");
161eace7efcSopenharmony_ci        return false;
162eace7efcSopenharmony_ci    }
163eace7efcSopenharmony_ci    if (abilityInfo.applicationName != appInfo.name) {
164eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "abilityInfo and appInfo have different appName");
165eace7efcSopenharmony_ci        return false;
166eace7efcSopenharmony_ci    }
167eace7efcSopenharmony_ci    return true;
168eace7efcSopenharmony_ci}
169eace7efcSopenharmony_ci
170eace7efcSopenharmony_cistd::shared_ptr<BundleMgrHelper> AppPreloader::GetBundleManagerHelper()
171eace7efcSopenharmony_ci{
172eace7efcSopenharmony_ci    if (!remoteClientManager_) {
173eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::APPMGR, "null remoteClientManager_");
174eace7efcSopenharmony_ci        return nullptr;
175eace7efcSopenharmony_ci    }
176eace7efcSopenharmony_ci    return remoteClientManager_->GetBundleManagerHelper();
177eace7efcSopenharmony_ci}
178eace7efcSopenharmony_ci}  // namespace AppExecFwk
179eace7efcSopenharmony_ci}  // namespace OHOS
180