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