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 WLOGI("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 WLOGI("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 WLOGI("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 WLOGI("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 WLOGI("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 sptr<JsDisplayListener> listener = this; // Avoid this be destroyed when using.
100 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback> (
101 [this, listener, id] (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 WLOGI("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 sptr<JsDisplayListener> listener = this; // Avoid this be destroyed when using.
126 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback> (
127 [this, listener, id] (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 WLOGI("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 sptr<JsDisplayListener> listener = this; // Avoid this be destroyed when using.
152 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback> (
153 [this, listener, id] (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
OnPrivateWindow(bool hasPrivate)165 void JsDisplayListener::OnPrivateWindow(bool hasPrivate)
166 {
167 std::lock_guard<std::mutex> lock(mtx_);
168 WLOGI("OnPrivateWindow is called, private status: %{public}u", static_cast<uint32_t>(hasPrivate));
169 if (jsCallBack_.empty()) {
170 WLOGFE("OnPrivateWindow not register!");
171 return;
172 }
173 if (jsCallBack_.find(EVENT_PRIVATE_MODE_CHANGE) == jsCallBack_.end()) {
174 WLOGE("OnPrivateWindow not this event, return");
175 return;
176 }
177 sptr<JsDisplayListener> listener = this; // Avoid this be destroyed when using.
178 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback> (
179 [this, listener, hasPrivate] (NativeEngine &engine, AsyncTask &task, int32_t status) {
180 NativeValue* argv[] = {CreateJsValue(*engine_, hasPrivate)};
181 CallJsMethod(EVENT_PRIVATE_MODE_CHANGE, argv, ArraySize(argv));
182 }
183 );
184
185 NativeReference* callback = nullptr;
186 std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
187 AsyncTask::Schedule("JsDisplayListener::OnPrivateWindow", *engine_, std::make_unique<AsyncTask>(
188 callback, std::move(execute), std::move(complete)));
189 }
190
OnFoldStatusChanged(FoldStatus foldStatus)191 void JsDisplayListener::OnFoldStatusChanged(FoldStatus foldStatus)
192 {
193 std::lock_guard<std::mutex> lock(mtx_);
194 WLOGI("OnFoldStatusChanged is called, foldStatus: %{public}u", static_cast<uint32_t>(foldStatus));
195 if (jsCallBack_.empty()) {
196 WLOGFE("OnFoldStatusChanged not register!");
197 return;
198 }
199 if (jsCallBack_.find(EVENT_FOLD_STATUS_CHANGED) == jsCallBack_.end()) {
200 WLOGE("OnFoldStatusChanged not this event, return");
201 return;
202 }
203 sptr<JsDisplayListener> listener = this; // Avoid this be destroyed when using.
204 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback> (
205 [this, listener, foldStatus] (NativeEngine &engine, AsyncTask &task, int32_t status) {
206 NativeValue* argv[] = {CreateJsValue(*engine_, foldStatus)};
207 CallJsMethod(EVENT_FOLD_STATUS_CHANGED, argv, ArraySize(argv));
208 }
209 );
210
211 NativeReference* callback = nullptr;
212 std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
213 AsyncTask::Schedule("JsDisplayListener::OnFoldStatusChanged", *engine_, std::make_unique<AsyncTask>(
214 callback, std::move(execute), std::move(complete)));
215 }
216
OnDisplayModeChanged(FoldDisplayMode displayMode)217 void JsDisplayListener::OnDisplayModeChanged(FoldDisplayMode displayMode)
218 {
219 std::lock_guard<std::mutex> lock(mtx_);
220 WLOGI("OnDisplayModeChanged is called, displayMode: %{public}u", static_cast<uint32_t>(displayMode));
221 if (jsCallBack_.empty()) {
222 WLOGFE("OnDisplayModeChanged not register!");
223 return;
224 }
225 if (jsCallBack_.find(EVENT_DISPLAY_MODE_CHANGED) == jsCallBack_.end()) {
226 WLOGE("OnDisplayModeChanged not this event, return");
227 return;
228 }
229 sptr<JsDisplayListener> listener = this; // Avoid this be destroyed when using.
230 std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback> (
231 [this, listener, displayMode] (NativeEngine &engine, AsyncTask &task, int32_t status) {
232 NativeValue* argv[] = {CreateJsValue(*engine_, displayMode)};
233 CallJsMethod(EVENT_DISPLAY_MODE_CHANGED, argv, ArraySize(argv));
234 }
235 );
236
237 NativeReference* callback = nullptr;
238 std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
239 AsyncTask::Schedule("JsDisplayListener::OnDisplayModeChanged", *engine_, std::make_unique<AsyncTask>(
240 callback, std::move(execute), std::move(complete)));
241 }
242 } // namespace Rosen
243 } // namespace OHOS
244