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 "key_event_input_subscribe_manager.h"
17
18 #include <cinttypes>
19
20 #include "define_multimodal.h"
21 #include "error_multimodal.h"
22
23 #include "bytrace_adapter.h"
24 #include "multimodal_event_handler.h"
25
26 namespace OHOS {
27 namespace MMI {
28 namespace {
29 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "KeyEventInputSubscribeManager" };
30 constexpr int32_t INVALID_SUBSCRIBE_ID = -1;
31 constexpr size_t PRE_KEYS_NUM = 4;
32 } // namespace
33 int32_t KeyEventInputSubscribeManager::subscribeIdManager_ = 0;
34
KeyEventInputSubscribeManager()35 KeyEventInputSubscribeManager::KeyEventInputSubscribeManager() {}
~KeyEventInputSubscribeManager()36 KeyEventInputSubscribeManager::~KeyEventInputSubscribeManager() {}
37
SubscribeKeyEventInfo(std::shared_ptr<KeyOption> keyOption,std::function<void (std::shared_ptr<KeyEvent>)> callback)38 KeyEventInputSubscribeManager::SubscribeKeyEventInfo::SubscribeKeyEventInfo(
39 std::shared_ptr<KeyOption> keyOption,
40 std::function<void(std::shared_ptr<KeyEvent>)> callback)
41 : keyOption_(keyOption), callback_(callback)
42 {
43 if (KeyEventInputSubscribeManager::subscribeIdManager_ >= INT_MAX) {
44 subscribeId_ = -1;
45 MMI_HILOGE("The subscribeId has reached the upper limit, cannot continue the subscription");
46 return;
47 }
48 subscribeId_ = KeyEventInputSubscribeManager::subscribeIdManager_;
49 ++KeyEventInputSubscribeManager::subscribeIdManager_;
50 }
51
operator <(const KeyOption & first,const KeyOption & second)52 static bool operator<(const KeyOption &first, const KeyOption &second)
53 {
54 if (first.GetFinalKey() != second.GetFinalKey()) {
55 return (first.GetFinalKey() < second.GetFinalKey());
56 }
57 const std::set<int32_t> sPrekeys { first.GetPreKeys() };
58 const std::set<int32_t> tPrekeys { second.GetPreKeys() };
59 std::set<int32_t>::const_iterator sIter = sPrekeys.cbegin();
60 std::set<int32_t>::const_iterator tIter = tPrekeys.cbegin();
61 for (; sIter != sPrekeys.cend() && tIter != tPrekeys.cend(); ++sIter, ++tIter) {
62 if (*sIter != *tIter) {
63 return (*sIter < *tIter);
64 }
65 }
66 if (sIter != sPrekeys.cend() || tIter != tPrekeys.cend()) {
67 return (tIter != tPrekeys.cend());
68 }
69 if (first.IsFinalKeyDown()) {
70 if (!second.IsFinalKeyDown()) {
71 return false;
72 }
73 } else {
74 if (second.IsFinalKeyDown()) {
75 return true;
76 }
77 }
78 return (first.GetFinalKeyDownDuration() < second.GetFinalKeyDownDuration());
79 }
80
operator <(const SubscribeKeyEventInfo & other) const81 bool KeyEventInputSubscribeManager::SubscribeKeyEventInfo::operator<(const SubscribeKeyEventInfo &other) const
82 {
83 if (keyOption_ == nullptr) {
84 return (other.keyOption_ != nullptr);
85 } else if (other.keyOption_ == nullptr) {
86 return false;
87 }
88 return (*keyOption_ < *other.keyOption_);
89 }
90
SubscribeKeyEvent(std::shared_ptr<KeyOption> keyOption,std::function<void (std::shared_ptr<KeyEvent>)> callback)91 int32_t KeyEventInputSubscribeManager::SubscribeKeyEvent(std::shared_ptr<KeyOption> keyOption,
92 std::function<void(std::shared_ptr<KeyEvent>)> callback)
93 {
94 CALL_INFO_TRACE;
95 CHKPR(keyOption, INVALID_SUBSCRIBE_ID);
96 CHKPR(callback, INVALID_SUBSCRIBE_ID);
97 std::set<int32_t> preKeys = keyOption->GetPreKeys();
98 if (preKeys.size() > PRE_KEYS_NUM) {
99 MMI_HILOGE("PreKeys number invalid");
100 return INVALID_SUBSCRIBE_ID;
101 }
102
103 std::lock_guard<std::mutex> guard(mtx_);
104 if (!MMIEventHdl.InitClient()) {
105 MMI_HILOGE("Client init failed");
106 return INVALID_SUBSCRIBE_ID;
107 }
108
109 auto [tIter, isOk] = subscribeInfos_.emplace(keyOption, callback);
110 if (!isOk) {
111 MMI_HILOGW("Subscription is duplicated");
112 return tIter->GetSubscribeId();
113 }
114 if (MMIEventHdl.SubscribeKeyEvent(*tIter) != RET_OK) {
115 MMI_HILOGE("Subscribing key event failed");
116 }
117
118 MMI_HILOGD("subscribeId:%{public}d,keyOption->finalKey:%{public}d,"
119 "keyOption->isFinalKeyDown:%{public}s,keyOption->finalKeyDownDuration:%{public}d",
120 tIter->GetSubscribeId(), keyOption->GetFinalKey(),
121 keyOption->IsFinalKeyDown() ? "true" : "false",
122 keyOption->GetFinalKeyDownDuration());
123 for (const auto &preKey : preKeys) {
124 MMI_HILOGD("prekey:%{public}d", preKey);
125 }
126 return tIter->GetSubscribeId();
127 }
128
UnsubscribeKeyEvent(int32_t subscribeId)129 int32_t KeyEventInputSubscribeManager::UnsubscribeKeyEvent(int32_t subscribeId)
130 {
131 CALL_INFO_TRACE;
132 if (subscribeId < 0) {
133 MMI_HILOGE("The subscribe id is less than 0");
134 return RET_ERR;
135 }
136
137 std::lock_guard<std::mutex> guard(mtx_);
138 if (!MMIEventHdl.InitClient()) {
139 MMI_HILOGE("Client init failed");
140 return INVALID_SUBSCRIBE_ID;
141 }
142 if (subscribeInfos_.empty()) {
143 MMI_HILOGE("The subscribeInfos is empty");
144 return RET_ERR;
145 }
146
147 for (auto it = subscribeInfos_.begin(); it != subscribeInfos_.end(); ++it) {
148 if (it->GetSubscribeId() == subscribeId) {
149 if (MMIEventHdl.UnsubscribeKeyEvent(subscribeId) != RET_OK) {
150 MMI_HILOGE("Leave, unsubscribe key event failed");
151 return RET_ERR;
152 }
153 subscribeInfos_.erase(it);
154 return RET_OK;
155 }
156 }
157 return RET_ERR;
158 }
159
OnSubscribeKeyEventCallback(std::shared_ptr<KeyEvent> event,int32_t subscribeId)160 int32_t KeyEventInputSubscribeManager::OnSubscribeKeyEventCallback(std::shared_ptr<KeyEvent> event,
161 int32_t subscribeId)
162 {
163 CHK_PID_AND_TID();
164 CHKPR(event, ERROR_NULL_POINTER);
165 if (subscribeId < 0) {
166 MMI_HILOGE("Leave, the subscribe id is less than 0");
167 return RET_ERR;
168 }
169
170 std::lock_guard<std::mutex> guard(mtx_);
171 BytraceAdapter::StartBytrace(event, BytraceAdapter::TRACE_STOP, BytraceAdapter::KEY_SUBSCRIBE_EVENT);
172 auto info = GetSubscribeKeyEvent(subscribeId);
173 CHKPR(info, ERROR_NULL_POINTER);
174 auto callback = info->GetCallback();
175 if (!callback) {
176 MMI_HILOGE("Callback is null");
177 return RET_ERR;
178 }
179 callback(event);
180 MMI_HILOGD("Key event id:%{public}d keyCode:%{public}d", subscribeId, event->GetKeyCode());
181 return RET_OK;
182 }
183
OnConnected()184 void KeyEventInputSubscribeManager::OnConnected()
185 {
186 CALL_DEBUG_ENTER;
187 if (subscribeInfos_.empty()) {
188 MMI_HILOGD("Leave, subscribeInfos_ is empty");
189 return;
190 }
191 for (const auto& subscriberInfo : subscribeInfos_) {
192 if (MMIEventHdl.SubscribeKeyEvent(subscriberInfo) != RET_OK) {
193 MMI_HILOGE("Subscribe key event failed");
194 }
195 }
196 }
197
GetSubscribeKeyEvent(int32_t id)198 const KeyEventInputSubscribeManager::SubscribeKeyEventInfo* KeyEventInputSubscribeManager::GetSubscribeKeyEvent(
199 int32_t id)
200 {
201 if (id < 0) {
202 MMI_HILOGE("Invalid input param id:%{public}d", id);
203 return nullptr;
204 }
205 for (const auto &subscriber : subscribeInfos_) {
206 if (subscriber.GetSubscribeId() == id) {
207 return &subscriber;
208 }
209 }
210 return nullptr;
211 }
212 } // namespace MMI
213 } // namespace OHOS