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 "panel_listener_impl.h"
17
18 #include "js_callback_handler.h"
19 #include "js_utils.h"
20
21 namespace OHOS {
22 namespace MiscServices {
23 std::shared_ptr<PanelListenerImpl> PanelListenerImpl::instance_{ nullptr };
24 std::mutex PanelListenerImpl::listenerMutex_;
GetInstance()25 std::shared_ptr<PanelListenerImpl> PanelListenerImpl::GetInstance()
26 {
27 if (instance_ == nullptr) {
28 std::lock_guard<std::mutex> lock(listenerMutex_);
29 if (instance_ == nullptr) {
30 instance_ = std::make_shared<PanelListenerImpl>();
31 }
32 }
33 return instance_;
34 }
35
~PanelListenerImpl()36 PanelListenerImpl::~PanelListenerImpl()
37 {
38 }
39
SaveInfo(napi_env env,const std::string & type,napi_value callback,uint32_t windowId)40 void PanelListenerImpl::SaveInfo(napi_env env, const std::string &type, napi_value callback, uint32_t windowId)
41 {
42 std::shared_ptr<JSCallbackObject> cbObject =
43 std::make_shared<JSCallbackObject>(env, callback, std::this_thread::get_id());
44 auto result = callbacks_.Find(windowId);
45 if (!result.first) {
46 IMSA_HILOGI("start to subscribe, type = %{public}s, windowId = %{public}u", type.c_str(), windowId);
47 ConcurrentMap<std::string, std::shared_ptr<JSCallbackObject>> cbs{};
48 cbs.Insert(type, cbObject);
49 callbacks_.Insert(windowId, cbs);
50 } else {
51 auto res = result.second.Find(type);
52 if (res.first) {
53 IMSA_HILOGD("type: %{public}s of windowId: %{public}u already subscribed", type.c_str(), windowId);
54 return;
55 }
56 IMSA_HILOGI("start to subscribe type: %{public}s of windowId: %{public}u", type.c_str(), windowId);
57 result.second.Insert(type, cbObject);
58 callbacks_.InsertOrAssign(windowId, result.second);
59 }
60 }
61
RemoveInfo(const std::string & type,uint32_t windowId)62 void PanelListenerImpl::RemoveInfo(const std::string &type, uint32_t windowId)
63 {
64 auto result = callbacks_.Find(windowId);
65 if (result.first) {
66 result.second.Erase(type);
67 if (result.second.Empty()) {
68 callbacks_.Erase(windowId);
69 }
70 }
71 }
72
OnPanelStatus(uint32_t windowId,bool isShow)73 void PanelListenerImpl::OnPanelStatus(uint32_t windowId, bool isShow)
74 {
75 std::string type = isShow ? "show" : "hide";
76 IMSA_HILOGI("windowId = %{public}u, type = %{public}s", windowId, type.c_str());
77 uv_work_t *work = new (std::nothrow) uv_work_t;
78 if (work == nullptr) {
79 IMSA_HILOGE("uv_work_t is nullptr!");
80 return;
81 }
82 auto result = callbacks_.Find(windowId);
83 if (!result.first) {
84 IMSA_HILOGE("no callback of windowId = %{public}d!", windowId);
85 return;
86 }
87 auto callback = result.second.Find(type);
88 if (!callback.first) {
89 IMSA_HILOGE("no callback in map!");
90 return;
91 }
92 work->data = new (std::nothrow) UvEntry(callback.second);
93 uv_loop_s *loop = nullptr;
94 napi_get_uv_event_loop(callback.second->env_, &loop);
95 uv_queue_work_with_qos(
96 loop, work, [](uv_work_t *work) {},
97 [](uv_work_t *work, int status) {
98 std::shared_ptr<UvEntry> entry(static_cast<UvEntry *>(work->data), [work](UvEntry *data) {
99 delete data;
100 delete work;
101 });
102 if (entry == nullptr) {
103 IMSA_HILOGE("entry is nullptr");
104 return;
105 }
106 JsCallbackHandler::Traverse({ entry->cbCopy });
107 },
108 uv_qos_user_initiated);
109 }
110 } // namespace MiscServices
111 } // namespace OHOS