1 /*
2 * Copyright (c) 2023 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 "application_state_change_callback.h"
17
18 #include "hilog_wrapper.h"
19 #include "js_data_struct_converter.h"
20 #include "js_runtime_utils.h"
21
22 namespace OHOS {
23 namespace AbilityRuntime {
JsApplicationStateChangeCallback(NativeEngine * engine)24 JsApplicationStateChangeCallback::JsApplicationStateChangeCallback(NativeEngine* engine)
25 : engine_(engine)
26 {
27 }
28
CallJsMethodInnerCommon(const std::string & methodName,const std::set<std::shared_ptr<NativeReference>> callbacks)29 void JsApplicationStateChangeCallback::CallJsMethodInnerCommon(
30 const std::string &methodName, const std::set<std::shared_ptr<NativeReference>> callbacks)
31 {
32 for (auto &callback : callbacks) {
33 if (!callback) {
34 HILOG_ERROR("Invalid jsCallback");
35 continue;
36 }
37
38 auto value = callback->Get();
39 auto obj = ConvertNativeValueTo<NativeObject>(value);
40 if (obj == nullptr) {
41 HILOG_ERROR("Failed to get object");
42 continue;
43 }
44
45 auto method = obj->GetProperty(methodName.data());
46 if (method == nullptr) {
47 HILOG_ERROR("Failed to get %{public}s from object", methodName.data());
48 continue;
49 }
50 engine_->CallFunction(value, method, nullptr, 0);
51 }
52 }
53
CallJsMethod(const std::string & methodName)54 void JsApplicationStateChangeCallback::CallJsMethod(const std::string &methodName)
55 {
56 HILOG_DEBUG("MethodName = %{public}s", methodName.c_str());
57 std::weak_ptr<JsApplicationStateChangeCallback> thisWeakPtr(shared_from_this());
58 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback>(
59 [thisWeakPtr, methodName, callbacks = callbacks_]
60 (NativeEngine &engine, AsyncTask &task, int32_t status) {
61 std::shared_ptr<JsApplicationStateChangeCallback> jsCallback = thisWeakPtr.lock();
62 if (jsCallback) {
63 jsCallback->CallJsMethodInnerCommon(methodName, callbacks);
64 }
65 }
66 );
67 NativeReference *callback = nullptr;
68 std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
69 AsyncTask::Schedule("JsApplicationStateChangeCallback::CallJsMethod:" + methodName,
70 *engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
71 }
72
NotifyApplicationForeground()73 void JsApplicationStateChangeCallback::NotifyApplicationForeground()
74 {
75 CallJsMethod("onApplicationForeground");
76 }
77
NotifyApplicationBackground()78 void JsApplicationStateChangeCallback::NotifyApplicationBackground()
79 {
80 CallJsMethod("onApplicationBackground");
81 }
82
Register(NativeValue * jsCallback)83 void JsApplicationStateChangeCallback::Register(NativeValue *jsCallback)
84 {
85 if (engine_ == nullptr || jsCallback == nullptr) {
86 HILOG_ERROR("Engine or jsCallback is nullptr");
87 return;
88 }
89 callbacks_.emplace(std::shared_ptr<NativeReference>(engine_->CreateReference(jsCallback, 1)));
90 }
91
UnRegister(NativeValue * jsCallback)92 bool JsApplicationStateChangeCallback::UnRegister(NativeValue *jsCallback)
93 {
94 if (jsCallback == nullptr) {
95 HILOG_INFO("jsCallback is nullptr, delete all callback.");
96 callbacks_.clear();
97 return true;
98 }
99
100 for (auto &callback : callbacks_) {
101 if (!callback) {
102 HILOG_ERROR("Invalid jsCallback");
103 continue;
104 }
105
106 NativeValue *value = callback->Get();
107 if (value == nullptr) {
108 HILOG_ERROR("Failed to get object");
109 continue;
110 }
111
112 if (value->StrictEquals(jsCallback)) {
113 return callbacks_.erase(callback) == 1;
114 }
115 }
116 return false;
117 }
118
IsEmpty() const119 bool JsApplicationStateChangeCallback::IsEmpty() const
120 {
121 return callbacks_.empty();
122 }
123 } // namespace AbilityRuntime
124 } // namespace OHOS