• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 
16 #include "js_input_monitor_manager.h"
17 #include <uv.h>
18 #include "define_multimodal.h"
19 
20 namespace OHOS {
21 namespace MMI {
22 namespace {
23     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, MMI_LOG_DOMAIN, "JsInputMonitorManager" };
24 }
25 
~JsInputMonitorManager()26 JsInputMonitorManager::~JsInputMonitorManager()
27 {
28     for (const auto &item : monitors_) {
29         item->Stop();
30     }
31     monitors_.clear();
32     RemoveAllEnv();
33 }
34 
GetInstance()35 JsInputMonitorManager& JsInputMonitorManager::GetInstance()
36 {
37     static JsInputMonitorManager instance;
38     return instance;
39 }
40 
AddMonitor(napi_env jsEnv,napi_value receiver)41 void JsInputMonitorManager::AddMonitor(napi_env jsEnv, napi_value receiver)
42 {
43     MMI_LOGD("Enter");
44     std::lock_guard<std::mutex> guard(mutex_);
45     for (auto& item : monitors_) {
46         if (item->IsMatch(jsEnv, receiver) != RET_ERR) {
47             return;
48         }
49     }
50     std::shared_ptr<JsInputMonitor> monitor = std::make_shared<JsInputMonitor>(jsEnv, receiver, nextId_++);
51     monitors_.push_back(monitor);
52     if (!monitor->Start()) {
53         monitors_.pop_back();
54     }
55     MMI_LOGD("Leave");
56 }
57 
RemoveMonitor(napi_env jsEnv,napi_value receiver)58 void JsInputMonitorManager::RemoveMonitor(napi_env jsEnv, napi_value receiver)
59 {
60     MMI_LOGD("Enter");
61     std::shared_ptr<JsInputMonitor> monitor = nullptr;
62     {
63         std::lock_guard<std::mutex> guard(mutex_);
64         for (auto it = monitors_.begin(); it != monitors_.end(); ++it) {
65             if ((*it)->IsMatch(jsEnv, receiver) == RET_OK) {
66                 monitor = *it;
67                 monitors_.erase(it);
68                 MMI_LOGD("Found monitor");
69                 break;
70             }
71         }
72     }
73     if (monitor != nullptr) {
74         monitor->Stop();
75     }
76     MMI_LOGD("Leave");
77 }
78 
RemoveMonitor(napi_env jsEnv)79 void JsInputMonitorManager::RemoveMonitor(napi_env jsEnv)
80 {
81     MMI_LOGD("Enter");
82     std::list<std::shared_ptr<JsInputMonitor>> monitors;
83     {
84         std::lock_guard<std::mutex> guard(mutex_);
85         for (auto it = monitors_.begin(); it != monitors_.end();) {
86             if ((*it)->IsMatch(jsEnv) == RET_OK) {
87                 monitors.push_back(*it);
88                 monitors_.erase(it++);
89                 continue;
90             }
91             ++it;
92         }
93     }
94     for (const auto &item : monitors) {
95         item->Stop();
96     }
97     MMI_LOGD("Leave");
98 }
99 
GetMonitor(int32_t id)100 std::shared_ptr<JsInputMonitor> JsInputMonitorManager::GetMonitor(int32_t id) {
101     MMI_LOGD("Enter");
102     std::lock_guard<std::mutex> guard(mutex_);
103     for (auto &item : monitors_) {
104         if (item->GetId() == id) {
105             MMI_LOGD("Leave");
106             return item;
107         }
108     }
109     MMI_LOGD("No monitor found");
110     return nullptr;
111 }
112 
AddEnv(napi_env env,napi_callback_info cbInfo)113 bool JsInputMonitorManager::AddEnv(napi_env env, napi_callback_info cbInfo)
114 {
115     MMI_LOGD("Enter");
116     if (IsExisting(env)) {
117         MMI_LOGD("Env is already exists");
118         return true;
119     }
120     napi_value thisVar = nullptr;
121     void *data = nullptr;
122     int32_t *id = new int32_t;
123     *id = 0;
124     napi_get_cb_info(env, cbInfo, nullptr, nullptr, &thisVar, &data);
125     auto status = napi_wrap(env, thisVar, static_cast<void*>(id),
126                             [](napi_env env, void *data, void *hint) {
127                                 MMI_LOGD("napi_wrap enter");
128                                 int32_t *id = static_cast<int32_t *>(data);
129                                 delete id;
130                                 id = nullptr;
131                                 JSIMM.RemoveMonitor(env);
132                                 JSIMM.RemoveEnv(env);
133                                 MMI_LOGD("napi_wrap leave");
134                                 }, nullptr, nullptr);
135     if (status != napi_ok) {
136         MMI_LOGE("napi_wrap failed");
137         delete id;
138         return false;
139     }
140     napi_ref ref = nullptr;
141     status = napi_create_reference(env, thisVar, 1, &ref);
142     if (status != napi_ok) {
143         MMI_LOGE("napi_create_reference failed");
144         delete id;
145         return false;
146     }
147     envManager_.insert(std::pair<napi_env, napi_ref>(env, ref));
148     MMI_LOGD("Leave");
149     return true;
150 }
151 
RemoveEnv(napi_env env)152 void JsInputMonitorManager::RemoveEnv(napi_env env)
153 {
154     MMI_LOGD("Enter");
155     auto it = envManager_.find(env);
156     if (it == envManager_.end()) {
157         MMI_LOGD("No env found");
158         return;
159     }
160     RemoveEnv(it);
161     MMI_LOGD("Leave");
162 }
163 
RemoveEnv(std::map<napi_env,napi_ref>::iterator it)164 void JsInputMonitorManager::RemoveEnv(std::map<napi_env, napi_ref>::iterator it)
165 {
166     MMI_LOGD("Enter");
167     uint32_t refCount;
168     auto status = napi_reference_unref(it->first, it->second, &refCount);
169     if (status != napi_ok) {
170         MMI_LOGE("napi_reference_unref failed");
171         return;
172     }
173     envManager_.erase(it);
174     MMI_LOGD("Leave");
175 }
176 
RemoveAllEnv()177 void JsInputMonitorManager::RemoveAllEnv()
178 {
179     MMI_LOGD("Enter");
180     for (auto it = envManager_.begin(); it != envManager_.end();) {
181         RemoveEnv(it++);
182     }
183     MMI_LOGD("Leave");
184 }
185 
IsExisting(napi_env env)186 bool JsInputMonitorManager::IsExisting(napi_env env)
187 {
188     MMI_LOGD("Enter");
189     auto it = envManager_.find(env);
190     if (it == envManager_.end()) {
191         MMI_LOGD("No env found");
192         return false;
193     }
194     MMI_LOGD("Leave");
195     return true;
196 }
197 } // namespace MMI
198 } // namespace OHOS
199