1 /*
2 * Copyright (c) 2022-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 "ability_lifecycle_callback.h"
17
18 #include "hilog_tag_wrapper.h"
19 #include "js_runtime_utils.h"
20
21 namespace OHOS {
22 namespace AbilityRuntime {
JsAbilityLifecycleCallback(napi_env env)23 JsAbilityLifecycleCallback::JsAbilityLifecycleCallback(napi_env env)
24 : env_(env)
25 {
26 }
27
28 int32_t JsAbilityLifecycleCallback::serialNumber_ = 0;
29
CallJsMethodInnerCommon(const std::string & methodName,const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage,const std::map<int32_t,std::shared_ptr<NativeReference>> callbacks)30 void JsAbilityLifecycleCallback::CallJsMethodInnerCommon(const std::string &methodName,
31 const std::shared_ptr<NativeReference> &ability, const std::shared_ptr<NativeReference> &windowStage,
32 const std::map<int32_t, std::shared_ptr<NativeReference>> callbacks)
33 {
34 auto nativeAbilityObj = CreateJsNull(env_);
35 if (ability != nullptr) {
36 nativeAbilityObj = ability->GetNapiValue();
37 }
38
39 bool isWindowStage = false;
40 auto nativeWindowStageObj = CreateJsNull(env_);
41 if (windowStage != nullptr) {
42 nativeWindowStageObj = windowStage->GetNapiValue();
43 isWindowStage = true;
44 }
45
46 for (auto &callback : callbacks) {
47 if (!callback.second) {
48 TAG_LOGE(AAFwkTag::APPKIT, "Invalid jsCallback");
49 return;
50 }
51
52 auto obj = callback.second->GetNapiValue();
53 if (!CheckTypeForNapiValue(env_, obj, napi_object)) {
54 TAG_LOGE(AAFwkTag::APPKIT, "Failed to get object");
55 return;
56 }
57
58 napi_value method = nullptr;
59 napi_get_named_property(env_, obj, methodName.data(), &method);
60 if (method == nullptr) {
61 TAG_LOGE(AAFwkTag::APPKIT, "Failed to get %{public}s from object",
62 methodName.data());
63 return;
64 }
65
66 if (!isWindowStage) {
67 napi_value argv[] = { nativeAbilityObj };
68 napi_call_function(env_, obj, method, ArraySize(argv), argv, nullptr);
69 } else {
70 napi_value argv[] = { nativeAbilityObj, nativeWindowStageObj };
71 napi_call_function(env_, obj, method, ArraySize(argv), argv, nullptr);
72 }
73 }
74 }
75
CallJsMethod(const std::string & methodName,const std::shared_ptr<NativeReference> & ability)76 void JsAbilityLifecycleCallback::CallJsMethod(
77 const std::string &methodName, const std::shared_ptr<NativeReference> &ability)
78 {
79 TAG_LOGD(AAFwkTag::APPKIT, "methodName = %{public}s", methodName.c_str());
80 if (!ability) {
81 TAG_LOGE(AAFwkTag::APPKIT, "ability is nullptr");
82 return;
83 }
84 HandleScope handleScope(env_);
85 CallJsMethodInnerCommon(methodName, ability, nullptr, callbacks_);
86 CallJsMethodInnerCommon(methodName, ability, nullptr, callbacksSync_);
87 }
88
CallWindowStageJsMethod(const std::string & methodName,const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)89 void JsAbilityLifecycleCallback::CallWindowStageJsMethod(const std::string &methodName,
90 const std::shared_ptr<NativeReference> &ability, const std::shared_ptr<NativeReference> &windowStage)
91 {
92 TAG_LOGD(AAFwkTag::APPKIT, "methodName = %{public}s", methodName.c_str());
93 if (!ability || !windowStage) {
94 TAG_LOGE(AAFwkTag::APPKIT, "ability or windowStage is nullptr");
95 return;
96 }
97 HandleScope handleScope(env_);
98 CallJsMethodInnerCommon(methodName, ability, windowStage, callbacks_);
99 CallJsMethodInnerCommon(methodName, ability, windowStage, callbacksSync_);
100 }
101
OnAbilityCreate(const std::shared_ptr<NativeReference> & ability)102 void JsAbilityLifecycleCallback::OnAbilityCreate(const std::shared_ptr<NativeReference> &ability)
103 {
104 CallJsMethod("onAbilityCreate", ability);
105 }
106
OnWindowStageCreate(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)107 void JsAbilityLifecycleCallback::OnWindowStageCreate(const std::shared_ptr<NativeReference> &ability,
108 const std::shared_ptr<NativeReference> &windowStage)
109 {
110 CallWindowStageJsMethod("onWindowStageCreate", ability, windowStage);
111 }
112
OnWindowStageDestroy(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)113 void JsAbilityLifecycleCallback::OnWindowStageDestroy(const std::shared_ptr<NativeReference> &ability,
114 const std::shared_ptr<NativeReference> &windowStage)
115 {
116 CallWindowStageJsMethod("onWindowStageDestroy", ability, windowStage);
117 }
118
OnWindowStageActive(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)119 void JsAbilityLifecycleCallback::OnWindowStageActive(const std::shared_ptr<NativeReference> &ability,
120 const std::shared_ptr<NativeReference> &windowStage)
121 {
122 CallWindowStageJsMethod("onWindowStageActive", ability, windowStage);
123 }
124
OnWindowStageInactive(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)125 void JsAbilityLifecycleCallback::OnWindowStageInactive(const std::shared_ptr<NativeReference> &ability,
126 const std::shared_ptr<NativeReference> &windowStage)
127 {
128 CallWindowStageJsMethod("onWindowStageInactive", ability, windowStage);
129 }
130
OnAbilityDestroy(const std::shared_ptr<NativeReference> & ability)131 void JsAbilityLifecycleCallback::OnAbilityDestroy(const std::shared_ptr<NativeReference> &ability)
132 {
133 CallJsMethod("onAbilityDestroy", ability);
134 }
135
OnAbilityForeground(const std::shared_ptr<NativeReference> & ability)136 void JsAbilityLifecycleCallback::OnAbilityForeground(const std::shared_ptr<NativeReference> &ability)
137 {
138 CallJsMethod("onAbilityForeground", ability);
139 }
140
OnAbilityBackground(const std::shared_ptr<NativeReference> & ability)141 void JsAbilityLifecycleCallback::OnAbilityBackground(const std::shared_ptr<NativeReference> &ability)
142 {
143 CallJsMethod("onAbilityBackground", ability);
144 }
145
OnAbilityContinue(const std::shared_ptr<NativeReference> & ability)146 void JsAbilityLifecycleCallback::OnAbilityContinue(const std::shared_ptr<NativeReference> &ability)
147 {
148 CallJsMethod("onAbilityContinue", ability);
149 }
150
OnAbilityWillContinue(const std::shared_ptr<NativeReference> & ability)151 void JsAbilityLifecycleCallback::OnAbilityWillContinue(const std::shared_ptr<NativeReference> &ability)
152 {
153 CallJsMethod("onAbilityWillContinue", ability);
154 }
155
OnWindowStageWillRestore(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)156 void JsAbilityLifecycleCallback::OnWindowStageWillRestore(const std::shared_ptr<NativeReference> &ability,
157 const std::shared_ptr<NativeReference> &windowStage)
158 {
159 CallWindowStageJsMethod("onWindowStageWillRestore", ability, windowStage);
160 }
161
OnWindowStageRestore(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)162 void JsAbilityLifecycleCallback::OnWindowStageRestore(const std::shared_ptr<NativeReference> &ability,
163 const std::shared_ptr<NativeReference> &windowStage)
164 {
165 CallWindowStageJsMethod("onWindowStageRestore", ability, windowStage);
166 }
167
OnAbilityWillSaveState(const std::shared_ptr<NativeReference> & ability)168 void JsAbilityLifecycleCallback::OnAbilityWillSaveState(const std::shared_ptr<NativeReference> &ability)
169 {
170 CallJsMethod("onAbilityWillSaveState", ability);
171 }
172
OnAbilitySaveState(const std::shared_ptr<NativeReference> & ability)173 void JsAbilityLifecycleCallback::OnAbilitySaveState(const std::shared_ptr<NativeReference> &ability)
174 {
175 CallJsMethod("onAbilitySaveState", ability);
176 }
177
Register(napi_value jsCallback,bool isSync)178 int32_t JsAbilityLifecycleCallback::Register(napi_value jsCallback, bool isSync)
179 {
180 TAG_LOGD(AAFwkTag::APPKIT, "enter");
181 if (env_ == nullptr) {
182 return -1;
183 }
184 int32_t callbackId = serialNumber_;
185 if (serialNumber_ < INT32_MAX) {
186 serialNumber_++;
187 } else {
188 serialNumber_ = 0;
189 }
190 napi_ref ref = nullptr;
191 napi_create_reference(env_, jsCallback, 1, &ref);
192 if (isSync) {
193 callbacksSync_.emplace(callbackId, std::shared_ptr<NativeReference>(reinterpret_cast<NativeReference*>(ref)));
194 } else {
195 callbacks_.emplace(callbackId, std::shared_ptr<NativeReference>(reinterpret_cast<NativeReference*>(ref)));
196 }
197 return callbackId;
198 }
199
UnRegister(int32_t callbackId,bool isSync)200 bool JsAbilityLifecycleCallback::UnRegister(int32_t callbackId, bool isSync)
201 {
202 TAG_LOGI(AAFwkTag::APPKIT, "callbackId : %{public}d", callbackId);
203 if (isSync) {
204 auto it = callbacksSync_.find(callbackId);
205 if (it == callbacksSync_.end()) {
206 TAG_LOGE(AAFwkTag::APPKIT, "callbackId: %{public}d is not in callbacksSync_", callbackId);
207 return false;
208 }
209 return callbacksSync_.erase(callbackId) == 1;
210 }
211 auto it = callbacks_.find(callbackId);
212 if (it == callbacks_.end()) {
213 TAG_LOGE(AAFwkTag::APPKIT, "callbackId: %{public}d is not in callbacks_", callbackId);
214 return false;
215 }
216 return callbacks_.erase(callbackId) == 1;
217 }
218
OnNewWant(const std::shared_ptr<NativeReference> & ability)219 void JsAbilityLifecycleCallback::OnNewWant(const std::shared_ptr<NativeReference> &ability)
220 {
221 CallJsMethod("onNewWant", ability);
222 }
223
OnWillNewWant(const std::shared_ptr<NativeReference> & ability)224 void JsAbilityLifecycleCallback::OnWillNewWant(const std::shared_ptr<NativeReference> &ability)
225 {
226 CallJsMethod("onWillNewWant", ability);
227 }
228
OnAbilityWillCreate(const std::shared_ptr<NativeReference> & ability)229 void JsAbilityLifecycleCallback::OnAbilityWillCreate(const std::shared_ptr<NativeReference> &ability)
230 {
231 CallJsMethod("onAbilityWillCreate", ability);
232 }
233
OnWindowStageWillCreate(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)234 void JsAbilityLifecycleCallback::OnWindowStageWillCreate(const std::shared_ptr<NativeReference> &ability,
235 const std::shared_ptr<NativeReference> &windowStage)
236 {
237 CallWindowStageJsMethod("onWindowStageWillCreate", ability, windowStage);
238 }
239
OnWindowStageWillDestroy(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)240 void JsAbilityLifecycleCallback::OnWindowStageWillDestroy(const std::shared_ptr<NativeReference> &ability,
241 const std::shared_ptr<NativeReference> &windowStage)
242 {
243 CallWindowStageJsMethod("onWindowStageWillDestroy", ability, windowStage);
244 }
245
OnAbilityWillDestroy(const std::shared_ptr<NativeReference> & ability)246 void JsAbilityLifecycleCallback::OnAbilityWillDestroy(const std::shared_ptr<NativeReference> &ability)
247 {
248 CallJsMethod("onAbilityWillDestroy", ability);
249 }
250
OnAbilityWillForeground(const std::shared_ptr<NativeReference> & ability)251 void JsAbilityLifecycleCallback::OnAbilityWillForeground(const std::shared_ptr<NativeReference> &ability)
252 {
253 CallJsMethod("onAbilityWillForeground", ability);
254 }
255
OnAbilityWillBackground(const std::shared_ptr<NativeReference> & ability)256 void JsAbilityLifecycleCallback::OnAbilityWillBackground(const std::shared_ptr<NativeReference> &ability)
257 {
258 CallJsMethod("onAbilityWillBackground", ability);
259 }
260
IsEmpty() const261 bool JsAbilityLifecycleCallback::IsEmpty() const
262 {
263 return callbacks_.empty() && callbacksSync_.empty();
264 }
265 } // namespace AbilityRuntime
266 } // namespace OHOS
267