• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_input_method_engine_listener.h"
16 #include "global.h"
17 #include "js_runtime_utils.h"
18 #include "js_input_method_engine_utils.h"
19 
20 namespace OHOS {
21 namespace MiscServices {
22     using namespace AbilityRuntime;
RegisterListenerWithType(NativeEngine & engine,std::string type,NativeValue * value)23     void JsInputMethodEngineListener::RegisterListenerWithType(NativeEngine& engine,
24                                                                std::string type, NativeValue* value)
25     {
26         // should do type check
27         if (IfCallbackRegistered(type, value)) {
28             IMSA_HILOGI("JsInputMethodEngineListener::RegisterListenerWithType callback already registered!");
29             return;
30         }
31         std::unique_ptr<NativeReference> callbackRef;
32         callbackRef.reset(engine.CreateReference(value, 1));
33 
34         AddCallback(type, value);
35     }
36 
AddCallback(std::string type,NativeValue * jsListenerObject)37     void JsInputMethodEngineListener::AddCallback(std::string type, NativeValue* jsListenerObject)
38     {
39         IMSA_HILOGI("JsInputMethodEngineListener::AddCallback is called");
40         std::lock_guard<std::mutex> lock(mMutex);
41         std::unique_ptr<NativeReference> callbackRef;
42         callbackRef.reset(engine_->CreateReference(jsListenerObject, 1));
43         jsCbMap_[type].push_back(std::move(callbackRef));
44         IMSA_HILOGI("JsInputMethodEngineListener::AddCallback success");
45         IMSA_HILOGI("jsCbMap_ size: %{public}d, and type[%{public}s] size: %{public}d!",
46             static_cast<uint32_t>(jsCbMap_.size()), type.c_str(), static_cast<uint32_t>(jsCbMap_[type].size()));
47         return;
48     }
49 
UnregisterAllListenerWithType(std::string type)50     void JsInputMethodEngineListener::UnregisterAllListenerWithType(std::string type)
51     {
52         IMSA_HILOGI("JsInputMethodEngineListener::UnregisterAllListenerWithType");
53         // should do type check
54         if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
55             IMSA_HILOGI("methodName %{public}s not registerted!", type.c_str());
56             return;
57         }
58         for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
59             jsCbMap_[type].erase(it);
60         }
61         // one type with multi jscallback, erase type when there is no callback in one type
62         if (jsCbMap_[type].empty()) {
63             jsCbMap_.erase(type);
64         }
65         return;
66     }
67 
UnregisterListenerWithType(std::string type,NativeValue * value)68     void JsInputMethodEngineListener::UnregisterListenerWithType(std::string type, NativeValue* value)
69     {
70         IMSA_HILOGI("JsInputMethodEngineListener::UnregisterListenerWithType");
71         // should do type check
72         if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
73             IMSA_HILOGI("methodName %{public}s not registerted!", type.c_str());
74             return;
75         }
76         for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
77             if (value->StrictEquals((*it)->Get())) {
78                 jsCbMap_[type].erase(it);
79                 break;
80             }
81         }
82         // one type with multi jscallback, erase type when there is no callback in one type
83         if (jsCbMap_[type].empty()) {
84             jsCbMap_.erase(type);
85         }
86         return;
87     }
88 
IfCallbackRegistered(std::string type,NativeValue * jsListenerObject)89     bool JsInputMethodEngineListener::IfCallbackRegistered(std::string type, NativeValue* jsListenerObject)
90     {
91         IMSA_HILOGI("JsInputMethodEngineListener::IfCallbackRegistered");
92         if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
93             IMSA_HILOGI("methodName %{public}s not registertd!", type.c_str());
94             return false;
95         }
96 
97         for (auto iter = jsCbMap_[type].begin(); iter != jsCbMap_[type].end(); iter++) {
98             if (jsListenerObject->StrictEquals((*iter)->Get())) {
99                 IMSA_HILOGI("JsInputMethodEngineListener::IfCallbackRegistered callback already registered!");
100                 return true;
101             }
102         }
103         return false;
104     }
105 
CallJsMethod(std::string methodName,NativeValue * const * argv,size_t argc)106     void JsInputMethodEngineListener::CallJsMethod(std::string methodName, NativeValue* const* argv, size_t argc)
107     {
108         IMSA_HILOGI("JsInputMethodEngineListener::CallJsMethod");
109         if (engine_ == nullptr) {
110             IMSA_HILOGI("engine_ nullptr");
111             return;
112         }
113 
114         if (jsCbMap_.empty() || jsCbMap_.find(methodName) == jsCbMap_.end()) {
115             IMSA_HILOGI("methodName %{public}s not registertd!", methodName.c_str());
116             return;
117         }
118 
119         for (auto iter = jsCbMap_[methodName].begin(); iter != jsCbMap_[methodName].end(); iter++) {
120             engine_->CallFunction(engine_->CreateUndefined(), (*iter)->Get(), argv, argc);
121         }
122     }
123 
CallJsMethodReturnBool(std::string methodName,NativeValue * const * argv,size_t argc)124     bool JsInputMethodEngineListener::CallJsMethodReturnBool(std::string methodName,
125                                                              NativeValue* const* argv, size_t argc)
126     {
127         IMSA_HILOGI("JsInputMethodEngineListener::CallJsMethodReturnBool");
128         if (engine_ == nullptr) {
129             IMSA_HILOGI("engine_ nullptr");
130             return false;
131         }
132 
133         if (jsCbMap_.empty() || jsCbMap_.find(methodName) == jsCbMap_.end()) {
134             IMSA_HILOGI("methodName %{public}s not registertd!", methodName.c_str());
135             return false;
136         }
137 
138         bool result = false;
139         for (auto iter = jsCbMap_[methodName].begin(); iter != jsCbMap_[methodName].end(); iter++) {
140             NativeValue* nativeValue = engine_->CallFunction(engine_->CreateUndefined(), (*iter)->Get(), argv, argc);
141             bool ret = false;
142             if (ConvertFromJsValue(*engine_, nativeValue, ret) && ret) {
143                 result = true;
144             }
145         }
146         return result;
147     }
148 
OnKeyboardStatus(bool isShow)149     void JsInputMethodEngineListener::OnKeyboardStatus(bool isShow)
150     {
151         std::lock_guard<std::mutex> lock(mMutex);
152         IMSA_HILOGI("JsInputMethodEngineListener::OnKeyboardStatus");
153 
154         auto task = [this, isShow] () {
155             HandleScope handleScope(*engine_);
156             NativeValue* nativeValue = engine_->CreateObject();
157             NativeObject* object = ConvertNativeValueTo < NativeObject >(nativeValue);
158             if (object == nullptr) {
159                 IMSA_HILOGI("Failed to convert rect to jsObject");
160                 return;
161             }
162             NativeValue* argv[] = { nativeValue };
163             std::string methodName;
164             if (isShow) {
165                 methodName = "keyboardShow";
166             } else {
167                 methodName = "keyboardHide";
168             }
169             CallJsMethod(methodName, argv, ArraySize(argv));
170         };
171         mainHandler_->PostTask(task);
172     }
173 
OnInputStart()174     void JsInputMethodEngineListener::OnInputStart()
175     {
176         std::lock_guard<std::mutex> lock(mMutex);
177         IMSA_HILOGI("JsInputMethodEngineListener::OnInputStart");
178         auto task = [this] () {
179             HandleScope handleScope(*engine_);
180             NativeValue *nativeValuekb = CreateKeyboardController(*engine_);
181             NativeValue *nativeValuetx = CreateTextInputClient(*engine_);
182             NativeValue* argv[] = {nativeValuekb, nativeValuetx};
183             std::string methodName = "inputStart";
184             CallJsMethod(methodName, argv, ArraySize(argv));
185         };
186         mainHandler_->PostTask(task);
187     }
188 
OnInputStop(std::string imeId)189     void JsInputMethodEngineListener::OnInputStop(std::string imeId)
190     {
191         std::lock_guard<std::mutex> lock(mMutex);
192         IMSA_HILOGI("JsInputMethodEngineListener::OnInputStop");
193 
194         auto task = [this, imeId] () {
195             HandleScope handleScope(*engine_);
196             NativeValue* nativeValue = CreateJsValue(*engine_, imeId);
197 
198             NativeValue* argv[] = { nativeValue };
199             std::string methodName = "inputStop";
200             CallJsMethod(methodName, argv, ArraySize(argv));
201         };
202         mainHandler_->PostTask(task);
203     }
204 
OnSetCallingWindow(uint32_t windowId)205     void JsInputMethodEngineListener::OnSetCallingWindow(uint32_t windowId)
206     {
207         std::lock_guard<std::mutex> lock(mMutex);
208         IMSA_HILOGI("JsInputMethodEngineListener::OnSetCallingWindow");
209 
210         auto task = [this, windowId] () {
211             HandleScope handleScope(*engine_);
212             NativeValue* nativeValue = CreateJsValue(*engine_, windowId);
213             NativeValue* argv[] = { nativeValue };
214             std::string methodName = "setCallingWindow";
215             CallJsMethod(methodName, argv, ArraySize(argv));
216         };
217         mainHandler_->PostTask(task);
218     }
219 } // namespace MiscServices
220 } // namespace OHOS
221