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