• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_, callbacksSync = callbacksSync_]
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                 jsCallback->CallJsMethodInnerCommon(methodName, ability, nullptr, callbacksSync);
91             }
92         }
93     );
94     NativeReference *callback = nullptr;
95     std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
96     AsyncTask::Schedule("JsAbilityLifecycleCallback::CallJsMethod:" + methodName,
97         *engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
98 }
99 
CallWindowStageJsMethod(const std::string & methodName,const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)100 void JsAbilityLifecycleCallback::CallWindowStageJsMethod(const std::string &methodName,
101     const std::shared_ptr<NativeReference> &ability, const std::shared_ptr<NativeReference> &windowStage)
102 {
103     HILOG_DEBUG("CallWindowStageJsMethod methodName = %{public}s", methodName.c_str());
104     if (!ability || !windowStage) {
105         HILOG_ERROR("ability or windowStage is nullptr");
106         return;
107     }
108     std::weak_ptr<JsAbilityLifecycleCallback> thisWeakPtr(shared_from_this());
109     std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback>(
110         [thisWeakPtr, methodName, ability, windowStage, callbacks = callbacks_, callbacksSync = callbacksSync_]
111         (NativeEngine &engine, AsyncTask &task, int32_t status) {
112             std::shared_ptr<JsAbilityLifecycleCallback> jsCallback = thisWeakPtr.lock();
113             if (jsCallback) {
114                 jsCallback->CallJsMethodInnerCommon(methodName, ability, windowStage, callbacks);
115                 jsCallback->CallJsMethodInnerCommon(methodName, ability, windowStage, callbacksSync);
116             }
117         }
118     );
119     NativeReference *callback = nullptr;
120     std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
121     AsyncTask::Schedule("JsAbilityLifecycleCallback::CallWindowStageJsMethod:" + methodName,
122         *engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
123 }
124 
OnAbilityCreate(const std::shared_ptr<NativeReference> & ability)125 void JsAbilityLifecycleCallback::OnAbilityCreate(const std::shared_ptr<NativeReference> &ability)
126 {
127     CallJsMethod("onAbilityCreate", ability);
128 }
129 
OnWindowStageCreate(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)130 void JsAbilityLifecycleCallback::OnWindowStageCreate(const std::shared_ptr<NativeReference> &ability,
131     const std::shared_ptr<NativeReference> &windowStage)
132 {
133     CallWindowStageJsMethod("onWindowStageCreate", ability, windowStage);
134 }
135 
OnWindowStageDestroy(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)136 void JsAbilityLifecycleCallback::OnWindowStageDestroy(const std::shared_ptr<NativeReference> &ability,
137     const std::shared_ptr<NativeReference> &windowStage)
138 {
139     CallWindowStageJsMethod("onWindowStageDestroy", ability, windowStage);
140 }
141 
OnWindowStageActive(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)142 void JsAbilityLifecycleCallback::OnWindowStageActive(const std::shared_ptr<NativeReference> &ability,
143     const std::shared_ptr<NativeReference> &windowStage)
144 {
145     CallWindowStageJsMethod("onWindowStageActive", ability, windowStage);
146 }
147 
OnWindowStageInactive(const std::shared_ptr<NativeReference> & ability,const std::shared_ptr<NativeReference> & windowStage)148 void JsAbilityLifecycleCallback::OnWindowStageInactive(const std::shared_ptr<NativeReference> &ability,
149     const std::shared_ptr<NativeReference> &windowStage)
150 {
151     CallWindowStageJsMethod("onWindowStageInactive", ability, windowStage);
152 }
153 
OnAbilityDestroy(const std::shared_ptr<NativeReference> & ability)154 void JsAbilityLifecycleCallback::OnAbilityDestroy(const std::shared_ptr<NativeReference> &ability)
155 {
156     CallJsMethod("onAbilityDestroy", ability);
157 }
158 
OnAbilityForeground(const std::shared_ptr<NativeReference> & ability)159 void JsAbilityLifecycleCallback::OnAbilityForeground(const std::shared_ptr<NativeReference> &ability)
160 {
161     CallJsMethod("onAbilityForeground", ability);
162 }
163 
OnAbilityBackground(const std::shared_ptr<NativeReference> & ability)164 void JsAbilityLifecycleCallback::OnAbilityBackground(const std::shared_ptr<NativeReference> &ability)
165 {
166     CallJsMethod("onAbilityBackground", ability);
167 }
168 
OnAbilityContinue(const std::shared_ptr<NativeReference> & ability)169 void JsAbilityLifecycleCallback::OnAbilityContinue(const std::shared_ptr<NativeReference> &ability)
170 {
171     CallJsMethod("onAbilityContinue", ability);
172 }
173 
Register(NativeValue * jsCallback,bool isSync)174 int32_t JsAbilityLifecycleCallback::Register(NativeValue *jsCallback, bool isSync)
175 {
176     if (engine_ == nullptr) {
177         return -1;
178     }
179     int32_t callbackId = serialNumber_;
180     if (serialNumber_ < INT32_MAX) {
181         serialNumber_++;
182     } else {
183         serialNumber_ = 0;
184     }
185     if (isSync) {
186         callbacksSync_.emplace(callbackId, std::shared_ptr<NativeReference>(engine_->CreateReference(jsCallback, 1)));
187     } else {
188         callbacks_.emplace(callbackId, std::shared_ptr<NativeReference>(engine_->CreateReference(jsCallback, 1)));
189     }
190     return callbackId;
191 }
192 
UnRegister(int32_t callbackId,bool isSync)193 bool JsAbilityLifecycleCallback::UnRegister(int32_t callbackId, bool isSync)
194 {
195     HILOG_INFO("UnRegister called, callbackId : %{public}d", callbackId);
196     if (isSync) {
197         auto it = callbacksSync_.find(callbackId);
198         if (it == callbacksSync_.end()) {
199             HILOG_ERROR("UnRegister callbackId: %{public}d is not in callbacksSync_", callbackId);
200             return false;
201         }
202         return callbacksSync_.erase(callbackId) == 1;
203     }
204     auto it = callbacks_.find(callbackId);
205     if (it == callbacks_.end()) {
206         HILOG_ERROR("UnRegister callbackId: %{public}d is not in callbacks_", callbackId);
207         return false;
208     }
209     return callbacks_.erase(callbackId) == 1;
210 }
211 
IsEmpty() const212 bool JsAbilityLifecycleCallback::IsEmpty() const
213 {
214     return callbacks_.empty() && callbacksSync_.empty();
215 }
216 }  // namespace AbilityRuntime
217 }  // namespace OHOS
218