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_service.h"
17#include "aot_compiler_error_utils.h"
18#include "aot_compiler_impl.h"
19#include "ecmascript/log_wrapper.h"
20#include "iservice_registry.h"
21#include "ipc_skeleton.h"
22#include "iremote_object.h"
23#include "system_ability_definition.h"
24
25#include "power_disconnected_listener.h"
26
27#include "common_event_data.h"
28#include "common_event_manager.h"
29#include "common_event_support.h"
30#include "common_event_subscriber.h"
31
32namespace OHOS::ArkCompiler {
33namespace {
34const std::string TASK_ID = "UnLoadSA";
35constexpr int32_t DELAY_TIME = 180000;
36}
37
38REGISTER_SYSTEM_ABILITY_BY_ID(AotCompilerService, AOT_COMPILER_SERVICE_ID, false);
39
40AotCompilerService::AotCompilerService()
41    : SystemAbility(AOT_COMPILER_SERVICE_ID, false), state_(ServiceRunningState::STATE_NOT_START)
42{
43}
44
45AotCompilerService::AotCompilerService(int32_t systemAbilityId, bool runOnCreate)
46    : SystemAbility(systemAbilityId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START)
47{
48}
49
50AotCompilerService::~AotCompilerService()
51{
52}
53
54void AotCompilerService::OnStart()
55{
56    LOG_SA(INFO) << "aot compiler service is onStart";
57    if (state_ == ServiceRunningState::STATE_RUNNING) {
58        LOG_SA(INFO) << "aot compiler service has already started";
59        return;
60    }
61    if (!Init()) {
62        LOG_SA(INFO) << "init aot compiler service failed";
63        return;
64    }
65    bool ret = Publish(this);
66    if (!ret) {
67        LOG_SA(ERROR) << "publish service failed";
68        return;
69    }
70    state_ = ServiceRunningState::STATE_RUNNING;
71    RegisterPowerDisconnectedListener();
72    RegisterScreenStatusSubscriber();
73    RegisterThermalMgrListener();
74}
75
76bool AotCompilerService::Init()
77{
78    auto runner = AppExecFwk::EventRunner::Create(TASK_ID);
79    if (unLoadHandler_ == nullptr) {
80        unLoadHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
81    }
82    return true;
83}
84
85void AotCompilerService::RemoveUnloadTask(const std::string &taskId)
86{
87    if (unLoadHandler_ == nullptr) {
88        LOG_SA(ERROR) << "NULL pointer of unLoadHandler_ error";
89        return;
90    }
91    unLoadHandler_->RemoveTask(taskId);
92}
93
94void AotCompilerService::DelayUnloadTask(const std::string &taskId, const int32_t delayTime)
95{
96    if (unLoadHandler_ == nullptr) {
97        LOG_SA(ERROR) << "NULL pointer of unLoadHandler_ error";
98        return;
99    }
100    auto task = []() {
101        sptr<ISystemAbilityManager> samgr =
102            SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
103        if (samgr == nullptr) {
104            LOG_SA(ERROR) << "fail to get system ability manager";
105            return;
106        }
107        int32_t ret = samgr->UnloadSystemAbility(AOT_COMPILER_SERVICE_ID);
108        if (ret != ERR_OK) {
109            LOG_SA(ERROR) << "remove system ability failed";
110            return;
111        }
112    };
113    unLoadHandler_->PostTask(task, taskId, delayTime);
114}
115
116void AotCompilerService::OnStop()
117{
118    LOG_SA(INFO) << "aot compiler service has been onStop";
119    state_ = ServiceRunningState::STATE_NOT_START;
120    UnRegisterPowerDisconnectedListener();
121    UnRegisterScreenStatusSubscriber();
122    UnRegisterThermalMgrListener();
123}
124
125int32_t AotCompilerService::AotCompiler(const std::unordered_map<std::string, std::string> &argsMap,
126                                        std::vector<int16_t> &sigData)
127{
128    LOG_SA(DEBUG) << "begin to call aot compiler";
129    RemoveUnloadTask(TASK_ID);
130    int32_t ret = ERR_FAIL;
131    {
132        std::lock_guard<std::mutex> lock(aotCompilerMutex_);
133        ret = AotCompilerImpl::GetInstance().EcmascriptAotCompiler(argsMap, sigData);
134    }
135    LOG_SA(DEBUG) << "finish aot compiler";
136    DelayUnloadTask(TASK_ID, DELAY_TIME);
137    return ret;
138}
139
140int32_t AotCompilerService::GetAOTVersion(std::string& sigData)
141{
142    LOG_SA(DEBUG) << "begin to get AOT version";
143    RemoveUnloadTask(TASK_ID);
144    int32_t ret = AotCompilerImpl::GetInstance().GetAOTVersion(sigData);
145    LOG_SA(DEBUG) << "finish get AOT Version";
146    DelayUnloadTask(TASK_ID, DELAY_TIME);
147    return ret;
148}
149
150int32_t AotCompilerService::NeedReCompile(const std::string& args, bool& sigData)
151{
152    LOG_SA(DEBUG) << "begin to check need to re-compile version";
153    RemoveUnloadTask(TASK_ID);
154    int32_t ret = AotCompilerImpl::GetInstance().NeedReCompile(args, sigData);
155    LOG_SA(DEBUG) << "finish check need re-compile";
156    DelayUnloadTask(TASK_ID, DELAY_TIME);
157    return ret;
158}
159
160int32_t AotCompilerService::StopAotCompiler()
161{
162    LOG_SA(DEBUG) << "stop aot compiler service";
163    RemoveUnloadTask(TASK_ID);
164    int32_t ret = AotCompilerImpl::GetInstance().StopAotCompiler();
165    DelayUnloadTask(TASK_ID, DELAY_TIME);
166    return ret;
167}
168
169void AotCompilerService::RegisterPowerDisconnectedListener()
170{
171    LOG_SA(DEBUG) << "AotCompilerService::RegisterPowerDisconnectedListener";
172    EventFwk::MatchingSkills matchingSkills;
173    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_POWER_DISCONNECTED);
174    EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
175    powerDisconnectedListener_ = std::make_shared<PowerDisconnectedListener>(subscribeInfo);
176    if (!EventFwk::CommonEventManager::SubscribeCommonEvent(powerDisconnectedListener_)) {
177        LOG_SA(INFO) << "AotCompilerService::RegisterPowerDisconnectedListener failed";
178        powerDisconnectedListener_ = nullptr;
179    } else {
180        LOG_SA(INFO) << "AotCompilerService::RegisterPowerDisconnectedListener success";
181        isPowerEventSubscribered_ = true;
182    }
183}
184
185void AotCompilerService::RegisterScreenStatusSubscriber()
186{
187    LOG_SA(DEBUG) << "AotCompilerService::RegisterScreenStatusSubscriber";
188    EventFwk::MatchingSkills matchingSkills;
189    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON);
190    EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
191    screenStatusSubscriber_ = std::make_shared<ScreenStatusSubscriber>(subscribeInfo);
192    if (!EventFwk::CommonEventManager::SubscribeCommonEvent(screenStatusSubscriber_)) {
193        LOG_SA(WARN) << "AotCompilerService::RegisterScreenStatusSubscriber failed";
194        screenStatusSubscriber_ = nullptr;
195    } else {
196        LOG_SA(INFO) << "AotCompilerService::RegisterScreenStatusSubscriber success";
197        isScreenStatusSubscribered_ = true;
198    }
199}
200
201void AotCompilerService::RegisterThermalMgrListener()
202{
203    LOG_SA(DEBUG) << "AotCompilerService::RegisterThermalMgrListener";
204    EventFwk::MatchingSkills matchingSkills;
205    matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_THERMAL_LEVEL_CHANGED);
206    EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
207    thermalMgrListener_ = std::make_shared<ThermalMgrListener>(subscribeInfo);
208    if (!EventFwk::CommonEventManager::SubscribeCommonEvent(thermalMgrListener_)) {
209        LOG_SA(WARN) << "AotCompilerService::RegisterThermalMgrListener failed";
210        thermalMgrListener_ = nullptr;
211    } else {
212        LOG_SA(INFO) << "AotCompilerService::RegisterThermalMgrListener success";
213        isThermalLevelEventSubscribered_ = true;
214    }
215}
216
217void AotCompilerService::UnRegisterPowerDisconnectedListener()
218{
219    LOG_SA(DEBUG) << "AotCompilerService::UnRegisterPowerDisconnectedListener";
220    if (!isPowerEventSubscribered_) {
221        return;
222    }
223    if (!EventFwk::CommonEventManager::UnSubscribeCommonEvent(powerDisconnectedListener_)) {
224        LOG_SA(INFO) << "AotCompilerService::UnRegisterPowerDisconnectedListener failed";
225    }
226    powerDisconnectedListener_ = nullptr;
227    isPowerEventSubscribered_ = false;
228    LOG_SA(INFO) << "AotCompilerService::UnRegisterPowerDisconnectedListener done";
229}
230
231void AotCompilerService::UnRegisterScreenStatusSubscriber()
232{
233    LOG_SA(DEBUG) << "AotCompilerService::UnRegisterScreenStatusSubscriber";
234    if (!isScreenStatusSubscribered_) {
235        return;
236    }
237    if (!EventFwk::CommonEventManager::UnSubscribeCommonEvent(screenStatusSubscriber_)) {
238        LOG_SA(WARN) << "AotCompilerService::UnRegisterScreenStatusSubscriber failed";
239    }
240    screenStatusSubscriber_ = nullptr;
241    isScreenStatusSubscribered_ = false;
242    LOG_SA(INFO) << "AotCompilerService::UnRegisterScreenStatusSubscriber done";
243}
244
245void AotCompilerService::UnRegisterThermalMgrListener()
246{
247    LOG_SA(DEBUG) << "AotCompilerService::UnRegisterThermalMgrListener";
248    if (!isThermalLevelEventSubscribered_) {
249        return;
250    }
251    if (!EventFwk::CommonEventManager::UnSubscribeCommonEvent(thermalMgrListener_)) {
252        LOG_SA(WARN) << "AotCompilerService::UnRegisterThermalMgrListener failed";
253    }
254    thermalMgrListener_ = nullptr;
255    isThermalLevelEventSubscribered_ = false;
256    LOG_SA(INFO) << "AotCompilerService::UnRegisterThermalMgrListener done";
257}
258} // namespace OHOS::ArkCompiler