1 /*
2  * Copyright (c) 2024 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 #ifndef FRAMEWORKS_JS_NAPI_JS_KEYBOARD_PANEL_MANAGER_H
17 #define FRAMEWORKS_JS_NAPI_JS_KEYBOARD_PANEL_MANAGER_H
18 
19 #include "async_call.h"
20 #include "block_queue.h"
21 #include "event_handler.h"
22 #include "js_callback_object.h"
23 #include "ime_system_channel.h"
24 
25 namespace OHOS {
26 namespace MiscServices {
27 struct PrivateCommandInfo {
28     std::chrono::system_clock::time_point timestamp{};
29     std::unordered_map<std::string, PrivateDataValue> privateCommand;
30     bool operator==(const PrivateCommandInfo &info) const
31     {
32         return (timestamp == info.timestamp && privateCommand == info.privateCommand);
33     }
34 };
35 
36 struct SendPrivateCommandContext : public AsyncCall::Context {
37     std::unordered_map<std::string, PrivateDataValue> privateCommand;
38     PrivateCommandInfo info;
SendPrivateCommandContextSendPrivateCommandContext39     SendPrivateCommandContext() : Context(nullptr, nullptr){};
40 
operatorSendPrivateCommandContext41     napi_status operator()(napi_env env, napi_value *result) override
42     {
43         if (status_ != napi_ok) {
44             output_ = nullptr;
45             return status_;
46         }
47         return Context::operator()(env, result);
48     }
49 };
50 
51 struct SmartMenuContext : public AsyncCall::Context {
52     std::string smartMenu;
SmartMenuContextSmartMenuContext53     SmartMenuContext() : Context(nullptr, nullptr){};
54 
operatorSmartMenuContext55     napi_status operator()(napi_env env, napi_value *result) override
56     {
57         if (status_ != napi_ok) {
58             output_ = nullptr;
59             return status_;
60         }
61         return Context::operator()(env, result);
62     }
63 };
64 
65 struct JsPanelStatus {
66     static napi_value Write(napi_env env, const SysPanelStatus &in);
67 };
68 
69 class JsKeyboardPanelManager : public OnSystemCmdListener {
70 public:
71     JsKeyboardPanelManager();
72     ~JsKeyboardPanelManager() = default;
73 
74     static napi_value Init(napi_env env, napi_value info);
75     static sptr<JsKeyboardPanelManager> GetInstance();
76     static napi_value SendPrivateCommand(napi_env env, napi_callback_info info);
77     static napi_value GetSmartMenuCfg(napi_env env, napi_callback_info info);
78     static napi_value ConnectSystemCmd(napi_env env, napi_callback_info info);
79     static napi_value Subscribe(napi_env env, napi_callback_info info);
80     static napi_value UnSubscribe(napi_env env, napi_callback_info info);
81     static napi_value GetDefaultInputMethod(napi_env env, napi_callback_info info);
82     static napi_value GetJsInputMethodProperty(napi_env env, const Property &property);
83 
84     void ReceivePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) override;
85     void NotifyPanelStatus(const SysPanelStatus &sysPanelStatus) override;
86 
87 private:
88     void RegisterListener(napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj);
89     void UnRegisterListener(napi_value callback, std::string type);
90     napi_value GetJsPanelStatus(napi_env env, const SysPanelStatus &in);
91     struct UvEntry {
92         std::vector<std::shared_ptr<JSCallbackObject>> vecCopy;
93         std::string type;
94         SysPanelStatus sysPanelStatus;
95         std::string smartMenu;
96         std::unordered_map<std::string, PrivateDataValue> privateCommand;
UvEntryUvEntry97         explicit UvEntry(const std::vector<std::shared_ptr<JSCallbackObject>> &cbVec, const std::string &type)
98             : vecCopy(cbVec), type(type), sysPanelStatus({ false, 0, 0, 0 }), smartMenu(""), privateCommand({})
99         {
100         }
101     };
102     using EntrySetter = std::function<void(UvEntry &)>;
103     std::shared_ptr<AppExecFwk::EventHandler> GetEventHandler();
104     std::shared_ptr<UvEntry> GetEntry(const std::string &type, EntrySetter entrySetter = nullptr);
105 
106     std::recursive_mutex mutex_;
107     std::map<std::string, std::vector<std::shared_ptr<JSCallbackObject>>> jsCbMap_;
108     std::mutex eventHandlerMutex_;
109     std::shared_ptr<AppExecFwk::EventHandler> handler_;
110     static std::mutex managerMutex_;
111     static sptr<JsKeyboardPanelManager> keyboardPanelManager_;
112     static BlockQueue<PrivateCommandInfo> privateCommandQueue_;
113 };
114 } // namespace MiscServices
115 } // namespace OHOS
116 #endif // FRAMEWORKS_JS_NAPI_JS_KEYBOARD_PANEL_MANAGER_H