• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "aot/aot_handler.h"
17 
18 #include <thread>
19 #include <vector>
20 
21 #include "appexecfwk_errors.h"
22 #include "app_log_wrapper.h"
23 #include "bundle_constants.h"
24 #include "bundle_mgr_service.h"
25 #include "bundle_util.h"
26 #include "installd_client.h"
27 #include "parameter.h"
28 #include "parameters.h"
29 #include "string_ex.h"
30 #ifdef BUNDLE_FRAMEWORK_POWER_MGR_ENABLE
31 #include "battery_srv_client.h"
32 #include "display_power_mgr_client.h"
33 #endif
34 
35 namespace OHOS {
36 namespace AppExecFwk {
37 namespace {
38 // ark compile option parameter key
39 constexpr const char* COMPILE_INSTALL_PARAM_KEY = "persist.bm.install.arkopt";
40 constexpr const char* COMPILE_IDLE_PARA_KEY = "persist.bm.idle.arkopt";
41 }
42 
GetInstance()43 AOTHandler& AOTHandler::GetInstance()
44 {
45     static AOTHandler handler;
46     return handler;
47 }
48 
IsSupportARM64() const49 bool AOTHandler::IsSupportARM64() const
50 {
51     std::string abis = GetAbiList();
52     APP_LOGD("abi list : %{public}s", abis.c_str());
53     std::vector<std::string> abiList;
54     SplitStr(abis, Constants::ABI_SEPARATOR, abiList, false, false);
55     if (abiList.empty()) {
56         APP_LOGD("abiList empty");
57         return false;
58     }
59     return std::find(abiList.begin(), abiList.end(), Constants::ARM64_V8A) != abiList.end();
60 }
61 
GetArkProfilePath(const std::string & bundleName,const std::string & moduleName) const62 std::string AOTHandler::GetArkProfilePath(const std::string &bundleName, const std::string &moduleName) const
63 {
64     APP_LOGD("GetArkProfilePath begin");
65     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
66     if (!dataMgr) {
67         APP_LOGE("dataMgr is null");
68         return Constants::EMPTY_STRING;
69     }
70     std::vector<int32_t> userIds = dataMgr->GetUserIds(bundleName);
71     for (int32_t userId : userIds) {
72         std::string path;
73         path.append(Constants::ARK_PROFILE_PATH).append(std::to_string(userId))
74             .append(Constants::PATH_SEPARATOR).append(bundleName)
75             .append(Constants::PATH_SEPARATOR).append(moduleName).append(Constants::AP_SUFFIX);
76         APP_LOGD("path : %{public}s", path.c_str());
77         bool isExistFile = false;
78         (void)InstalldClient::GetInstance()->IsExistFile(path, isExistFile);
79         if (isExistFile) {
80             return path;
81         }
82     }
83     APP_LOGD("GetArkProfilePath failed");
84     return Constants::EMPTY_STRING;
85 }
86 
BuildAOTArgs(const InnerBundleInfo & info,const std::string & moduleName,const std::string & compileMode) const87 std::optional<AOTArgs> AOTHandler::BuildAOTArgs(
88     const InnerBundleInfo &info, const std::string &moduleName, const std::string &compileMode) const
89 {
90     AOTArgs aotArgs;
91     aotArgs.bundleName = info.GetBundleName();
92     aotArgs.moduleName = moduleName;
93     if (compileMode == Constants::COMPILE_PARTIAL) {
94         aotArgs.arkProfilePath = GetArkProfilePath(aotArgs.bundleName, aotArgs.moduleName);
95         if (aotArgs.arkProfilePath.empty()) {
96             APP_LOGI("compile mode is partial, but ap not exist, no need to AOT");
97             return std::nullopt;
98         }
99     }
100     aotArgs.compileMode = compileMode;
101     aotArgs.hapPath = info.GetModuleHapPath(aotArgs.moduleName);
102     aotArgs.coreLibPath = Constants::EMPTY_STRING;
103     aotArgs.outputPath = Constants::ARK_CACHE_PATH + aotArgs.bundleName + Constants::PATH_SEPARATOR + Constants::ARM64;
104     APP_LOGD("args : %{public}s", aotArgs.ToString().c_str());
105     return aotArgs;
106 }
107 
AOTInternal(std::optional<AOTArgs> aotArgs,uint32_t versionCode) const108 void AOTHandler::AOTInternal(std::optional<AOTArgs> aotArgs, uint32_t versionCode) const
109 {
110     if (!aotArgs) {
111         APP_LOGI("aotArgs empty");
112         return;
113     }
114     ErrCode ret = ERR_OK;
115     {
116         std::lock_guard<std::mutex> lock(mutex_);
117         ret = InstalldClient::GetInstance()->ExecuteAOT(*aotArgs);
118     }
119     APP_LOGI("ExecuteAOT ret : %{public}d", ret);
120 
121     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
122     if (!dataMgr) {
123         APP_LOGE("dataMgr is null");
124         return;
125     }
126     AOTCompileStatus status = ret == ERR_OK ? AOTCompileStatus::COMPILE_SUCCESS : AOTCompileStatus::COMPILE_FAILED;
127     dataMgr->SetAOTCompileStatus(aotArgs->bundleName, aotArgs->moduleName, status, versionCode);
128 }
129 
HandleInstallWithSingleHap(const InnerBundleInfo & info,const std::string & compileMode) const130 void AOTHandler::HandleInstallWithSingleHap(const InnerBundleInfo &info, const std::string &compileMode) const
131 {
132     std::optional<AOTArgs> aotArgs = BuildAOTArgs(info, info.GetCurrentModulePackage(), compileMode);
133     AOTInternal(aotArgs, info.GetVersionCode());
134 }
135 
HandleInstall(const std::unordered_map<std::string,InnerBundleInfo> & infos) const136 void AOTHandler::HandleInstall(const std::unordered_map<std::string, InnerBundleInfo> &infos) const
137 {
138     auto task = [this, infos]() {
139         APP_LOGD("HandleInstall begin");
140         if (infos.empty() || !(infos.cbegin()->second.GetIsNewVersion())) {
141             APP_LOGD("not stage model, no need to AOT");
142             return;
143         }
144         if (!IsSupportARM64()) {
145             APP_LOGD("current device doesn't support arm64, no need to AOT");
146             return;
147         }
148         std::string compileMode = system::GetParameter(COMPILE_INSTALL_PARAM_KEY, Constants::COMPILE_NONE);
149         APP_LOGD("%{public}s = %{public}s", COMPILE_INSTALL_PARAM_KEY, compileMode.c_str());
150         if (compileMode == Constants::COMPILE_NONE) {
151             APP_LOGD("%{public}s = none, no need to AOT", COMPILE_INSTALL_PARAM_KEY);
152             return;
153         }
154         std::for_each(infos.cbegin(), infos.cend(), [this, compileMode](const auto &item) {
155             HandleInstallWithSingleHap(item.second, compileMode);
156         });
157         APP_LOGD("HandleInstall end");
158     };
159     std::thread t(task);
160     t.detach();
161 }
162 
ClearArkCacheDir() const163 void AOTHandler::ClearArkCacheDir() const
164 {
165     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
166     if (!dataMgr) {
167         APP_LOGE("dataMgr is null");
168         return;
169     }
170     std::vector<std::string> bundleNames = dataMgr->GetAllBundleName();
171     std::for_each(bundleNames.cbegin(), bundleNames.cend(), [dataMgr](const auto &bundleName) {
172         std::string removeDir = Constants::ARK_CACHE_PATH + bundleName;
173         ErrCode ret = InstalldClient::GetInstance()->RemoveDir(removeDir);
174         APP_LOGD("removeDir %{public}s, ret : %{public}d", removeDir.c_str(), ret);
175     });
176 }
177 
ResetAOTFlags() const178 void AOTHandler::ResetAOTFlags() const
179 {
180     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
181     if (!dataMgr) {
182         APP_LOGE("dataMgr is null");
183         return;
184     }
185     dataMgr->ResetAOTFlags();
186 }
187 
HandleOTA() const188 void AOTHandler::HandleOTA() const
189 {
190     APP_LOGI("HandleOTA begin");
191     ClearArkCacheDir();
192     ResetAOTFlags();
193     APP_LOGI("HandleOTA end");
194 }
195 
HandleIdleWithSingleHap(const InnerBundleInfo & info,const std::string & moduleName,const std::string & compileMode) const196 void AOTHandler::HandleIdleWithSingleHap(
197     const InnerBundleInfo &info, const std::string &moduleName, const std::string &compileMode) const
198 {
199     APP_LOGD("HandleIdleWithSingleHap, moduleName : %{public}s", moduleName.c_str());
200     if (info.GetAOTCompileStatus(moduleName) == AOTCompileStatus::COMPILE_SUCCESS) {
201         APP_LOGD("AOT history success, no need to AOT");
202         return;
203     }
204     std::optional<AOTArgs> aotArgs = BuildAOTArgs(info, moduleName, compileMode);
205     AOTInternal(aotArgs, info.GetVersionCode());
206 }
207 
CheckDeviceState() const208 bool AOTHandler::CheckDeviceState() const
209 {
210 #ifdef BUNDLE_FRAMEWORK_POWER_MGR_ENABLE
211     DisplayPowerMgr::DisplayState displayState =
212         DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().GetDisplayState();
213     if (displayState != DisplayPowerMgr::DisplayState::DISPLAY_OFF) {
214         APP_LOGI("displayState is not DISPLAY_OFF");
215         return false;
216     }
217     PowerMgr::BatteryChargeState batteryChargeState =
218         OHOS::PowerMgr::BatterySrvClient::GetInstance().GetChargingStatus();
219     if (batteryChargeState == PowerMgr::BatteryChargeState::CHARGE_STATE_ENABLE
220         || batteryChargeState == PowerMgr::BatteryChargeState::CHARGE_STATE_FULL) {
221         APP_LOGI("device is in charging state");
222         return true;
223     }
224     APP_LOGI("device is not in charging state");
225     return false;
226 #else
227     APP_LOGI("device not support power system");
228     return false;
229 #endif
230 }
231 
HandleIdle() const232 void AOTHandler::HandleIdle() const
233 {
234     APP_LOGI("HandleIdle begin");
235     if (!IsSupportARM64()) {
236         APP_LOGI("current device doesn't support arm64, no need to AOT");
237         return;
238     }
239     std::string compileMode = system::GetParameter(COMPILE_IDLE_PARA_KEY, Constants::COMPILE_PARTIAL);
240     APP_LOGI("%{public}s = %{public}s", COMPILE_IDLE_PARA_KEY, compileMode.c_str());
241     if (compileMode == Constants::COMPILE_NONE) {
242         APP_LOGI("%{public}s = none, no need to AOT", COMPILE_IDLE_PARA_KEY);
243         return;
244     }
245     if (!CheckDeviceState()) {
246         APP_LOGI("device state is not suitable");
247         return;
248     }
249     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
250     if (!dataMgr) {
251         APP_LOGE("dataMgr is null");
252         return;
253     }
254     std::vector<std::string> bundleNames = dataMgr->GetAllBundleName();
255     std::for_each(bundleNames.cbegin(), bundleNames.cend(), [this, dataMgr, &compileMode](const auto &bundleName) {
256         APP_LOGD("HandleIdle bundleName : %{public}s", bundleName.c_str());
257         InnerBundleInfo info;
258         if (!dataMgr->QueryInnerBundleInfo(bundleName, info)) {
259             APP_LOGE("QueryInnerBundleInfo failed");
260             return;
261         }
262         if (!info.GetIsNewVersion()) {
263             APP_LOGD("not stage model, no need to AOT");
264             return;
265         }
266         std::vector<std::string> moduleNames;
267         info.GetModuleNames(moduleNames);
268         std::for_each(moduleNames.cbegin(), moduleNames.cend(), [this, &info, &compileMode](const auto &moduleName) {
269             HandleIdleWithSingleHap(info, moduleName, compileMode);
270         });
271     });
272     APP_LOGI("HandleIdle end");
273 }
274 }  // namespace AppExecFwk
275 }  // namespace OHOS
276