1 /*
2  * Copyright (c) 2023-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 "aot/aot_handler.h"
17 
18 #include <dlfcn.h>
19 #include <sys/stat.h>
20 
21 #include "account_helper.h"
22 #ifdef CODE_SIGNATURE_ENABLE
23 #include "aot/aot_sign_data_cache_mgr.h"
24 #endif
25 #include "scope_guard.h"
26 #include "installd_client.h"
27 #include "parameter.h"
28 #include "parameters.h"
29 #ifdef BUNDLE_FRAMEWORK_POWER_MGR_ENABLE
30 #include "display_power_mgr_client.h"
31 #endif
32 
33 namespace OHOS {
34 namespace AppExecFwk {
35 namespace {
36 using UserStatusFunc = ErrCode (*)(int32_t, std::vector<std::string>&, std::vector<std::string>&);
37 using AOTVersionFunc = ErrCode (*)(std::string&);
38 // ark compile option parameter key
39 constexpr const char* INSTALL_COMPILE_MODE = "persist.bm.install.arkopt";
40 constexpr const char* IDLE_COMPILE_MODE = "persist.bm.idle.arkopt";
41 constexpr const char* OTA_COMPILE_MODE = "persist.bm.ota.arkopt";
42 
43 constexpr const char* COMPILE_OPTCODE_RANGE_KEY = "ark.optcode.range";
44 const std::string DEBUG_APP_IDENTIFIER = "DEBUG_LIB_ID";
45 
46 constexpr const char* UPDATE_TYPE = "persist.dupdate_engine.update_type";
47 const std::string UPDATE_TYPE_MANUAL = "manual";
48 const std::string UPDATE_TYPE_NIGHT = "night";
49 
50 constexpr const char* OTA_COMPILE_SWITCH = "const.bms.optimizing_apps.switch";
51 constexpr const char* OTA_COMPILE_SWITCH_DEFAULT = "off";
52 const std::string OTA_COMPILE_SWITCH_ON = "on";
53 
54 constexpr const char* OTA_COMPILE_TIME = "persist.bms.optimizing_apps.timing";
55 constexpr int32_t OTA_COMPILE_TIME_DEFAULT = 4 * 60; // 4min
56 constexpr int32_t GAP_SECONDS = 10;
57 
58 constexpr const char* OTA_COMPILE_COUNT_MANUAL = "persist.bms.optimizing_apps.counts.manual";
59 constexpr int32_t OTA_COMPILE_COUNT_MANUAL_DEFAULT = 20;
60 constexpr const char* OTA_COMPILE_COUNT_NIGHT = "persist.bms.optimizing_apps.counts.night";
61 constexpr int32_t OTA_COMPILE_COUNT_NIGHT_DEFAULT = 30;
62 
63 constexpr const char* OTA_COMPILE_STATUS = "bms.optimizing_apps.status";
64 constexpr const char* OTA_COMPILE_STATUS_BEGIN = "0";
65 constexpr const char* OTA_COMPILE_STATUS_END = "1";
66 
67 const std::string QUEUE_NAME = "OTAQueue";
68 const std::string TASK_NAME = "OTACompileTimer";
69 
70 constexpr uint32_t CONVERSION_FACTOR = 1000; // s to ms
71 
72 const std::string FAILURE_REASON_TIME_OUT = "timeout";
73 const std::string FAILURE_REASON_BUNDLE_NOT_EXIST = "bundle not exist";
74 const std::string FAILURE_REASON_NOT_STAGE_MODEL = "not stage model";
75 const std::string FAILURE_REASON_COMPILE_FAILED = "compile failed";
76 
77 constexpr const char* PGO_MERGED_AP_PREFIX = "merged_";
78 constexpr const char* PGO_RT_AP_PREFIX = "rt_";
79 constexpr const char* COPY_AP_DEST_PATH  = "/data/local/pgo/";
80 constexpr const char* COMPILE_NONE = "none";
81 
82 constexpr const char* USER_STATUS_SO_NAME = "libuser_status_client.z.so";
83 constexpr const char* USER_STATUS_FUNC_NAME = "GetUserPreferenceApp";
84 constexpr const char* ARK_SO_NAME = "libark_jsruntime.so";
85 constexpr const char* AOT_VERSION_FUNC_NAME = "GetAOTVersion";
86 constexpr const char* BM_AOT_TEST = "bm.aot.test";
87 const std::string AOT_VERSION = "aot_version";
88 
89 }
90 
AOTHandler()91 AOTHandler::AOTHandler()
92 {
93     serialQueue_ = std::make_shared<SerialQueue>(QUEUE_NAME);
94 }
95 
GetInstance()96 AOTHandler& AOTHandler::GetInstance()
97 {
98     static AOTHandler handler;
99     return handler;
100 }
101 
IsSupportARM64() const102 bool AOTHandler::IsSupportARM64() const
103 {
104     std::string abis = GetAbiList();
105     APP_LOGD("abi list : %{public}s", abis.c_str());
106     std::vector<std::string> abiList;
107     SplitStr(abis, ServiceConstants::ABI_SEPARATOR, abiList, false, false);
108     if (abiList.empty()) {
109         APP_LOGD("abiList empty");
110         return false;
111     }
112     return std::find(abiList.begin(), abiList.end(), ServiceConstants::ARM64_V8A) != abiList.end();
113 }
114 
GetArkProfilePath(const std::string & bundleName,const std::string & moduleName) const115 std::string AOTHandler::GetArkProfilePath(const std::string &bundleName, const std::string &moduleName) const
116 {
117     APP_LOGD("GetArkProfilePath begin");
118     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
119     if (!dataMgr) {
120         APP_LOGE("dataMgr is null");
121         return Constants::EMPTY_STRING;
122     }
123     int32_t userId = AccountHelper::GetCurrentActiveUserId();
124     if (userId <= 0) {
125         userId = Constants::START_USERID;
126     }
127     std::string path;
128     path.append(ServiceConstants::ARK_PROFILE_PATH).append(std::to_string(userId))
129         .append(ServiceConstants::PATH_SEPARATOR).append(bundleName)
130         .append(ServiceConstants::PATH_SEPARATOR).append(moduleName).append(ServiceConstants::AP_SUFFIX);
131     APP_LOGD("path : %{public}s", path.c_str());
132     bool isExistFile = false;
133     (void)InstalldClient::GetInstance()->IsExistApFile(path, isExistFile);
134     if (isExistFile) {
135         return path;
136     }
137     APP_LOGD("GetArkProfilePath failed");
138     return Constants::EMPTY_STRING;
139 }
140 
BuildAOTArgs(const InnerBundleInfo & info,const std::string & moduleName,const std::string & compileMode,bool isEnableBaselinePgo) const141 std::optional<AOTArgs> AOTHandler::BuildAOTArgs(const InnerBundleInfo &info, const std::string &moduleName,
142     const std::string &compileMode, bool isEnableBaselinePgo) const
143 {
144     AOTArgs aotArgs;
145     aotArgs.bundleName = info.GetBundleName();
146     aotArgs.moduleName = moduleName;
147     if (compileMode == ServiceConstants::COMPILE_PARTIAL) {
148         aotArgs.arkProfilePath = GetArkProfilePath(aotArgs.bundleName, aotArgs.moduleName);
149         if (aotArgs.arkProfilePath.empty()) {
150             APP_LOGD("compile mode is partial, but ap not exist, no need to AOT");
151             return std::nullopt;
152         }
153     }
154     aotArgs.compileMode = compileMode;
155     aotArgs.hapPath = info.GetModuleHapPath(aotArgs.moduleName);
156     aotArgs.coreLibPath = Constants::EMPTY_STRING;
157     aotArgs.outputPath = ServiceConstants::ARK_CACHE_PATH + aotArgs.bundleName + ServiceConstants::PATH_SEPARATOR
158         + ServiceConstants::ARM64;
159     // handle internal hsp
160     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
161     if (!dataMgr) {
162         APP_LOGE("dataMgr is null");
163         return std::nullopt;
164     }
165     InnerBundleInfo installedInfo;
166     if (!dataMgr->QueryInnerBundleInfo(info.GetBundleName(), installedInfo)) {
167         APP_LOGE("QueryInnerBundleInfo failed");
168         return std::nullopt;
169     }
170     installedInfo.GetInternalDependentHspInfo(moduleName, aotArgs.hspVector);
171 
172     InnerBundleUserInfo newInnerBundleUserInfo;
173     int32_t curActiveUserId = AccountHelper::GetCurrentActiveUserId();
174     int32_t activeUserId = curActiveUserId <= 0 ? Constants::START_USERID : curActiveUserId;
175     if (!installedInfo.GetInnerBundleUserInfo(activeUserId, newInnerBundleUserInfo)) {
176         APP_LOGE("bundle(%{public}s) get user (%{public}d) failed",
177             installedInfo.GetBundleName().c_str(), activeUserId);
178         return std::nullopt;
179     }
180     aotArgs.bundleUid = newInnerBundleUserInfo.uid;
181     aotArgs.bundleGid = installedInfo.GetGid(activeUserId);
182     aotArgs.isEncryptedBundle = installedInfo.IsEncryptedMoudle(moduleName) ? 1 : 0;
183     aotArgs.appIdentifier = (info.GetAppProvisionType() == Constants::APP_PROVISION_TYPE_DEBUG) ?
184         DEBUG_APP_IDENTIFIER : info.GetAppIdentifier();
185     aotArgs.anFileName = aotArgs.outputPath + ServiceConstants::PATH_SEPARATOR + aotArgs.moduleName
186         + ServiceConstants::AN_SUFFIX;
187 
188     std::string optBCRange = system::GetParameter(COMPILE_OPTCODE_RANGE_KEY, "");
189     aotArgs.optBCRangeList = optBCRange;
190 
191     bool deviceIsScreenOff = CheckDeviceState();
192     aotArgs.isScreenOff = static_cast<uint32_t>(deviceIsScreenOff);
193 
194     aotArgs.isEnableBaselinePgo = static_cast<uint32_t>(isEnableBaselinePgo);
195     APP_LOGD("args : %{public}s", aotArgs.ToString().c_str());
196     return aotArgs;
197 }
198 
AOTInternal(const std::optional<AOTArgs> & aotArgs,uint32_t versionCode) const199 ErrCode AOTHandler::AOTInternal(const std::optional<AOTArgs> &aotArgs, uint32_t versionCode) const
200 {
201     if (!aotArgs) {
202         APP_LOGD("aotArgs empty");
203         return ERR_APPEXECFWK_AOT_ARGS_EMPTY;
204     }
205     ErrCode ret = ERR_OK;
206     std::vector<uint8_t> pendSignData;
207     {
208         std::lock_guard<std::mutex> lock(executeMutex_);
209         ret = InstalldClient::GetInstance()->ExecuteAOT(*aotArgs, pendSignData);
210     }
211     APP_LOGI("ExecuteAOT ret : %{public}d", ret);
212 #ifdef CODE_SIGNATURE_ENABLE
213     AOTSignDataCacheMgr::GetInstance().AddPendSignData(*aotArgs, versionCode, pendSignData, ret);
214 #endif
215     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
216     if (!dataMgr) {
217         APP_LOGE("dataMgr is null");
218         return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
219     }
220     AOTCompileStatus status = ConvertToAOTCompileStatus(ret);
221     dataMgr->SetAOTCompileStatus(aotArgs->bundleName, aotArgs->moduleName, status, versionCode);
222     return ret;
223 }
224 
ConvertToAOTCompileStatus(const ErrCode ret) const225 AOTCompileStatus AOTHandler::ConvertToAOTCompileStatus(const ErrCode ret) const
226 {
227     switch (ret) {
228         case ERR_OK:
229             return AOTCompileStatus::COMPILE_SUCCESS;
230         case ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_CRASH:
231             return AOTCompileStatus::COMPILE_CRASH;
232         case ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_CANCELLED:
233             return AOTCompileStatus::COMPILE_CANCELLED;
234         default:
235             return AOTCompileStatus::COMPILE_FAILED;
236     }
237 }
238 
HandleInstallWithSingleHap(const InnerBundleInfo & info,const std::string & compileMode) const239 void AOTHandler::HandleInstallWithSingleHap(const InnerBundleInfo &info, const std::string &compileMode) const
240 {
241     std::optional<AOTArgs> aotArgs = BuildAOTArgs(info, info.GetCurrentModulePackage(), compileMode, true);
242     (void)AOTInternal(aotArgs, info.GetVersionCode());
243 }
244 
HandleInstall(const std::unordered_map<std::string,InnerBundleInfo> & infos) const245 void AOTHandler::HandleInstall(const std::unordered_map<std::string, InnerBundleInfo> &infos) const
246 {
247     auto task = [this, infos]() {
248         APP_LOGD("HandleInstall begin");
249         if (infos.empty() || !(infos.cbegin()->second.GetIsNewVersion())) {
250             APP_LOGD("not stage model, no need to AOT");
251             return;
252         }
253         if (!IsSupportARM64()) {
254             APP_LOGD("current device doesn't support arm64, no need to AOT");
255             return;
256         }
257         std::string compileMode = system::GetParameter(INSTALL_COMPILE_MODE, COMPILE_NONE);
258         APP_LOGD("%{public}s = %{public}s", INSTALL_COMPILE_MODE, compileMode.c_str());
259         if (compileMode == COMPILE_NONE) {
260             APP_LOGD("%{public}s = none, no need to AOT", INSTALL_COMPILE_MODE);
261             return;
262         }
263         std::for_each(infos.cbegin(), infos.cend(), [this, compileMode](const auto &item) {
264             HandleInstallWithSingleHap(item.second, compileMode);
265         });
266         APP_LOGD("HandleInstall end");
267     };
268     std::thread t(task);
269     t.detach();
270 }
271 
ClearArkCacheDir() const272 void AOTHandler::ClearArkCacheDir() const
273 {
274     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
275     if (!dataMgr) {
276         APP_LOGE("dataMgr is null");
277         return;
278     }
279     std::vector<std::string> bundleNames = dataMgr->GetAllBundleName();
280     std::for_each(bundleNames.cbegin(), bundleNames.cend(), [dataMgr](const auto &bundleName) {
281         std::string removeDir = ServiceConstants::ARK_CACHE_PATH + bundleName;
282         ErrCode ret = InstalldClient::GetInstance()->RemoveDir(removeDir);
283         APP_LOGD("removeDir %{public}s, ret : %{public}d", removeDir.c_str(), ret);
284     });
285 }
286 
ClearArkAp(const std::string & oldAOTVersion,const std::string & curAOTVersion) const287 void AOTHandler::ClearArkAp(const std::string &oldAOTVersion, const std::string &curAOTVersion) const
288 {
289     APP_LOGI("oldAOTVersion(%{public}s), curAOTVersion(%{public}s)",
290         oldAOTVersion.c_str(), curAOTVersion.c_str());
291     if (!oldAOTVersion.empty() && curAOTVersion == oldAOTVersion) {
292         APP_LOGI("Version not changed");
293         return;
294     }
295 
296     APP_LOGI("ClearArkAp start");
297     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
298     if (dataMgr == nullptr) {
299         APP_LOGE("is nullptr");
300         return;
301     }
302     std::set<int32_t> userIds = dataMgr->GetAllUser();
303     for (const auto &userId : userIds) {
304         std::vector<BundleInfo> bundleInfos;
305         if (dataMgr->GetBundleInfosV9(static_cast<int32_t>(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE),
306             bundleInfos, userId) != ERR_OK) {
307             APP_LOGE("GetAllBundleInfos failed");
308             continue;
309         }
310         for (const auto &bundleInfo : bundleInfos) {
311             DeleteArkAp(bundleInfo, userId);
312         }
313     }
314     APP_LOGI("ClearArkAp end");
315 }
316 
DeleteArkAp(const BundleInfo & bundleInfo,const int32_t userId) const317 void AOTHandler::DeleteArkAp(const BundleInfo &bundleInfo, const int32_t userId) const
318 {
319     std::string arkProfilePath;
320     arkProfilePath.append(ServiceConstants::ARK_PROFILE_PATH).append(std::to_string(userId))
321         .append(ServiceConstants::PATH_SEPARATOR).append(bundleInfo.name).append(ServiceConstants::PATH_SEPARATOR);
322     for (const auto &moduleName : bundleInfo.moduleNames) {
323         std::string runtimeAp = arkProfilePath;
324         std::string mergedAp = arkProfilePath;
325         runtimeAp.append(PGO_RT_AP_PREFIX).append(moduleName)
326             .append(ServiceConstants::PGO_FILE_SUFFIX);
327         (void)InstalldClient::GetInstance()->RemoveDir(runtimeAp);
328         mergedAp.append(PGO_MERGED_AP_PREFIX).append(moduleName).append(ServiceConstants::PGO_FILE_SUFFIX);
329         (void)InstalldClient::GetInstance()->RemoveDir(mergedAp);
330     }
331 }
332 
HandleResetAOT(const std::string & bundleName,bool isAllBundle) const333 void AOTHandler::HandleResetAOT(const std::string &bundleName, bool isAllBundle) const
334 {
335     if (isAllBundle && system::GetParameter(BM_AOT_TEST, "").empty()) {
336         APP_LOGD("isAllBundle true, param bm.aot.test empty, so ignore");
337         return;
338     }
339     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
340     if (!dataMgr) {
341         APP_LOGE("dataMgr is null");
342         return;
343     }
344     std::vector<std::string> bundleNames;
345     if (isAllBundle) {
346         bundleNames = dataMgr->GetAllBundleName();
347     } else {
348         bundleNames = {bundleName};
349     }
350     std::for_each(bundleNames.cbegin(), bundleNames.cend(), [dataMgr](const auto &bundleToReset) {
351         std::string removeDir = ServiceConstants::ARK_CACHE_PATH + bundleToReset;
352         ErrCode ret = InstalldClient::GetInstance()->RemoveDir(removeDir);
353         APP_LOGD("removeDir %{public}s, ret : %{public}d", removeDir.c_str(), ret);
354         dataMgr->ResetAOTFlagsCommand(bundleToReset);
355     });
356 }
357 
MkApDestDirIfNotExist() const358 ErrCode AOTHandler::MkApDestDirIfNotExist() const
359 {
360     ErrCode errCode;
361     bool isDirExist = false;
362     errCode = InstalldClient::GetInstance()->IsExistDir(COPY_AP_DEST_PATH, isDirExist);
363     if (errCode != ERR_OK) {
364         APP_LOGE("check if dir exist failed, err %{public}d", errCode);
365     }
366     if (isDirExist) {
367         APP_LOGI("Copy ap path is exist");
368         return ERR_OK;
369     }
370     mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP;
371     errCode = InstalldClient::GetInstance()->Mkdir(
372         COPY_AP_DEST_PATH, mode, Constants::FOUNDATION_UID, ServiceConstants::SHELL_UID);
373     if (errCode != ERR_OK) {
374         APP_LOGE("fail create dir err %{public}d", errCode);
375         return errCode;
376     }
377     APP_LOGI("MkApDestDir path success");
378     return ERR_OK;
379 }
380 
HandleCopyAp(const std::string & bundleName,bool isAllBundle,std::vector<std::string> & results) const381 ErrCode AOTHandler::HandleCopyAp(const std::string &bundleName, bool isAllBundle,
382     std::vector<std::string> &results) const
383 {
384     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
385     if (!dataMgr) {
386         APP_LOGE("dataMgr is null");
387         return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
388     }
389     std::vector<std::string> bundleNames;
390     if (isAllBundle) {
391         bundleNames = dataMgr->GetAllBundleName();
392     } else {
393         bundleNames = {bundleName};
394     }
395     ErrCode errCode = MkApDestDirIfNotExist();
396     if (errCode != ERR_OK) {
397         return errCode;
398     }
399     int32_t userId = AccountHelper::GetCurrentActiveUserId();
400     if (userId <= 0) {
401         userId = Constants::START_USERID;
402     }
403     for (const auto &bundleName : bundleNames) {
404         BundleInfo bundleInfo;
405         if (!dataMgr->GetBundleInfo(bundleName, BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, userId)) {
406             std::string errInfo = bundleName + " GetBundleInfo failed";
407             APP_LOGW("%{public}s", errInfo.c_str());
408             results.emplace_back(errInfo);
409             continue;
410         }
411         CopyApWithBundle(bundleName, bundleInfo, userId, results);
412     };
413     return ERR_OK;
414 }
415 
GetSouceAp(const std::string & mergedAp,const std::string & rtAp) const416 std::string AOTHandler::GetSouceAp(const std::string &mergedAp, const std::string &rtAp) const
417 {
418     ErrCode errCode;
419     bool isMergedApExist = false;
420     bool isRtApExist = false;
421     errCode = InstalldClient::GetInstance()->IsExistFile(mergedAp, isMergedApExist);
422     if (errCode != ERR_OK) {
423         APP_LOGE("CopyAp mergedAp %{public}s failed due to call IsExistFile failed %{public}d",
424             mergedAp.c_str(), errCode);
425         return Constants::EMPTY_STRING;
426     }
427     if (isMergedApExist) {
428         return mergedAp;
429     }
430     errCode = InstalldClient::GetInstance()->IsExistFile(rtAp, isRtApExist);
431     if (errCode != ERR_OK) {
432         APP_LOGE("CopyAp rtAp %{public}s failed due to call IsExistFile failed %{public}d",
433             rtAp.c_str(), errCode);
434         return Constants::EMPTY_STRING;
435     }
436     if (isRtApExist) {
437         return rtAp;
438     }
439     APP_LOGE("Source ap is not exist");
440     return Constants::EMPTY_STRING;
441 }
442 
CopyApWithBundle(const std::string & bundleName,const BundleInfo & bundleInfo,const int32_t userId,std::vector<std::string> & results) const443 void AOTHandler::CopyApWithBundle(const std::string &bundleName, const BundleInfo &bundleInfo,
444     const int32_t userId, std::vector<std::string> &results) const
445 {
446     std::string arkProfilePath;
447     arkProfilePath.append(ServiceConstants::ARK_PROFILE_PATH).append(std::to_string(userId))
448         .append(ServiceConstants::PATH_SEPARATOR).append(bundleName).append(ServiceConstants::PATH_SEPARATOR);
449     ErrCode errCode;
450     for (const auto &moduleName : bundleInfo.moduleNames) {
451         std::string mergedAp = arkProfilePath + PGO_MERGED_AP_PREFIX + moduleName + ServiceConstants::AP_SUFFIX;
452         std::string rtAp = arkProfilePath + PGO_RT_AP_PREFIX + moduleName + ServiceConstants::AP_SUFFIX;
453         std::string sourceAp = GetSouceAp(mergedAp, rtAp);
454         std::string result;
455         if (sourceAp.empty()) {
456             result.append(bundleName).append(" ").append(moduleName).append(" get source ap failed");
457             results.emplace_back(result);
458             continue;
459         }
460         if (sourceAp.find(ServiceConstants::RELATIVE_PATH) != std::string::npos) {
461             return;
462         }
463         std::string destAp = COPY_AP_DEST_PATH  + bundleName + "_" + moduleName + ServiceConstants::AP_SUFFIX;
464         result.append(sourceAp);
465         errCode = InstalldClient::GetInstance()->CopyFile(sourceAp, destAp);
466         if (errCode != ERR_OK) {
467             APP_LOGE("Copy ap dir %{public}s failed err %{public}d", sourceAp.c_str(), errCode);
468             result.append(" copy ap failed");
469             continue;
470         }
471         result.append(" copy ap success");
472         results.emplace_back(result);
473     }
474 }
475 
ResetAOTFlags() const476 void AOTHandler::ResetAOTFlags() const
477 {
478     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
479     if (!dataMgr) {
480         APP_LOGE("dataMgr is null");
481         return;
482     }
483     dataMgr->ResetAOTFlags();
484 }
485 
HandleOTA()486 void AOTHandler::HandleOTA()
487 {
488     APP_LOGI("HandleOTA begin");
489     ClearArkCacheDir();
490     std::string curAOTVersion = GetCurAOTVersion();
491     std::string oldAOTVersion;
492     (void)GetOldAOTVersion(oldAOTVersion);
493     ClearArkAp(oldAOTVersion, curAOTVersion);
494     SaveAOTVersion(curAOTVersion);
495     ResetAOTFlags();
496     HandleOTACompile();
497 }
498 
HandleOTACompile()499 void AOTHandler::HandleOTACompile()
500 {
501     if (!IsOTACompileSwitchOn()) {
502         APP_LOGI("OTACompileSwitch off, no need to compile");
503         return;
504     }
505     BeforeOTACompile();
506     OTACompile();
507 }
508 
IsOTACompileSwitchOn() const509 bool AOTHandler::IsOTACompileSwitchOn() const
510 {
511     std::string OTACompileSwitch = system::GetParameter(OTA_COMPILE_SWITCH, OTA_COMPILE_SWITCH_DEFAULT);
512     APP_LOGI("OTACompileSwitch %{public}s", OTACompileSwitch.c_str());
513     return OTACompileSwitch == OTA_COMPILE_SWITCH_ON;
514 }
515 
BeforeOTACompile()516 void AOTHandler::BeforeOTACompile()
517 {
518     OTACompileDeadline_ = false;
519     int32_t limitSeconds = system::GetIntParameter<int32_t>(OTA_COMPILE_TIME, OTA_COMPILE_TIME_DEFAULT);
520     APP_LOGI("OTA compile time limit seconds %{public}d", limitSeconds);
521     auto task = [this]() {
522         APP_LOGI("compile timer end");
523         OTACompileDeadline_ = true;
524         ErrCode ret = InstalldClient::GetInstance()->StopAOT();
525         APP_LOGI("StopAOT ret %{public}d", ret);
526     };
527     int32_t delayTimeSeconds = limitSeconds - GAP_SECONDS;
528     if (delayTimeSeconds < 0) {
529         delayTimeSeconds = 0;
530     }
531     serialQueue_->ScheduleDelayTask(TASK_NAME, delayTimeSeconds * CONVERSION_FACTOR, task);
532 }
533 
OTACompile() const534 void AOTHandler::OTACompile() const
535 {
536     auto OTACompileTask = [this]() {
537         OTACompileInternal();
538     };
539     std::thread(OTACompileTask).detach();
540 }
541 
OTACompileInternal() const542 void AOTHandler::OTACompileInternal() const
543 {
544     APP_LOGI("OTACompileInternal begin");
545     system::SetParameter(OTA_COMPILE_STATUS, OTA_COMPILE_STATUS_BEGIN);
546     ScopeGuard guard([this] {
547         APP_LOGI("set OTA compile status to end");
548         system::SetParameter(OTA_COMPILE_STATUS, OTA_COMPILE_STATUS_END);
549         serialQueue_->CancelDelayTask(TASK_NAME);
550     });
551 
552     if (!IsSupportARM64()) {
553         APP_LOGI("current device doesn't support arm64, no need to AOT");
554         return;
555     }
556 
557     std::string compileMode = system::GetParameter(OTA_COMPILE_MODE, COMPILE_NONE);
558     APP_LOGI("%{public}s = %{public}s", OTA_COMPILE_MODE, compileMode.c_str());
559     if (compileMode == COMPILE_NONE) {
560         APP_LOGI("%{public}s none, no need to AOT", OTA_COMPILE_MODE);
561         return;
562     }
563 
564     std::vector<std::string> bundleNames;
565     if (!GetOTACompileList(bundleNames)) {
566         APP_LOGE("get OTA compile list failed");
567         return;
568     }
569 
570     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
571     if (!dataMgr) {
572         APP_LOGE("dataMgr is null");
573         return;
574     }
575 
576     std::map<std::string, EventInfo> sysEventMap;
577     for (const std::string &bundleName : bundleNames) {
578         EventInfo eventInfo = HandleCompileWithBundle(bundleName, compileMode, dataMgr);
579         sysEventMap.emplace(bundleName, eventInfo);
580     }
581     ReportSysEvent(sysEventMap);
582     APP_LOGI("OTACompileInternal end");
583 }
584 
GetOTACompileList(std::vector<std::string> & bundleNames) const585 bool AOTHandler::GetOTACompileList(std::vector<std::string> &bundleNames) const
586 {
587     std::string updateType = system::GetParameter(UPDATE_TYPE, "");
588     APP_LOGI("updateType %{public}s", updateType.c_str());
589     int32_t size = 0;
590     if (updateType == UPDATE_TYPE_MANUAL) {
591         size = system::GetIntParameter<int32_t>(OTA_COMPILE_COUNT_MANUAL, OTA_COMPILE_COUNT_MANUAL_DEFAULT);
592     } else if (updateType == UPDATE_TYPE_NIGHT) {
593         size = system::GetIntParameter<int32_t>(OTA_COMPILE_COUNT_NIGHT, OTA_COMPILE_COUNT_NIGHT_DEFAULT);
594     } else {
595         APP_LOGE("invalid updateType");
596         return false;
597     }
598     return GetUserBehaviourAppList(bundleNames, size);
599 }
600 
GetUserBehaviourAppList(std::vector<std::string> & bundleNames,int32_t size) const601 bool AOTHandler::GetUserBehaviourAppList(std::vector<std::string> &bundleNames, int32_t size) const
602 {
603     APP_LOGI("GetUserBehaviourAppList begin, size %{public}d", size);
604     void* handle = dlopen(USER_STATUS_SO_NAME, RTLD_NOW);
605     if (handle == nullptr) {
606         APP_LOGE("user status dlopen failed : %{public}s", dlerror());
607         return false;
608     }
609     UserStatusFunc userStatusFunc = reinterpret_cast<UserStatusFunc>(dlsym(handle, USER_STATUS_FUNC_NAME));
610     if (userStatusFunc == nullptr) {
611         APP_LOGE("user status dlsym failed : %{public}s", dlerror());
612         dlclose(handle);
613         return false;
614     }
615     std::vector<std::string> interestedApps;
616     ErrCode ret = userStatusFunc(size, interestedApps, bundleNames);
617     APP_LOGI("GetUserPreferenceApp ret : %{public}d, bundleNames size : %{public}zu", ret, bundleNames.size());
618     dlclose(handle);
619     return ret == ERR_OK;
620 }
621 
HandleCompileWithBundle(const std::string & bundleName,const std::string & compileMode,std::shared_ptr<BundleDataMgr> dataMgr) const622 EventInfo AOTHandler::HandleCompileWithBundle(const std::string &bundleName, const std::string &compileMode,
623     std::shared_ptr<BundleDataMgr> dataMgr) const
624 {
625     APP_LOGI("handle compile bundle %{public}s", bundleName.c_str());
626     EventInfo eventInfo;
627     eventInfo.timeStamp = BundleUtil::GetCurrentTime();
628     eventInfo.bundleName = bundleName;
629     eventInfo.compileMode = compileMode;
630     eventInfo.compileResult = false;
631 
632     if (OTACompileDeadline_) {
633         APP_LOGI("reach OTA deadline, stop compile bundle");
634         eventInfo.failureReason = FAILURE_REASON_TIME_OUT;
635         return eventInfo;
636     }
637 
638     InnerBundleInfo info;
639     if (!dataMgr->QueryInnerBundleInfo(bundleName, info)) {
640         APP_LOGE("QueryInnerBundleInfo failed");
641         eventInfo.failureReason = FAILURE_REASON_BUNDLE_NOT_EXIST;
642         return eventInfo;
643     }
644     if (!info.GetIsNewVersion()) {
645         APP_LOGI("not stage model, no need to AOT");
646         eventInfo.failureReason = FAILURE_REASON_NOT_STAGE_MODEL;
647         return eventInfo;
648     }
649 
650     int64_t beginTimeSeconds = BundleUtil::GetCurrentTime();
651     bool compileRet = true;
652 
653     std::vector<std::string> moduleNames;
654     info.GetModuleNames(moduleNames);
655     for (const std::string &moduleName : moduleNames) {
656         if (OTACompileDeadline_) {
657             APP_LOGI("reach OTA deadline, stop compile module");
658             eventInfo.failureReason = FAILURE_REASON_TIME_OUT;
659             eventInfo.costTimeSeconds = BundleUtil::GetCurrentTime() - beginTimeSeconds;
660             return eventInfo;
661         }
662         ErrCode ret = HandleCompileWithSingleHap(info, moduleName, compileMode, true);
663         APP_LOGI("moduleName : %{public}s, ret : %{public}d", moduleName.c_str(), ret);
664         if (ret != ERR_OK) {
665             compileRet = false;
666         }
667     }
668 
669     if (compileRet) {
670         eventInfo.compileResult = true;
671         eventInfo.failureReason.clear();
672     } else {
673         eventInfo.compileResult = false;
674         eventInfo.failureReason = FAILURE_REASON_COMPILE_FAILED;
675     }
676     eventInfo.costTimeSeconds = BundleUtil::GetCurrentTime() - beginTimeSeconds;
677     return eventInfo;
678 }
679 
ReportSysEvent(const std::map<std::string,EventInfo> & sysEventMap) const680 void AOTHandler::ReportSysEvent(const std::map<std::string, EventInfo> &sysEventMap) const
681 {
682     auto task = [sysEventMap]() {
683         APP_LOGI("begin to report AOT sysEvent");
684         EventInfo summaryInfo;
685         summaryInfo.timeStamp = BundleUtil::GetCurrentTime();
686         for (const auto &item : sysEventMap) {
687             summaryInfo.totalBundleNames.emplace_back(item.first);
688             if (item.second.compileResult) {
689                 summaryInfo.successCnt++;
690             }
691             summaryInfo.costTimeSeconds += item.second.costTimeSeconds;
692             EventReport::SendSystemEvent(BMSEventType::AOT_COMPILE_RECORD, item.second);
693         }
694         EventReport::SendSystemEvent(BMSEventType::AOT_COMPILE_SUMMARY, summaryInfo);
695         APP_LOGI("report AOT sysEvent done");
696     };
697     std::thread(task).detach();
698 }
699 
HandleIdleWithSingleHap(const InnerBundleInfo & info,const std::string & moduleName,const std::string & compileMode) const700 void AOTHandler::HandleIdleWithSingleHap(
701     const InnerBundleInfo &info, const std::string &moduleName, const std::string &compileMode) const
702 {
703     APP_LOGD("HandleIdleWithSingleHap, moduleName : %{public}s", moduleName.c_str());
704     if (!NeedCompile(info, moduleName)) {
705         return;
706     }
707     std::optional<AOTArgs> aotArgs = BuildAOTArgs(info, moduleName, compileMode);
708     (void)AOTInternal(aotArgs, info.GetVersionCode());
709 }
710 
NeedCompile(const InnerBundleInfo & info,const std::string & moduleName) const711 bool AOTHandler::NeedCompile(const InnerBundleInfo &info, const std::string &moduleName) const
712 {
713     AOTCompileStatus status = info.GetAOTCompileStatus(moduleName);
714     if (status == AOTCompileStatus::NOT_COMPILED || status == AOTCompileStatus::COMPILE_CANCELLED) {
715         return true;
716     }
717     APP_LOGI("%{public}s:%{public}d, skip compile", moduleName.c_str(), static_cast<int32_t>(status));
718     return false;
719 }
720 
HandleCompileWithSingleHap(const InnerBundleInfo & info,const std::string & moduleName,const std::string & compileMode,bool isEnableBaselinePgo) const721 ErrCode AOTHandler::HandleCompileWithSingleHap(const InnerBundleInfo &info, const std::string &moduleName,
722     const std::string &compileMode, bool isEnableBaselinePgo) const
723 {
724     APP_LOGI("HandleCompileWithSingleHap, moduleName : %{public}s", moduleName.c_str());
725     std::optional<AOTArgs> aotArgs = BuildAOTArgs(info, moduleName, compileMode, isEnableBaselinePgo);
726     return AOTInternal(aotArgs, info.GetVersionCode());
727 }
728 
CheckDeviceState() const729 bool AOTHandler::CheckDeviceState() const
730 {
731 #ifdef BUNDLE_FRAMEWORK_POWER_MGR_ENABLE
732     DisplayPowerMgr::DisplayState displayState =
733         DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().GetDisplayState();
734     if (displayState != DisplayPowerMgr::DisplayState::DISPLAY_OFF) {
735         APP_LOGI("displayState is not DISPLAY_OFF");
736         return false;
737     }
738     return true;
739 #else
740     APP_LOGI("device not support power system");
741     return false;
742 #endif
743 }
744 
HandleIdle() const745 void AOTHandler::HandleIdle() const
746 {
747     APP_LOGI("HandleIdle begin");
748     std::unique_lock<std::mutex> lock(idleMutex_, std::defer_lock);
749     if (!lock.try_lock()) {
750         APP_LOGI("idle task is running, skip");
751         return;
752     }
753     if (!IsSupportARM64()) {
754         APP_LOGI("current device doesn't support arm64, no need to AOT");
755         return;
756     }
757     std::string compileMode = system::GetParameter(IDLE_COMPILE_MODE, ServiceConstants::COMPILE_PARTIAL);
758     APP_LOGI("%{public}s = %{public}s", IDLE_COMPILE_MODE, compileMode.c_str());
759     if (compileMode == COMPILE_NONE) {
760         APP_LOGI("%{public}s none, no need to AOT", IDLE_COMPILE_MODE);
761         return;
762     }
763     if (!CheckDeviceState()) {
764         APP_LOGI("device state is not suitable");
765         return;
766     }
767     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
768     if (!dataMgr) {
769         APP_LOGE("dataMgr is null");
770         return;
771     }
772     std::vector<std::string> bundleNames = dataMgr->GetAllBundleName();
773     std::for_each(bundleNames.cbegin(), bundleNames.cend(), [this, dataMgr, &compileMode](const auto &bundleName) {
774         APP_LOGD("HandleIdle bundleName : %{public}s", bundleName.c_str());
775         InnerBundleInfo info;
776         if (!dataMgr->QueryInnerBundleInfo(bundleName, info)) {
777             APP_LOGE("QueryInnerBundleInfo failed");
778             return;
779         }
780         if (!info.GetIsNewVersion()) {
781             APP_LOGD("not stage model, no need to AOT");
782             return;
783         }
784         std::vector<std::string> moduleNames;
785         info.GetModuleNames(moduleNames);
786         std::for_each(moduleNames.cbegin(), moduleNames.cend(), [this, &info, &compileMode](const auto &moduleName) {
787             HandleIdleWithSingleHap(info, moduleName, compileMode);
788         });
789     });
790     APP_LOGI("HandleIdle end");
791 }
792 
HandleCompile(const std::string & bundleName,const std::string & compileMode,bool isAllBundle,std::vector<std::string> & compileResults) const793 ErrCode AOTHandler::HandleCompile(const std::string &bundleName, const std::string &compileMode, bool isAllBundle,
794     std::vector<std::string> &compileResults) const
795 {
796     APP_LOGI("HandleCompile begin");
797     if (isAllBundle && system::GetParameter("BM_AOT_TEST", "").empty()) {
798         APP_LOGD("isAllBundle true, param bm.aot.test empty, so ignore");
799         return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
800     }
801     std::unique_lock<std::mutex> lock(compileMutex_, std::defer_lock);
802     if (!lock.try_lock()) {
803         APP_LOGI("compile task running, skip %{public}s", bundleName.c_str());
804         std::string compileResult = "info: compile task is running, skip.";
805         compileResults.emplace_back(compileResult);
806         return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
807     }
808     if (!IsSupportARM64()) {
809         APP_LOGI("current device doesn't support arm64, no need to AOT");
810         std::string compileResult = "info: current device doesn't support arm64, no need to AOT.";
811         compileResults.emplace_back(compileResult);
812         return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
813     }
814     if (compileMode == COMPILE_NONE) {
815         APP_LOGI("%{public}s none, no need to AOT", IDLE_COMPILE_MODE);
816         std::string compileResult = "info: persist.bm.idle.arkopt = none, no need to AOT.";
817         compileResults.emplace_back(compileResult);
818         return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
819     }
820     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
821     if (!dataMgr) {
822         APP_LOGE("dataMgr is null");
823         std::string compileResult = "error: dataMgr is null, compile fail.";
824         compileResults.emplace_back(compileResult);
825         return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
826     }
827     std::vector<std::string> bundleNames;
828     if (isAllBundle) {
829         bundleNames = dataMgr->GetAllBundleName();
830     } else {
831         bundleNames = {bundleName};
832     }
833     ErrCode ret = HandleCompileBundles(bundleNames, compileMode, dataMgr, compileResults);
834     if (ret == ERR_OK) {
835         compileResults.clear();
836     }
837     APP_LOGI("HandleCompile end");
838     return ret;
839 }
840 
HandleCompileBundles(const std::vector<std::string> & bundleNames,const std::string & compileMode,std::shared_ptr<BundleDataMgr> & dataMgr,std::vector<std::string> & compileResults) const841 ErrCode AOTHandler::HandleCompileBundles(const std::vector<std::string> &bundleNames, const std::string &compileMode,
842     std::shared_ptr<BundleDataMgr> &dataMgr, std::vector<std::string> &compileResults) const
843 {
844     ErrCode ret = ERR_OK;
845     std::for_each(bundleNames.cbegin(), bundleNames.cend(),
846         [this, dataMgr, &compileMode, &ret, &compileResults](const auto &bundleToCompile) {
847         APP_LOGD("HandleCompile bundleToCompile : %{public}s", bundleToCompile.c_str());
848         InnerBundleInfo info;
849         if (!dataMgr->QueryInnerBundleInfo(bundleToCompile, info)) {
850             APP_LOGE("QueryInnerBundleInfo failed. bundleToCompile %{public}s", bundleToCompile.c_str());
851             std::string compileResult = bundleToCompile + ": QueryInnerBundleInfo failed.";
852             compileResults.emplace_back(compileResult);
853             ret = ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
854             return;
855         }
856         if (!info.GetIsNewVersion()) {
857             APP_LOGD("not stage model, no need to AOT");
858             std::string compileResult = bundleToCompile + ": not stage model, no need to AOT.";
859             compileResults.emplace_back(compileResult);
860             ret = ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
861             return;
862         }
863         std::vector<std::string> moduleNames;
864         info.GetModuleNames(moduleNames);
865         std::string compileResult = "";
866         if (HandleCompileModules(moduleNames, compileMode, info, compileResult) == ERR_OK) {
867             compileResult = bundleToCompile + ": compile success.";
868         } else {
869             compileResult = bundleToCompile + ":" + compileResult;
870             ret = ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
871         }
872         compileResults.emplace_back(compileResult);
873     });
874     return ret;
875 }
876 
HandleCompileModules(const std::vector<std::string> & moduleNames,const std::string & compileMode,InnerBundleInfo & info,std::string & compileResult) const877 ErrCode AOTHandler::HandleCompileModules(const std::vector<std::string> &moduleNames, const std::string &compileMode,
878     InnerBundleInfo &info, std::string &compileResult) const
879 {
880     ErrCode ret = ERR_OK;
881     std::for_each(moduleNames.cbegin(), moduleNames.cend(),
882         [this, &info, &compileMode, &ret, &compileResult](const auto &moduleName) {
883         ErrCode errCode = HandleCompileWithSingleHap(info, moduleName, compileMode);
884         switch (errCode) {
885             case ERR_OK:
886                 break;
887             case ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED:
888                 compileResult += "  " + moduleName + ":compile-fail";
889                 break;
890             case ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_CRASH:
891                 compileResult += "  " + moduleName + ":compile-crash";
892                 break;
893             case ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_CANCELLED:
894                 compileResult += "  " + moduleName + ":compile-cancelled";
895                 break;
896             case ERR_APPEXECFWK_INSTALLD_SIGN_AOT_FAILED:
897                 compileResult += "  " + moduleName + ":signature-fail";
898                 break;
899             case ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE:
900                 compileResult += "  " + moduleName + ":signature-disable";
901                 break;
902             case ERR_APPEXECFWK_AOT_ARGS_EMPTY:
903                 compileResult += "  " + moduleName + ":args-empty";
904                 break;
905             default:
906                 compileResult += "  " + moduleName + ":other-fail";
907                 break;
908         }
909         if (errCode != ERR_OK) {
910             ret = ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED;
911         }
912     });
913     return ret;
914 }
915 
GetCurAOTVersion() const916 std::string AOTHandler::GetCurAOTVersion() const
917 {
918     APP_LOGI("GetCurAOTVersion begin");
919     void* handle = dlopen(ARK_SO_NAME, RTLD_NOW);
920     if (handle == nullptr) {
921         APP_LOGE("get aot version dlopen failed : %{public}s", dlerror());
922         return Constants::EMPTY_STRING;
923     }
924     AOTVersionFunc aotVersionFunc = reinterpret_cast<AOTVersionFunc>(dlsym(handle, AOT_VERSION_FUNC_NAME));
925     if (aotVersionFunc == nullptr) {
926         APP_LOGE("get aot version dlsym failed : %{public}s", dlerror());
927         dlclose(handle);
928         return Constants::EMPTY_STRING;
929     }
930     std::string aotVersion;
931     ErrCode ret = aotVersionFunc(aotVersion);
932     APP_LOGI("GetCurAOTVersion ret : %{public}d, aotVersion: %{public}s", ret, aotVersion.c_str());
933     dlclose(handle);
934     return aotVersion;
935 }
936 
GetOldAOTVersion(std::string & oldAOTVersion) const937 bool AOTHandler::GetOldAOTVersion(std::string &oldAOTVersion) const
938 {
939     auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
940     if (bmsPara == nullptr) {
941         APP_LOGE("bmsPara is nullptr");
942         return false;
943     }
944     bmsPara->GetBmsParam(AOT_VERSION, oldAOTVersion);
945     if (oldAOTVersion.empty()) {
946         APP_LOGI("oldAOTVersion is empty");
947         return false;
948     }
949     return true;
950 }
951 
SaveAOTVersion(const std::string & curAOTVersion) const952 void AOTHandler::SaveAOTVersion(const std::string &curAOTVersion) const
953 {
954     if (curAOTVersion.empty()) {
955         return;
956     }
957     auto bmsPara = DelayedSingleton<BundleMgrService>::GetInstance()->GetBmsParam();
958     if (bmsPara == nullptr) {
959         APP_LOGE("bmsPara is nullptr");
960         return;
961     }
962     bmsPara->SaveBmsParam(AOT_VERSION, curAOTVersion);
963 }
964 }  // namespace AppExecFwk
965 }  // namespace OHOS
966