• 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 "display_power_mgr_client.h"
32 #endif
33 
34 namespace OHOS {
35 namespace AppExecFwk {
36 namespace {
37 // ark compile option parameter key
38 constexpr const char* COMPILE_INSTALL_PARAM_KEY = "persist.bm.install.arkopt";
39 constexpr const char* COMPILE_IDLE_PARA_KEY = "persist.bm.idle.arkopt";
40 const std::string DEBUG_APP_IDENTIFIER = "DEBUG_LIB_ID";
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()->IsExistApFile(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     // handle internal hsp
105     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
106     if (!dataMgr) {
107         APP_LOGE("dataMgr is null");
108         return std::nullopt;
109     }
110     InnerBundleInfo installedInfo;
111     if (!dataMgr->QueryInnerBundleInfo(info.GetBundleName(), installedInfo)) {
112         APP_LOGE("QueryInnerBundleInfo failed");
113         return std::nullopt;
114     }
115     installedInfo.GetInternalDependentHspInfo(moduleName, aotArgs.hspVector);
116 
117     InnerBundleUserInfo newInnerBundleUserInfo;
118     if (!installedInfo.GetInnerBundleUserInfo(Constants::ALL_USERID, newInnerBundleUserInfo)) {
119         APP_LOGE("bundle(%{public}s) get user (%{public}d) failed.",
120             installedInfo.GetBundleName().c_str(), Constants::ALL_USERID);
121         return std::nullopt;
122     }
123     aotArgs.bundleUid = static_cast<uint32_t>(newInnerBundleUserInfo.uid);
124     aotArgs.isEncryptedBundle = installedInfo.IsEncryptedMoudle(moduleName) ? 1 : 0;
125     aotArgs.appIdentifier = (info.GetAppProvisionType() == Constants::APP_PROVISION_TYPE_DEBUG) ?
126         DEBUG_APP_IDENTIFIER : info.GetAppIdentifier();
127     APP_LOGD("args : %{public}s", aotArgs.ToString().c_str());
128     return aotArgs;
129 }
130 
AOTInternal(std::optional<AOTArgs> aotArgs,uint32_t versionCode) const131 void AOTHandler::AOTInternal(std::optional<AOTArgs> aotArgs, uint32_t versionCode) const
132 {
133     if (!aotArgs) {
134         APP_LOGI("aotArgs empty");
135         return;
136     }
137     ErrCode ret = ERR_OK;
138     {
139         std::lock_guard<std::mutex> lock(executeMutex_);
140         ret = InstalldClient::GetInstance()->ExecuteAOT(*aotArgs);
141     }
142     APP_LOGI("ExecuteAOT ret : %{public}d", ret);
143 
144     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
145     if (!dataMgr) {
146         APP_LOGE("dataMgr is null");
147         return;
148     }
149     AOTCompileStatus status = ret == ERR_OK ? AOTCompileStatus::COMPILE_SUCCESS : AOTCompileStatus::COMPILE_FAILED;
150     dataMgr->SetAOTCompileStatus(aotArgs->bundleName, aotArgs->moduleName, status, versionCode);
151 }
152 
HandleInstallWithSingleHap(const InnerBundleInfo & info,const std::string & compileMode) const153 void AOTHandler::HandleInstallWithSingleHap(const InnerBundleInfo &info, const std::string &compileMode) const
154 {
155     std::optional<AOTArgs> aotArgs = BuildAOTArgs(info, info.GetCurrentModulePackage(), compileMode);
156     AOTInternal(aotArgs, info.GetVersionCode());
157 }
158 
HandleInstall(const std::unordered_map<std::string,InnerBundleInfo> & infos) const159 void AOTHandler::HandleInstall(const std::unordered_map<std::string, InnerBundleInfo> &infos) const
160 {
161     auto task = [this, infos]() {
162         APP_LOGD("HandleInstall begin");
163         if (infos.empty() || !(infos.cbegin()->second.GetIsNewVersion())) {
164             APP_LOGD("not stage model, no need to AOT");
165             return;
166         }
167         if (!IsSupportARM64()) {
168             APP_LOGD("current device doesn't support arm64, no need to AOT");
169             return;
170         }
171         std::string compileMode = system::GetParameter(COMPILE_INSTALL_PARAM_KEY, Constants::COMPILE_NONE);
172         APP_LOGD("%{public}s = %{public}s", COMPILE_INSTALL_PARAM_KEY, compileMode.c_str());
173         if (compileMode == Constants::COMPILE_NONE) {
174             APP_LOGD("%{public}s = none, no need to AOT", COMPILE_INSTALL_PARAM_KEY);
175             return;
176         }
177         std::for_each(infos.cbegin(), infos.cend(), [this, compileMode](const auto &item) {
178             HandleInstallWithSingleHap(item.second, compileMode);
179         });
180         APP_LOGD("HandleInstall end");
181     };
182     std::thread t(task);
183     t.detach();
184 }
185 
ClearArkCacheDir() const186 void AOTHandler::ClearArkCacheDir() const
187 {
188     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
189     if (!dataMgr) {
190         APP_LOGE("dataMgr is null");
191         return;
192     }
193     std::vector<std::string> bundleNames = dataMgr->GetAllBundleName();
194     std::for_each(bundleNames.cbegin(), bundleNames.cend(), [dataMgr](const auto &bundleName) {
195         std::string removeDir = Constants::ARK_CACHE_PATH + bundleName;
196         ErrCode ret = InstalldClient::GetInstance()->RemoveDir(removeDir);
197         APP_LOGD("removeDir %{public}s, ret : %{public}d", removeDir.c_str(), ret);
198     });
199 }
200 
HandleResetAOT(const std::string & bundleName,bool isAllBundle) const201 void AOTHandler::HandleResetAOT(const std::string &bundleName, bool isAllBundle) const
202 {
203     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
204     if (!dataMgr) {
205         APP_LOGE("dataMgr is null");
206         return;
207     }
208     std::vector<std::string> bundleNames;
209     if (isAllBundle) {
210         bundleNames = dataMgr->GetAllBundleName();
211     } else {
212         bundleNames = {bundleName};
213     }
214     std::for_each(bundleNames.cbegin(), bundleNames.cend(), [dataMgr](const auto &bundleToReset) {
215         std::string removeDir = Constants::ARK_CACHE_PATH + bundleToReset;
216         ErrCode ret = InstalldClient::GetInstance()->RemoveDir(removeDir);
217         APP_LOGD("removeDir %{public}s, ret : %{public}d", removeDir.c_str(), ret);
218         dataMgr->ResetAOTFlagsCommand(bundleToReset);
219     });
220 }
221 
ResetAOTFlags() const222 void AOTHandler::ResetAOTFlags() const
223 {
224     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
225     if (!dataMgr) {
226         APP_LOGE("dataMgr is null");
227         return;
228     }
229     dataMgr->ResetAOTFlags();
230 }
231 
HandleOTA() const232 void AOTHandler::HandleOTA() const
233 {
234     APP_LOGI("HandleOTA begin");
235     ClearArkCacheDir();
236     ResetAOTFlags();
237     APP_LOGI("HandleOTA end");
238 }
239 
HandleIdleWithSingleHap(const InnerBundleInfo & info,const std::string & moduleName,const std::string & compileMode) const240 void AOTHandler::HandleIdleWithSingleHap(
241     const InnerBundleInfo &info, const std::string &moduleName, const std::string &compileMode) const
242 {
243     APP_LOGD("HandleIdleWithSingleHap, moduleName : %{public}s", moduleName.c_str());
244     if (info.GetAOTCompileStatus(moduleName) == AOTCompileStatus::COMPILE_SUCCESS) {
245         APP_LOGD("AOT history success, no need to AOT");
246         return;
247     }
248     std::optional<AOTArgs> aotArgs = BuildAOTArgs(info, moduleName, compileMode);
249     AOTInternal(aotArgs, info.GetVersionCode());
250 }
251 
HandleCompileWithSingleHap(const InnerBundleInfo & info,const std::string & moduleName,const std::string & compileMode) const252 void AOTHandler::HandleCompileWithSingleHap(
253     const InnerBundleInfo &info, const std::string &moduleName, const std::string &compileMode) const
254 {
255     APP_LOGD("HandleCompileWithSingleHap, moduleName : %{public}s", moduleName.c_str());
256     std::optional<AOTArgs> aotArgs = BuildAOTArgs(info, moduleName, compileMode);
257     AOTInternal(aotArgs, info.GetVersionCode());
258 }
259 
CheckDeviceState() const260 bool AOTHandler::CheckDeviceState() const
261 {
262 #ifdef BUNDLE_FRAMEWORK_POWER_MGR_ENABLE
263     DisplayPowerMgr::DisplayState displayState =
264         DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().GetDisplayState();
265     if (displayState != DisplayPowerMgr::DisplayState::DISPLAY_OFF) {
266         APP_LOGI("displayState is not DISPLAY_OFF");
267         return false;
268     }
269     return true;
270 #else
271     APP_LOGI("device not support power system");
272     return false;
273 #endif
274 }
275 
HandleIdle() const276 void AOTHandler::HandleIdle() const
277 {
278     APP_LOGI("HandleIdle begin");
279     std::unique_lock<std::mutex> lock(idleMutex_, std::defer_lock);
280     if (!lock.try_lock()) {
281         APP_LOGI("idle task is running, skip");
282         return;
283     }
284     if (!IsSupportARM64()) {
285         APP_LOGI("current device doesn't support arm64, no need to AOT");
286         return;
287     }
288     std::string compileMode = system::GetParameter(COMPILE_IDLE_PARA_KEY, Constants::COMPILE_PARTIAL);
289     APP_LOGI("%{public}s = %{public}s", COMPILE_IDLE_PARA_KEY, compileMode.c_str());
290     if (compileMode == Constants::COMPILE_NONE) {
291         APP_LOGI("%{public}s = none, no need to AOT", COMPILE_IDLE_PARA_KEY);
292         return;
293     }
294     if (!CheckDeviceState()) {
295         APP_LOGI("device state is not suitable");
296         return;
297     }
298     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
299     if (!dataMgr) {
300         APP_LOGE("dataMgr is null");
301         return;
302     }
303     std::vector<std::string> bundleNames = dataMgr->GetAllBundleName();
304     std::for_each(bundleNames.cbegin(), bundleNames.cend(), [this, dataMgr, &compileMode](const auto &bundleName) {
305         APP_LOGD("HandleIdle bundleName : %{public}s", bundleName.c_str());
306         InnerBundleInfo info;
307         if (!dataMgr->QueryInnerBundleInfo(bundleName, info)) {
308             APP_LOGE("QueryInnerBundleInfo failed");
309             return;
310         }
311         if (!info.GetIsNewVersion()) {
312             APP_LOGD("not stage model, no need to AOT");
313             return;
314         }
315         std::vector<std::string> moduleNames;
316         info.GetModuleNames(moduleNames);
317         std::for_each(moduleNames.cbegin(), moduleNames.cend(), [this, &info, &compileMode](const auto &moduleName) {
318             HandleIdleWithSingleHap(info, moduleName, compileMode);
319         });
320     });
321     APP_LOGI("HandleIdle end");
322 }
323 
HandleCompile(const std::string & bundleName,const std::string & compileMode,bool isAllBundle) const324 void AOTHandler::HandleCompile(const std::string &bundleName, const std::string &compileMode, bool isAllBundle) const
325 {
326     APP_LOGI("HandleCompile begin");
327     std::unique_lock<std::mutex> lock(compileMutex_, std::defer_lock);
328     if (!lock.try_lock()) {
329         APP_LOGI("compile task is running, skip %{public}s", bundleName.c_str());
330         return;
331     }
332     if (!IsSupportARM64()) {
333         APP_LOGI("current device doesn't support arm64, no need to AOT");
334         return;
335     }
336     if (compileMode == Constants::COMPILE_NONE) {
337         APP_LOGI("%{public}s = none, no need to AOT", COMPILE_IDLE_PARA_KEY);
338         return;
339     }
340     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
341     if (!dataMgr) {
342         APP_LOGE("dataMgr is null");
343         return;
344     }
345     std::vector<std::string> bundleNames;
346     if (isAllBundle) {
347         bundleNames = dataMgr->GetAllBundleName();
348     } else {
349         bundleNames = {bundleName};
350     }
351     std::for_each(bundleNames.cbegin(), bundleNames.cend(), [this, dataMgr, &compileMode](const auto &bundleToCompile) {
352         APP_LOGD("HandleCompile bundleToCompile : %{public}s", bundleToCompile.c_str());
353         InnerBundleInfo info;
354         if (!dataMgr->QueryInnerBundleInfo(bundleToCompile, info)) {
355             APP_LOGE("QueryInnerBundleInfo failed. bundleToCompile: %{public}s", bundleToCompile.c_str());
356             return;
357         }
358         if (!info.GetIsNewVersion()) {
359             APP_LOGD("not stage model, no need to AOT");
360             return;
361         }
362         std::vector<std::string> moduleNames;
363         info.GetModuleNames(moduleNames);
364         std::for_each(moduleNames.cbegin(), moduleNames.cend(),
365             [this, &info, &compileMode](const auto &moduleName) {
366             HandleCompileWithSingleHap(info, moduleName, compileMode);
367         });
368     });
369     APP_LOGI("HandleCompile end");
370 }
371 }  // namespace AppExecFwk
372 }  // namespace OHOS
373