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, "get object failed");
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, "null method %{public}s", methodName.data());
62 return;
63 }
64
65 if (!isWindowStage) {
66 napi_value argv[] = { nativeAbilityObj };
67 napi_call_function(env_, obj, method, ArraySize(argv), argv, nullptr);
68 } else {
69 napi_value argv[] = { nativeAbilityObj, nativeWindowStageObj };
70 napi_call_function(env_, obj, method, ArraySize(argv), argv, nullptr);
71 }
72 }
73 }
74
CallJsMethod(const std::string & methodName,const std::shared_ptr<NativeReference> & ability)75 void JsAbilityLifecycleCallback::CallJsMethod(
76 const std::string &methodName, const std::shared_ptr<NativeReference> &ability)
77 {
78 TAG_LOGD(AAFwkTag::APPKIT, "methodName = %{public}s", methodName.c_str());
79 if (!ability) {
80 TAG_LOGE(AAFwkTag::APPKIT, "null ability");
81 return;
82 }
83 HandleScope handleScope(env_);
84 CallJsMethodInnerCommon(methodName, ability, nullptr, callbacks_);
85 CallJsMethodInnerCommon(methodName, ability, nullptr, callbacksSync_);
86 }
87
CallWindowStageJsMethod(const std::string & methodName,const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)88 void JsAbilityLifecycleCallback::CallWindowStageJsMethod(const std::string &methodName,
89 const std::shared_ptr<NativeReference> &ability, const std::shared_ptr<NativeReference> &windowStage)
90 {
91 TAG_LOGD(AAFwkTag::APPKIT, "methodName = %{public}s", methodName.c_str());
92 if (!ability || !windowStage) {
93 TAG_LOGE(AAFwkTag::APPKIT, "null ability or windowStage");
94 return;
95 }
96 HandleScope handleScope(env_);
97 CallJsMethodInnerCommon(methodName, ability, windowStage, callbacks_);
98 CallJsMethodInnerCommon(methodName, ability, windowStage, callbacksSync_);
99 }
100
OnAbilityCreate(const std::shared_ptr<NativeReference> & ability)101 void JsAbilityLifecycleCallback::OnAbilityCreate(const std::shared_ptr<NativeReference> &ability)
102 {
103 CallJsMethod("onAbilityCreate", ability);
104 }
105
OnWindowStageCreate(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)106 void JsAbilityLifecycleCallback::OnWindowStageCreate(const std::shared_ptr<NativeReference> &ability,
107 const std::shared_ptr<NativeReference> &windowStage)
108 {
109 CallWindowStageJsMethod("onWindowStageCreate", ability, windowStage);
110 }
111
OnWindowStageDestroy(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)112 void JsAbilityLifecycleCallback::OnWindowStageDestroy(const std::shared_ptr<NativeReference> &ability,
113 const std::shared_ptr<NativeReference> &windowStage)
114 {
115 CallWindowStageJsMethod("onWindowStageDestroy", ability, windowStage);
116 }
117
OnWindowStageActive(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)118 void JsAbilityLifecycleCallback::OnWindowStageActive(const std::shared_ptr<NativeReference> &ability,
119 const std::shared_ptr<NativeReference> &windowStage)
120 {
121 CallWindowStageJsMethod("onWindowStageActive", ability, windowStage);
122 }
123
OnWindowStageInactive(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)124 void JsAbilityLifecycleCallback::OnWindowStageInactive(const std::shared_ptr<NativeReference> &ability,
125 const std::shared_ptr<NativeReference> &windowStage)
126 {
127 CallWindowStageJsMethod("onWindowStageInactive", ability, windowStage);
128 }
129
OnAbilityDestroy(const std::shared_ptr<NativeReference> & ability)130 void JsAbilityLifecycleCallback::OnAbilityDestroy(const std::shared_ptr<NativeReference> &ability)
131 {
132 CallJsMethod("onAbilityDestroy", ability);
133 }
134
OnAbilityForeground(const std::shared_ptr<NativeReference> & ability)135 void JsAbilityLifecycleCallback::OnAbilityForeground(const std::shared_ptr<NativeReference> &ability)
136 {
137 CallJsMethod("onAbilityForeground", ability);
138 }
139
OnAbilityBackground(const std::shared_ptr<NativeReference> & ability)140 void JsAbilityLifecycleCallback::OnAbilityBackground(const std::shared_ptr<NativeReference> &ability)
141 {
142 CallJsMethod("onAbilityBackground", ability);
143 }
144
OnAbilityContinue(const std::shared_ptr<NativeReference> & ability)145 void JsAbilityLifecycleCallback::OnAbilityContinue(const std::shared_ptr<NativeReference> &ability)
146 {
147 CallJsMethod("onAbilityContinue", ability);
148 }
149
OnAbilityWillContinue(const std::shared_ptr<NativeReference> & ability)150 void JsAbilityLifecycleCallback::OnAbilityWillContinue(const std::shared_ptr<NativeReference> &ability)
151 {
152 CallJsMethod("onAbilityWillContinue", ability);
153 }
154
OnWindowStageWillRestore(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)155 void JsAbilityLifecycleCallback::OnWindowStageWillRestore(const std::shared_ptr<NativeReference> &ability,
156 const std::shared_ptr<NativeReference> &windowStage)
157 {
158 CallWindowStageJsMethod("onWindowStageWillRestore", ability, windowStage);
159 }
160
OnWindowStageRestore(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)161 void JsAbilityLifecycleCallback::OnWindowStageRestore(const std::shared_ptr<NativeReference> &ability,
162 const std::shared_ptr<NativeReference> &windowStage)
163 {
164 CallWindowStageJsMethod("onWindowStageRestore", ability, windowStage);
165 }
166
OnAbilityWillSaveState(const std::shared_ptr<NativeReference> & ability)167 void JsAbilityLifecycleCallback::OnAbilityWillSaveState(const std::shared_ptr<NativeReference> &ability)
168 {
169 CallJsMethod("onAbilityWillSaveState", ability);
170 }
171
OnAbilitySaveState(const std::shared_ptr<NativeReference> & ability)172 void JsAbilityLifecycleCallback::OnAbilitySaveState(const std::shared_ptr<NativeReference> &ability)
173 {
174 CallJsMethod("onAbilitySaveState", ability);
175 }
176
Register(napi_value jsCallback,bool isSync)177 int32_t JsAbilityLifecycleCallback::Register(napi_value jsCallback, bool isSync)
178 {
179 TAG_LOGD(AAFwkTag::APPKIT, "enter");
180 if (env_ == nullptr) {
181 return -1;
182 }
183 int32_t callbackId = serialNumber_;
184 if (serialNumber_ < INT32_MAX) {
185 serialNumber_++;
186 } else {
187 serialNumber_ = 0;
188 }
189 napi_ref ref = nullptr;
190 napi_create_reference(env_, jsCallback, 1, &ref);
191 if (isSync) {
192 callbacksSync_.emplace(callbackId, std::shared_ptr<NativeReference>(reinterpret_cast<NativeReference*>(ref)));
193 } else {
194 callbacks_.emplace(callbackId, std::shared_ptr<NativeReference>(reinterpret_cast<NativeReference*>(ref)));
195 }
196 return callbackId;
197 }
198
UnRegister(int32_t callbackId,bool isSync)199 bool JsAbilityLifecycleCallback::UnRegister(int32_t callbackId, bool isSync)
200 {
201 TAG_LOGI(AAFwkTag::APPKIT, "callbackId : %{public}d", callbackId);
202 if (isSync) {
203 auto it = callbacksSync_.find(callbackId);
204 if (it == callbacksSync_.end()) {
205 TAG_LOGE(AAFwkTag::APPKIT, "%{public}d not in callbacksSync_", callbackId);
206 return false;
207 }
208 return callbacksSync_.erase(callbackId) == 1;
209 }
210 auto it = callbacks_.find(callbackId);
211 if (it == callbacks_.end()) {
212 TAG_LOGE(AAFwkTag::APPKIT, "%{public}d not in callbacks_", callbackId);
213 return false;
214 }
215 return callbacks_.erase(callbackId) == 1;
216 }
217
OnNewWant(const std::shared_ptr<NativeReference> & ability)218 void JsAbilityLifecycleCallback::OnNewWant(const std::shared_ptr<NativeReference> &ability)
219 {
220 CallJsMethod("onNewWant", ability);
221 }
222
OnWillNewWant(const std::shared_ptr<NativeReference> & ability)223 void JsAbilityLifecycleCallback::OnWillNewWant(const std::shared_ptr<NativeReference> &ability)
224 {
225 CallJsMethod("onWillNewWant", ability);
226 }
227
OnAbilityWillCreate(const std::shared_ptr<NativeReference> & ability)228 void JsAbilityLifecycleCallback::OnAbilityWillCreate(const std::shared_ptr<NativeReference> &ability)
229 {
230 CallJsMethod("onAbilityWillCreate", ability);
231 }
232
OnWindowStageWillCreate(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)233 void JsAbilityLifecycleCallback::OnWindowStageWillCreate(const std::shared_ptr<NativeReference> &ability,
234 const std::shared_ptr<NativeReference> &windowStage)
235 {
236 CallWindowStageJsMethod("onWindowStageWillCreate", ability, windowStage);
237 }
238
OnWindowStageWillDestroy(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)239 void JsAbilityLifecycleCallback::OnWindowStageWillDestroy(const std::shared_ptr<NativeReference> &ability,
240 const std::shared_ptr<NativeReference> &windowStage)
241 {
242 CallWindowStageJsMethod("onWindowStageWillDestroy", ability, windowStage);
243 }
244
OnAbilityWillDestroy(const std::shared_ptr<NativeReference> & ability)245 void JsAbilityLifecycleCallback::OnAbilityWillDestroy(const std::shared_ptr<NativeReference> &ability)
246 {
247 CallJsMethod("onAbilityWillDestroy", ability);
248 }
249
OnAbilityWillForeground(const std::shared_ptr<NativeReference> & ability)250 void JsAbilityLifecycleCallback::OnAbilityWillForeground(const std::shared_ptr<NativeReference> &ability)
251 {
252 CallJsMethod("onAbilityWillForeground", ability);
253 }
254
OnAbilityWillBackground(const std::shared_ptr<NativeReference> & ability)255 void JsAbilityLifecycleCallback::OnAbilityWillBackground(const std::shared_ptr<NativeReference> &ability)
256 {
257 CallJsMethod("onAbilityWillBackground", ability);
258 }
259
IsEmpty() const260 bool JsAbilityLifecycleCallback::IsEmpty() const
261 {
262 return callbacks_.empty() && callbacksSync_.empty();
263 }
264
OnWillForeground(const std::shared_ptr<NativeReference> & ability)265 void JsAbilityLifecycleCallback::OnWillForeground(const std::shared_ptr<NativeReference> &ability)
266 {
267 CallJsMethod("onWillForeground", ability);
268 }
269
OnDidForeground(const std::shared_ptr<NativeReference> & ability)270 void JsAbilityLifecycleCallback::OnDidForeground(const std::shared_ptr<NativeReference> &ability)
271 {
272 CallJsMethod("onDidForeground", ability);
273 }
274
OnWillBackground(const std::shared_ptr<NativeReference> & ability)275 void JsAbilityLifecycleCallback::OnWillBackground(const std::shared_ptr<NativeReference> &ability)
276 {
277 CallJsMethod("onWillBackground", ability);
278 }
279
OnDidBackground(const std::shared_ptr<NativeReference> & ability)280 void JsAbilityLifecycleCallback::OnDidBackground(const std::shared_ptr<NativeReference> &ability)
281 {
282 CallJsMethod("onDidBackground", ability);
283 }
284 } // namespace AbilityRuntime
285 } // namespace OHOS
286