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 #include "js_display_listener.h"
16 #include "js_runtime_utils.h"
17 #include "window_manager_hilog.h"
18 namespace OHOS {
19 namespace Rosen {
20 using namespace AbilityRuntime;
21 namespace {
22 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "JsDisplayListener"};
23 }
24
AddCallback(const std::string & type,NativeValue * jsListenerObject)25 void JsDisplayListener::AddCallback(const std::string& type, NativeValue* jsListenerObject)
26 {
27 WLOGFI("JsDisplayListener::AddCallback is called");
28 std::unique_ptr<NativeReference> callbackRef;
29 if (engine_ == nullptr) {
30 WLOGFE("engine_ nullptr");
31 return;
32 }
33 callbackRef.reset(engine_->CreateReference(jsListenerObject, 1));
34 std::lock_guard<std::mutex> lock(mtx_);
35 jsCallBack_[type].emplace_back(std::move(callbackRef));
36 WLOGFI("JsDisplayListener::AddCallback success jsCallBack_ size: %{public}u!",
37 static_cast<uint32_t>(jsCallBack_[type].size()));
38 }
39
RemoveAllCallback()40 void JsDisplayListener::RemoveAllCallback()
41 {
42 std::lock_guard<std::mutex> lock(mtx_);
43 jsCallBack_.clear();
44 }
45
RemoveCallback(const std::string & type,NativeValue * jsListenerObject)46 void JsDisplayListener::RemoveCallback(const std::string& type, NativeValue* jsListenerObject)
47 {
48 std::lock_guard<std::mutex> lock(mtx_);
49 auto it = jsCallBack_.find(type);
50 if (it == jsCallBack_.end()) {
51 WLOGE("JsDisplayListener::RemoveCallback no callback to remove");
52 return;
53 }
54 auto& listeners = it->second;
55 for (auto iter = listeners.begin(); iter != listeners.end();) {
56 if (jsListenerObject->StrictEquals((*iter)->Get())) {
57 listeners.erase(iter);
58 } else {
59 iter++;
60 }
61 }
62 WLOGFI("JsDisplayListener::RemoveCallback success jsCallBack_ size: %{public}u!",
63 static_cast<uint32_t>(listeners.size()));
64 }
65
CallJsMethod(const std::string & methodName,NativeValue * const * argv,size_t argc)66 void JsDisplayListener::CallJsMethod(const std::string& methodName, NativeValue* const* argv, size_t argc)
67 {
68 if (methodName.empty()) {
69 WLOGFE("empty method name str, call method failed");
70 return;
71 }
72 WLOGFI("CallJsMethod methodName = %{public}s", methodName.c_str());
73 if (engine_ == nullptr) {
74 WLOGFE("engine_ nullptr");
75 return;
76 }
77 for (auto& callback : jsCallBack_[methodName]) {
78 NativeValue* method = callback->Get();
79 if (method == nullptr) {
80 WLOGFE("Failed to get method callback from object");
81 continue;
82 }
83 engine_->CallFunction(engine_->CreateUndefined(), method, argv, argc);
84 }
85 }
86
OnCreate(DisplayId id)87 void JsDisplayListener::OnCreate(DisplayId id)
88 {
89 std::lock_guard<std::mutex> lock(mtx_);
90 WLOGFI("JsDisplayListener::OnCreate is called, displayId: %{public}d", static_cast<uint32_t>(id));
91 if (jsCallBack_.empty()) {
92 WLOGFE("JsDisplayListener::OnCreate not register!");
93 return;
94 }
95 if (jsCallBack_.find(EVENT_ADD) == jsCallBack_.end()) {
96 WLOGE("JsDisplayListener::OnCreate not this event, return");
97 return;
98 }
99
100 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback> (
101 [=] (NativeEngine &engine, AsyncTask &task, int32_t status) {
102 NativeValue* argv[] = {CreateJsValue(*engine_, static_cast<uint32_t>(id))};
103 CallJsMethod(EVENT_ADD, argv, ArraySize(argv));
104 }
105 );
106
107 NativeReference* callback = nullptr;
108 std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
109 AsyncTask::Schedule("JsDisplayListener::OnCreate", *engine_, std::make_unique<AsyncTask>(
110 callback, std::move(execute), std::move(complete)));
111 }
112
OnDestroy(DisplayId id)113 void JsDisplayListener::OnDestroy(DisplayId id)
114 {
115 std::lock_guard<std::mutex> lock(mtx_);
116 WLOGFI("JsDisplayListener::OnDestroy is called, displayId: %{public}d", static_cast<uint32_t>(id));
117 if (jsCallBack_.empty()) {
118 WLOGFE("JsDisplayListener::OnDestroy not register!");
119 return;
120 }
121 if (jsCallBack_.find(EVENT_REMOVE) == jsCallBack_.end()) {
122 WLOGE("JsDisplayListener::OnDestroy not this event, return");
123 return;
124 }
125
126 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback> (
127 [=] (NativeEngine &engine, AsyncTask &task, int32_t status) {
128 NativeValue* argv[] = {CreateJsValue(*engine_, static_cast<uint32_t>(id))};
129 CallJsMethod(EVENT_REMOVE, argv, ArraySize(argv));
130 }
131 );
132
133 NativeReference* callback = nullptr;
134 std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
135 AsyncTask::Schedule("JsDisplayListener::OnDestroy", *engine_, std::make_unique<AsyncTask>(
136 callback, std::move(execute), std::move(complete)));
137 }
138
OnChange(DisplayId id)139 void JsDisplayListener::OnChange(DisplayId id)
140 {
141 std::lock_guard<std::mutex> lock(mtx_);
142 WLOGFI("JsDisplayListener::OnChange is called, displayId: %{public}d", static_cast<uint32_t>(id));
143 if (jsCallBack_.empty()) {
144 WLOGFE("JsDisplayListener::OnChange not register!");
145 return;
146 }
147 if (jsCallBack_.find(EVENT_CHANGE) == jsCallBack_.end()) {
148 WLOGE("JsDisplayListener::OnChange not this event, return");
149 return;
150 }
151
152 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback> (
153 [=] (NativeEngine &engine, AsyncTask &task, int32_t status) {
154 NativeValue* argv[] = {CreateJsValue(*engine_, static_cast<uint32_t>(id))};
155 CallJsMethod(EVENT_CHANGE, argv, ArraySize(argv));
156 }
157 );
158
159 NativeReference* callback = nullptr;
160 std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
161 AsyncTask::Schedule("JsDisplayListener::OnChange", *engine_, std::make_unique<AsyncTask>(
162 callback, std::move(execute), std::move(complete)));
163 }
164 } // namespace Rosen
165 } // namespace OHOS
166