1 /*
2 * Copyright (c) 2024-2025 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_sign_data_cache_mgr.h"
17
18 #include <thread>
19 #include <chrono>
20
21 #include "installd_client.h"
22
23 namespace OHOS {
24 namespace AppExecFwk {
GetInstance()25 AOTSignDataCacheMgr& AOTSignDataCacheMgr::GetInstance()
26 {
27 static AOTSignDataCacheMgr signDataCacheMgr;
28 return signDataCacheMgr;
29 }
30
RegisterScreenUnlockListener()31 void AOTSignDataCacheMgr::RegisterScreenUnlockListener()
32 {
33 EventFwk::MatchingSkills matchingSkill;
34 // use COMMON_EVENT_USER_UNLOCKED if only for device with PIN
35 matchingSkill.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED);
36 EventFwk::CommonEventSubscribeInfo eventInfo(matchingSkill);
37 unlockEventSubscriber_ = std::make_shared<UnlockEventSubscriber>(eventInfo);
38 const bool result = EventFwk::CommonEventManager::SubscribeCommonEvent(unlockEventSubscriber_);
39 if (!result) {
40 APP_LOGE_NOFUNC("register screen unlock event for pending sign AOT error");
41 return;
42 }
43 APP_LOGI_NOFUNC("AOT register screen unlock event success");
44 }
45
AddSignDataForSysComp(const std::string & anFileName,const std::vector<uint8_t> & signData,const ErrCode ret)46 void AOTSignDataCacheMgr::AddSignDataForSysComp(const std::string &anFileName, const std::vector<uint8_t> &signData,
47 const ErrCode ret)
48 {
49 if (anFileName.empty() || signData.empty()) {
50 APP_LOGE_NOFUNC("empty anFileName or signData");
51 return;
52 }
53 if (!isLocked_ || ret != ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE) {
54 return;
55 }
56 std::lock_guard<std::mutex> lock(mutex_);
57 sysCompSignDataMap_[anFileName] = signData;
58 }
59
AddSignDataForHap(const AOTArgs & aotArgs,const uint32_t versionCode,const std::vector<uint8_t> & signData,const ErrCode ret)60 void AOTSignDataCacheMgr::AddSignDataForHap(const AOTArgs &aotArgs, const uint32_t versionCode,
61 const std::vector<uint8_t> &signData, const ErrCode ret)
62 {
63 if (aotArgs.bundleName.empty() || aotArgs.moduleName.empty() || signData.empty()) {
64 APP_LOGE_NOFUNC("empty bundleName or moduleName or signData");
65 return;
66 }
67 if (!isLocked_ || ret != ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE) {
68 return;
69 }
70 std::lock_guard<std::mutex> lock(mutex_);
71 hapSignDataVector_.emplace_back(HapSignData{versionCode, aotArgs.bundleName, aotArgs.moduleName, signData});
72 }
73
UnregisterScreenUnlockEvent()74 void AOTSignDataCacheMgr::UnregisterScreenUnlockEvent()
75 {
76 const bool result = EventFwk::CommonEventManager::UnSubscribeCommonEvent(unlockEventSubscriber_);
77 if (!result) {
78 APP_LOGE_NOFUNC("unregister screen unlock event error");
79 return;
80 }
81 APP_LOGI_NOFUNC("unregister screen unlock event success");
82 }
83
OnReceiveEvent(const EventFwk::CommonEventData & event)84 void AOTSignDataCacheMgr::UnlockEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &event)
85 {
86 const auto want = event.GetWant();
87 const auto action = want.GetAction();
88 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED) {
89 APP_LOGI("receive screen unlock event");
90 auto task = []() {
91 AOTSignDataCacheMgr::GetInstance().HandleUnlockEvent();
92 };
93 std::thread(task).detach();
94 }
95 }
96
HandleUnlockEvent()97 void AOTSignDataCacheMgr::HandleUnlockEvent()
98 {
99 APP_LOGI_NOFUNC("begin to sign data");
100 isLocked_ = false;
101 UnregisterScreenUnlockEvent();
102
103 uint8_t maxRetry = 5;
104 for (uint8_t i = 1; i <= maxRetry; ++i) {
105 std::this_thread::sleep_for(std::chrono::seconds(1));
106 if (EnforceCodeSign()) {
107 APP_LOGI_NOFUNC("sign data success");
108 return;
109 }
110 }
111 std::lock_guard<std::mutex> lock(mutex_);
112 std::unordered_map<std::string, std::vector<uint8_t>>().swap(sysCompSignDataMap_);
113 hapSignDataVector_.clear();
114 APP_LOGE_NOFUNC("sign data failed");
115 }
116
EnforceCodeSign()117 bool AOTSignDataCacheMgr::EnforceCodeSign()
118 {
119 return EnforceCodeSignForSysComp() && EnforceCodeSignForHap();
120 }
121
EnforceCodeSignForSysComp()122 bool AOTSignDataCacheMgr::EnforceCodeSignForSysComp()
123 {
124 std::lock_guard<std::mutex> lock(mutex_);
125 for (const auto &[anFileName, signData] : sysCompSignDataMap_) {
126 ErrCode signRet = InstalldClient::GetInstance()->PendSignAOT(anFileName, signData);
127 if (signRet == ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE) {
128 APP_LOGE_NOFUNC("sign service disabled");
129 return false;
130 }
131 }
132 std::unordered_map<std::string, std::vector<uint8_t>>().swap(sysCompSignDataMap_);
133 return true;
134 }
135
EnforceCodeSignForHap()136 bool AOTSignDataCacheMgr::EnforceCodeSignForHap()
137 {
138 std::lock_guard<std::mutex> lock(mutex_);
139 for (const HapSignData &hapSignData : hapSignDataVector_) {
140 std::filesystem::path anFileName(ServiceConstants::ARK_CACHE_PATH);
141 anFileName /= hapSignData.bundleName;
142 anFileName /= ServiceConstants::ARM64;
143 anFileName /= hapSignData.moduleName + ServiceConstants::AN_SUFFIX;
144 ErrCode signRet = InstalldClient::GetInstance()->PendSignAOT(anFileName.string(), hapSignData.signData);
145 if (signRet == ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE) {
146 APP_LOGE_NOFUNC("sign service disabled");
147 return false;
148 }
149 if (signRet == ERR_OK) {
150 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
151 if (dataMgr != nullptr) {
152 dataMgr->SetAOTCompileStatus(hapSignData.bundleName, hapSignData.moduleName,
153 AOTCompileStatus::COMPILE_SUCCESS, hapSignData.versionCode);
154 }
155 }
156 }
157 hapSignDataVector_.clear();
158 return true;
159 }
160 } // namespace AppExecFwk
161 } // namespace OHOS
162