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 #ifndef INTERFACE_KITS_JS_GETINPUT_METHOD_SETTING_H
16 #define INTERFACE_KITS_JS_GETINPUT_METHOD_SETTING_H
17 
18 #include <uv.h>
19 
20 #include "async_call.h"
21 #include "event_handler.h"
22 #include "global.h"
23 #include "input_method_controller.h"
24 #include "input_method_status.h"
25 #include "js_callback_object.h"
26 
27 namespace OHOS {
28 namespace MiscServices {
29 struct ListInputContext : public AsyncCall::Context {
30     InputMethodStatus inputMethodStatus = InputMethodStatus::ALL;
31     std::vector<Property> properties;
32     std::vector<SubProperty> subProperties;
33     Property property;
34     napi_status status = napi_generic_failure;
ListInputContextListInputContext35     ListInputContext() : Context(nullptr, nullptr){};
ListInputContextListInputContext36     ListInputContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
37 
operatorListInputContext38     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
39     {
40         CHECK_RETURN(self != nullptr, "self is nullptr!", napi_invalid_arg);
41         return Context::operator()(env, argc, argv, self);
42     }
operatorListInputContext43     napi_status operator()(napi_env env, napi_value *result) override
44     {
45         if (status != napi_ok) {
46             output_ = nullptr;
47             return status;
48         }
49         return Context::operator()(env, result);
50     }
51 };
52 
53 struct DisplayOptionalInputMethodContext : public AsyncCall::Context {
54     napi_status status = napi_generic_failure;
55     bool isDisplayed = false;
DisplayOptionalInputMethodContextDisplayOptionalInputMethodContext56     DisplayOptionalInputMethodContext() : Context(nullptr, nullptr){};
DisplayOptionalInputMethodContextDisplayOptionalInputMethodContext57     DisplayOptionalInputMethodContext(InputAction input, OutputAction output)
58         : Context(std::move(input), std::move(output)){};
59 
operatorDisplayOptionalInputMethodContext60     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
61     {
62         CHECK_RETURN(self != nullptr, "self is nullptr!", napi_invalid_arg);
63         return Context::operator()(env, argc, argv, self);
64     }
operatorDisplayOptionalInputMethodContext65     napi_status operator()(napi_env env, napi_value *result) override
66     {
67         if (status != napi_ok) {
68             output_ = nullptr;
69             return status;
70         }
71         return Context::operator()(env, result);
72     }
73 };
74 
75 struct GetInputMethodControllerContext : public AsyncCall::Context {
76     bool isStopInput = false;
77     napi_status status = napi_generic_failure;
GetInputMethodControllerContextGetInputMethodControllerContext78     GetInputMethodControllerContext() : Context(nullptr, nullptr){};
GetInputMethodControllerContextGetInputMethodControllerContext79     GetInputMethodControllerContext(InputAction input, OutputAction output)
80         : Context(std::move(input), std::move(output)){};
81 
operatorGetInputMethodControllerContext82     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
83     {
84         CHECK_RETURN(self != nullptr, "self is nullptr!", napi_invalid_arg);
85         return Context::operator()(env, argc, argv, self);
86     }
operatorGetInputMethodControllerContext87     napi_status operator()(napi_env env, napi_value *result) override
88     {
89         if (status != napi_ok) {
90             output_ = nullptr;
91             return status;
92         }
93         return Context::operator()(env, result);
94     }
95 };
96 
97 class JsGetInputMethodSetting : public ImeEventListener {
98 public:
99     JsGetInputMethodSetting() = default;
100     ~JsGetInputMethodSetting() = default;
101     static napi_value Init(napi_env env, napi_value exports);
102     static napi_value GetSetting(napi_env env, napi_callback_info info);
103     static napi_value GetInputMethodSetting(napi_env env, napi_callback_info info);
104     static napi_value ListInputMethod(napi_env env, napi_callback_info info);
105     static napi_value ListInputMethodSubtype(napi_env env, napi_callback_info info);
106     static napi_value ListCurrentInputMethodSubtype(napi_env env, napi_callback_info info);
107     static napi_value GetInputMethods(napi_env env, napi_callback_info info);
108     static napi_value GetInputMethodsSync(napi_env env, napi_callback_info info);
109     static napi_value GetAllInputMethods(napi_env env, napi_callback_info info);
110     static napi_value GetAllInputMethodsSync(napi_env env, napi_callback_info info);
111     static napi_value DisplayOptionalInputMethod(napi_env env, napi_callback_info info);
112     static napi_value ShowOptionalInputMethods(napi_env env, napi_callback_info info);
113     static napi_value IsPanelShown(napi_env env, napi_callback_info info);
114     static napi_value Subscribe(napi_env env, napi_callback_info info);
115     static napi_value UnSubscribe(napi_env env, napi_callback_info info);
116     static std::shared_ptr<JsGetInputMethodSetting> GetInputMethodSettingInstance();
117     void OnImeChange(const Property &property, const SubProperty &subProperty) override;
118     void OnImeShow(const ImeWindowInfo &info) override;
119     void OnImeHide(const ImeWindowInfo &info) override;
120 
121 private:
122     static napi_status GetInputMethodProperty(napi_env env, napi_value argv, std::shared_ptr<ListInputContext> ctxt);
123     static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo);
124     static napi_value GetJsConstProperty(napi_env env, uint32_t num);
125     static napi_value GetIMSetting(napi_env env, napi_callback_info info, bool needThrowException);
126     static std::shared_ptr<AppExecFwk::EventHandler> GetEventHandler();
127     int32_t RegisterListener(napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj);
128     void UnRegisterListener(napi_value callback, std::string type, bool &isUpdateFlag);
129     void OnPanelStatusChange(const std::string &type, const InputWindowInfo &info);
130     struct UvEntry {
131         std::vector<std::shared_ptr<JSCallbackObject>> vecCopy;
132         std::string type;
133         Property property;
134         SubProperty subProperty;
135         std::vector<InputWindowInfo> windowInfo;
UvEntryUvEntry136         UvEntry(const std::vector<std::shared_ptr<JSCallbackObject>> &cbVec, const std::string &type)
137             : vecCopy(cbVec), type(type)
138         {
139         }
140     };
141     using EntrySetter = std::function<void(UvEntry &)>;
142     std::shared_ptr<UvEntry> GetEntry(const std::string &type, EntrySetter entrySetter = nullptr);
143     static const std::string IMS_CLASS_NAME;
144     static thread_local napi_ref IMSRef_;
145     static std::mutex eventHandlerMutex_;
146     static std::shared_ptr<AppExecFwk::EventHandler> handler_;
147     uv_loop_s *loop_ = nullptr;
148     std::recursive_mutex mutex_;
149     std::map<std::string, std::vector<std::shared_ptr<JSCallbackObject>>> jsCbMap_;
150     static std::mutex msMutex_;
151     static std::shared_ptr<JsGetInputMethodSetting> inputMethod_;
152 
153     PanelFlag softKbShowingFlag_{ FLG_CANDIDATE_COLUMN };
154     PanelFlag GetSoftKbShowingFlag();
155     void SetSoftKbShowingFlag(PanelFlag flag);
156 };
157 } // namespace MiscServices
158 } // namespace OHOS
159 #endif // INTERFACE_KITS_JS_GETINPUT_METHOD_SETTING_H
160