1 /*
2 * Copyright (c) 2022 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_wrapper.h"
19 #include "js_runtime_utils.h"
20
21 namespace OHOS {
22 namespace AbilityRuntime {
JsAbilityLifecycleCallback(NativeEngine * engine)23 JsAbilityLifecycleCallback::JsAbilityLifecycleCallback(NativeEngine* engine)
24 : engine_(engine)
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 = engine_->CreateNull();
35 if (ability != nullptr) {
36 nativeAbilityObj = ability->Get();
37 }
38
39 bool isWindowStage = false;
40 auto nativeWindowStageObj = engine_->CreateNull();
41 if (windowStage != nullptr) {
42 nativeWindowStageObj = windowStage->Get();
43 isWindowStage = true;
44 }
45
46 for (auto &callback : callbacks) {
47 if (!callback.second) {
48 HILOG_ERROR("CallJsMethodInnerCommon, Invalid jsCallback");
49 return;
50 }
51
52 auto value = callback.second->Get();
53 auto obj = ConvertNativeValueTo<NativeObject>(value);
54 if (obj == nullptr) {
55 HILOG_ERROR("CallJsMethodInnerCommon, Failed to get object");
56 return;
57 }
58
59 auto method = obj->GetProperty(methodName.data());
60 if (method == nullptr) {
61 HILOG_ERROR("CallJsMethodInnerCommon, Failed to get %{public}s from object", methodName.data());
62 return;
63 }
64
65 if (!isWindowStage) {
66 NativeValue *argv[] = { nativeAbilityObj };
67 engine_->CallFunction(value, method, argv, ArraySize(argv));
68 } else {
69 NativeValue *argv[] = { nativeAbilityObj, nativeWindowStageObj };
70 engine_->CallFunction(value, method, argv, ArraySize(argv));
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 HILOG_DEBUG("CallJsMethod methodName = %{public}s", methodName.c_str());
79 if (!ability) {
80 HILOG_ERROR("ability is nullptr");
81 return;
82 }
83 std::weak_ptr<JsAbilityLifecycleCallback> thisWeakPtr(shared_from_this());
84 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback>(
85 [thisWeakPtr, methodName, ability, callbacks = callbacks_]
86 (NativeEngine &engine, AsyncTask &task, int32_t status) {
87 std::shared_ptr<JsAbilityLifecycleCallback> jsCallback = thisWeakPtr.lock();
88 if (jsCallback) {
89 jsCallback->CallJsMethodInnerCommon(methodName, ability, nullptr, callbacks);
90 }
91 }
92 );
93 NativeReference *callback = nullptr;
94 std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
95 AsyncTask::Schedule("JsAbilityLifecycleCallback::CallJsMethod:" + methodName,
96 *engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
97 }
98
CallWindowStageJsMethod(const std::string & methodName,const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)99 void JsAbilityLifecycleCallback::CallWindowStageJsMethod(const std::string &methodName,
100 const std::shared_ptr<NativeReference> &ability, const std::shared_ptr<NativeReference> &windowStage)
101 {
102 HILOG_DEBUG("CallWindowStageJsMethod methodName = %{public}s", methodName.c_str());
103 if (!ability || !windowStage) {
104 HILOG_ERROR("ability or windowStage is nullptr");
105 return;
106 }
107 std::weak_ptr<JsAbilityLifecycleCallback> thisWeakPtr(shared_from_this());
108 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback>(
109 [thisWeakPtr, methodName, ability, windowStage, callbacks = callbacks_]
110 (NativeEngine &engine, AsyncTask &task, int32_t status) {
111 std::shared_ptr<JsAbilityLifecycleCallback> jsCallback = thisWeakPtr.lock();
112 if (jsCallback) {
113 jsCallback->CallJsMethodInnerCommon(methodName, ability, windowStage, callbacks);
114 }
115 }
116 );
117 NativeReference *callback = nullptr;
118 std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
119 AsyncTask::Schedule("JsAbilityLifecycleCallback::CallWindowStageJsMethod:" + methodName,
120 *engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
121 }
122
OnAbilityCreate(const std::shared_ptr<NativeReference> & ability)123 void JsAbilityLifecycleCallback::OnAbilityCreate(const std::shared_ptr<NativeReference> &ability)
124 {
125 CallJsMethod("onAbilityCreate", ability);
126 }
127
OnWindowStageCreate(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)128 void JsAbilityLifecycleCallback::OnWindowStageCreate(const std::shared_ptr<NativeReference> &ability,
129 const std::shared_ptr<NativeReference> &windowStage)
130 {
131 CallWindowStageJsMethod("onWindowStageCreate", ability, windowStage);
132 }
133
OnWindowStageDestroy(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)134 void JsAbilityLifecycleCallback::OnWindowStageDestroy(const std::shared_ptr<NativeReference> &ability,
135 const std::shared_ptr<NativeReference> &windowStage)
136 {
137 CallWindowStageJsMethod("onWindowStageDestroy", ability, windowStage);
138 }
139
OnWindowStageActive(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)140 void JsAbilityLifecycleCallback::OnWindowStageActive(const std::shared_ptr<NativeReference> &ability,
141 const std::shared_ptr<NativeReference> &windowStage)
142 {
143 CallWindowStageJsMethod("onWindowStageActive", ability, windowStage);
144 }
145
OnWindowStageInactive(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)146 void JsAbilityLifecycleCallback::OnWindowStageInactive(const std::shared_ptr<NativeReference> &ability,
147 const std::shared_ptr<NativeReference> &windowStage)
148 {
149 CallWindowStageJsMethod("onWindowStageInactive", ability, windowStage);
150 }
151
OnAbilityDestroy(const std::shared_ptr<NativeReference> & ability)152 void JsAbilityLifecycleCallback::OnAbilityDestroy(const std::shared_ptr<NativeReference> &ability)
153 {
154 CallJsMethod("onAbilityDestroy", ability);
155 }
156
OnAbilityForeground(const std::shared_ptr<NativeReference> & ability)157 void JsAbilityLifecycleCallback::OnAbilityForeground(const std::shared_ptr<NativeReference> &ability)
158 {
159 CallJsMethod("onAbilityForeground", ability);
160 }
161
OnAbilityBackground(const std::shared_ptr<NativeReference> & ability)162 void JsAbilityLifecycleCallback::OnAbilityBackground(const std::shared_ptr<NativeReference> &ability)
163 {
164 CallJsMethod("onAbilityBackground", ability);
165 }
166
OnAbilityContinue(const std::shared_ptr<NativeReference> & ability)167 void JsAbilityLifecycleCallback::OnAbilityContinue(const std::shared_ptr<NativeReference> &ability)
168 {
169 CallJsMethod("onAbilityContinue", ability);
170 }
171
Register(NativeValue * jsCallback)172 int32_t JsAbilityLifecycleCallback::Register(NativeValue *jsCallback)
173 {
174 if (engine_ == nullptr) {
175 return -1;
176 }
177 int32_t callbackId = serialNumber_;
178 if (serialNumber_ < INT32_MAX) {
179 serialNumber_++;
180 } else {
181 serialNumber_ = 0;
182 }
183 callbacks_.emplace(callbackId, std::shared_ptr<NativeReference>(engine_->CreateReference(jsCallback, 1)));
184 return callbackId;
185 }
186
UnRegister(int32_t callbackId)187 bool JsAbilityLifecycleCallback::UnRegister(int32_t callbackId)
188 {
189 HILOG_INFO("UnRegister called, callbackId : %{public}d", callbackId);
190 auto it = callbacks_.find(callbackId);
191 if (it == callbacks_.end()) {
192 HILOG_ERROR("UnRegister callbackId: %{public}d is not in callbacks_", callbackId);
193 return false;
194 }
195 return callbacks_.erase(callbackId) == 1;
196 }
197
IsEmpty() const198 bool JsAbilityLifecycleCallback::IsEmpty() const
199 {
200 return callbacks_.empty();
201 }
202 } // namespace AbilityRuntime
203 } // namespace OHOS
204