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