1 /*
2 * Copyright (c) 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_compiler_client.h"
17 #include "aot_compiler_error_utils.h"
18 #include "aot_compiler_load_callback.h"
19 #include "ecmascript/log_wrapper.h"
20 #include "hitrace_meter.h"
21 #include "iservice_registry.h"
22 #include "system_ability_definition.h"
23
24 namespace OHOS::ArkCompiler {
25 namespace {
26 const int LOAD_SA_TIMEOUT_MS = 6 * 1000;
27 } // namespace
28
AotCompilerClient()29 AotCompilerClient::AotCompilerClient()
30 {
31 aotCompilerDiedRecipient_ = new (std::nothrow) AotCompilerDiedRecipient();
32 if (aotCompilerDiedRecipient_ == nullptr) {
33 LOG_SA(ERROR) << "create aot compiler died recipient failed";
34 }
35 }
36
GetInstance()37 AotCompilerClient &AotCompilerClient::GetInstance()
38 {
39 static AotCompilerClient singleAotCompilerClient;
40 return singleAotCompilerClient;
41 }
42
AotCompiler(const std::unordered_map<std::string, std::string> &argsMap, std::vector<int16_t> &sigData)43 int32_t AotCompilerClient::AotCompiler(const std::unordered_map<std::string, std::string> &argsMap,
44 std::vector<int16_t> &sigData)
45 {
46 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
47 LOG_SA(DEBUG) << "aot compiler function called";
48 auto aotCompilerProxy = GetAotCompilerProxy();
49 if (aotCompilerProxy == nullptr) {
50 LOG_SA(ERROR) << "get aot compiler service failed";
51 return ERR_AOT_COMPILER_CONNECT_FAILED;
52 }
53 return aotCompilerProxy->AotCompiler(argsMap, sigData);
54 }
55
StopAotCompiler()56 int32_t AotCompilerClient::StopAotCompiler()
57 {
58 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
59 LOG_SA(DEBUG) << "aot compiler function called";
60 auto aotCompilerProxy = GetAotCompilerProxy();
61 if (aotCompilerProxy == nullptr) {
62 LOG_SA(ERROR) << "get aot compiler service failed";
63 return ERR_AOT_COMPILER_CONNECT_FAILED;
64 }
65 return aotCompilerProxy->StopAotCompiler();
66 }
67
GetAOTVersion(std::string& sigData)68 int32_t AotCompilerClient::GetAOTVersion(std::string& sigData)
69 {
70 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
71 LOG_SA(DEBUG) << "aot compiler get AOT version called";
72 auto aotCompilerProxy = GetAotCompilerProxy();
73 if (aotCompilerProxy == nullptr) {
74 LOG_SA(ERROR) << "get aot compiler service failed";
75 return ERR_AOT_COMPILER_CONNECT_FAILED;
76 }
77
78 return aotCompilerProxy->GetAOTVersion(sigData);
79 }
80
NeedReCompile(const std::string& oldVersion, bool& sigData)81 int32_t AotCompilerClient::NeedReCompile(const std::string& oldVersion, bool& sigData)
82 {
83 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
84 LOG_SA(DEBUG) << "aot compiler check need re-compile called";
85 auto aotCompilerProxy = GetAotCompilerProxy();
86 if (aotCompilerProxy == nullptr) {
87 LOG_SA(ERROR) << "get aot compiler service failed";
88 return ERR_AOT_COMPILER_CONNECT_FAILED;
89 }
90 return aotCompilerProxy->NeedReCompile(oldVersion, sigData);
91 }
92
GetAotCompilerProxy()93 sptr<IAotCompilerInterface> AotCompilerClient::GetAotCompilerProxy()
94 {
95 LOG_SA(DEBUG) << "get aot compiler proxy function called";
96 auto aotCompilerProxy = GetAotCompiler();
97 if (aotCompilerProxy != nullptr) {
98 LOG_SA(DEBUG) << "aot compiler service proxy has been started";
99 return aotCompilerProxy;
100 }
101 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
102 if (systemAbilityMgr == nullptr) {
103 LOG_SA(ERROR) << "failed to get system ability manager";
104 return nullptr;
105 }
106 auto remoteObject = systemAbilityMgr->CheckSystemAbility(AOT_COMPILER_SERVICE_ID);
107 if (remoteObject != nullptr) {
108 aotCompilerProxy = iface_cast<IAotCompilerInterface>(remoteObject);
109 return aotCompilerProxy;
110 }
111 if (!LoadAotCompilerService()) {
112 LOG_SA(ERROR) << "load aot compiler service failed";
113 return nullptr;
114 }
115 aotCompilerProxy = GetAotCompiler();
116 if (aotCompilerProxy == nullptr || aotCompilerProxy->AsObject() == nullptr) {
117 LOG_SA(ERROR) << "failed to get aot compiler service";
118 return nullptr;
119 }
120 LOG_SA(DEBUG) << "get aot compiler proxy function finished";
121 return aotCompilerProxy;
122 }
123
LoadAotCompilerService()124 bool AotCompilerClient::LoadAotCompilerService()
125 {
126 {
127 std::unique_lock<std::mutex> lock(loadSaMutex_);
128 loadSaFinished_ = false;
129 }
130 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
131 if (systemAbilityMgr == nullptr) {
132 LOG_SA(ERROR) << "failed to get system ability manager";
133 return false;
134 }
135 sptr<AotCompilerLoadCallback> loadCallback = new (std::nothrow) AotCompilerLoadCallback();
136 if (loadCallback == nullptr) {
137 LOG_SA(ERROR) << "failed to create load callback";
138 return false;
139 }
140 auto ret = systemAbilityMgr->LoadSystemAbility(AOT_COMPILER_SERVICE_ID, loadCallback);
141 if (ret != 0) {
142 LOG_SA(ERROR) << "load system ability " << AOT_COMPILER_SERVICE_ID << " failed with " << ret;
143 return false;
144 }
145 {
146 std::unique_lock<std::mutex> lock(loadSaMutex_);
147 auto waitStatus = loadSaCondition_.wait_for(lock, std::chrono::milliseconds(LOAD_SA_TIMEOUT_MS),
148 [this]() {
149 return loadSaFinished_;
150 });
151 if (!waitStatus) {
152 LOG_SA(ERROR) << "wait for load SA timeout";
153 return false;
154 }
155 }
156 return true;
157 }
158
SetAotCompiler(const sptr<IRemoteObject> &remoteObject)159 void AotCompilerClient::SetAotCompiler(const sptr<IRemoteObject> &remoteObject)
160 {
161 std::lock_guard<std::mutex> lock(mutex_);
162 aotCompilerProxy_ = iface_cast<IAotCompilerInterface>(remoteObject);
163 }
164
GetAotCompiler()165 sptr<IAotCompilerInterface> AotCompilerClient::GetAotCompiler()
166 {
167 std::lock_guard<std::mutex> lock(mutex_);
168 return aotCompilerProxy_;
169 }
170
OnLoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)171 void AotCompilerClient::OnLoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)
172 {
173 if (aotCompilerDiedRecipient_ == nullptr) {
174 LOG_SA(ERROR) << "register aot compiler died recipient failed";
175 return;
176 }
177 if (!remoteObject->AddDeathRecipient(aotCompilerDiedRecipient_)) {
178 LOG_SA(ERROR) << "add aot compiler died recipient failed";
179 return;
180 }
181 SetAotCompiler(remoteObject);
182 std::unique_lock<std::mutex> lock(loadSaMutex_);
183 loadSaFinished_ = true;
184 loadSaCondition_.notify_one();
185 }
186
OnLoadSystemAbilityFail()187 void AotCompilerClient::OnLoadSystemAbilityFail()
188 {
189 SetAotCompiler(nullptr);
190 std::unique_lock<std::mutex> lock(loadSaMutex_);
191 loadSaFinished_ = true;
192 loadSaCondition_.notify_one();
193 }
194
OnRemoteDied(const wptr<IRemoteObject> &remoteObject)195 void AotCompilerClient::AotCompilerDiedRecipient::OnRemoteDied(const wptr<IRemoteObject> &remoteObject)
196 {
197 if (remoteObject == nullptr) {
198 LOG_SA(ERROR) << "remote object of aot compiler died recipient is nullptr";
199 return;
200 }
201 AotCompilerClient::GetInstance().AotCompilerOnRemoteDied(remoteObject);
202 }
203
AotCompilerOnRemoteDied(const wptr<IRemoteObject> &remoteObject)204 void AotCompilerClient::AotCompilerOnRemoteDied(const wptr<IRemoteObject> &remoteObject)
205 {
206 LOG_SA(INFO) << "remote object of aot compiler died recipient is died";
207 auto aotCompilerProxy = GetAotCompiler();
208 if (aotCompilerProxy == nullptr) {
209 LOG_SA(ERROR) << "aot compiler proxy is nullptr";
210 return;
211 }
212 sptr<IRemoteObject> remotePromote = remoteObject.promote();
213 if (remotePromote == nullptr) {
214 LOG_SA(ERROR) << "remote object of aot compiler promote fail";
215 return;
216 }
217 if (aotCompilerProxy->AsObject() != remotePromote) {
218 LOG_SA(ERROR) << "aot compiler died recipient not find remote object";
219 return;
220 }
221 remotePromote->RemoveDeathRecipient(aotCompilerDiedRecipient_);
222 SetAotCompiler(nullptr);
223 }
224 } // namespace OHOS::ArkCompiler