• 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 "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_DEBUG_ENTER;
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         subscribeInfos_.erase(tIter);
117         return INVALID_SUBSCRIBE_ID;
118     }
119 
120     MMI_HILOGD("subscribeId:%{public}d,keyOption->finalKey:%{public}d,"
121         "keyOption->isFinalKeyDown:%{public}s,keyOption->finalKeyDownDuration:%{public}d",
122         tIter->GetSubscribeId(), keyOption->GetFinalKey(),
123         keyOption->IsFinalKeyDown() ? "true" : "false",
124         keyOption->GetFinalKeyDownDuration());
125     for (const auto &preKey : preKeys) {
126         MMI_HILOGD("prekey:%{public}d", preKey);
127     }
128     return tIter->GetSubscribeId();
129 }
130 
UnsubscribeKeyEvent(int32_t subscribeId)131 int32_t KeyEventInputSubscribeManager::UnsubscribeKeyEvent(int32_t subscribeId)
132 {
133     CALL_INFO_TRACE;
134     if (subscribeId < 0) {
135         MMI_HILOGE("The subscribe id is less than 0");
136         return RET_ERR;
137     }
138 
139     std::lock_guard<std::mutex> guard(mtx_);
140     if (!MMIEventHdl.InitClient()) {
141         MMI_HILOGE("Client init failed");
142         return INVALID_SUBSCRIBE_ID;
143     }
144     if (subscribeInfos_.empty()) {
145         MMI_HILOGE("The subscribeInfos is empty");
146         return RET_ERR;
147     }
148 
149     for (auto it = subscribeInfos_.begin(); it != subscribeInfos_.end(); ++it) {
150         if (it->GetSubscribeId() == subscribeId) {
151             if (MMIEventHdl.UnsubscribeKeyEvent(subscribeId) != RET_OK) {
152                 MMI_HILOGE("Leave, unsubscribe key event failed");
153                 return RET_ERR;
154             }
155             subscribeInfos_.erase(it);
156             return RET_OK;
157         }
158     }
159     return RET_ERR;
160 }
161 
OnSubscribeKeyEventCallback(std::shared_ptr<KeyEvent> event,int32_t subscribeId)162 int32_t KeyEventInputSubscribeManager::OnSubscribeKeyEventCallback(std::shared_ptr<KeyEvent> event,
163     int32_t subscribeId)
164 {
165     CHK_PID_AND_TID();
166     CHKPR(event, ERROR_NULL_POINTER);
167     if (subscribeId < 0) {
168         MMI_HILOGE("Leave, the subscribe id is less than 0");
169         return RET_ERR;
170     }
171 
172     std::lock_guard<std::mutex> guard(mtx_);
173     BytraceAdapter::StartBytrace(event, BytraceAdapter::TRACE_STOP, BytraceAdapter::KEY_SUBSCRIBE_EVENT);
174     auto info = GetSubscribeKeyEvent(subscribeId);
175     CHKPR(info, ERROR_NULL_POINTER);
176     auto callback = info->GetCallback();
177     if (!callback) {
178         MMI_HILOGE("Callback is null");
179         return RET_ERR;
180     }
181     callback(event);
182     MMI_HILOGD("Key event id:%{public}d keyCode:%{public}d", subscribeId, event->GetKeyCode());
183     return RET_OK;
184 }
185 
OnConnected()186 void KeyEventInputSubscribeManager::OnConnected()
187 {
188     CALL_DEBUG_ENTER;
189     if (subscribeInfos_.empty()) {
190         MMI_HILOGD("Leave, subscribeInfos_ is empty");
191         return;
192     }
193     for (const auto& subscriberInfo : subscribeInfos_) {
194         if (MMIEventHdl.SubscribeKeyEvent(subscriberInfo) != RET_OK) {
195             MMI_HILOGE("Subscribe key event failed");
196         }
197     }
198 }
199 
GetSubscribeKeyEvent(int32_t id)200 const KeyEventInputSubscribeManager::SubscribeKeyEventInfo* KeyEventInputSubscribeManager::GetSubscribeKeyEvent(
201     int32_t id)
202 {
203     if (id < 0) {
204         MMI_HILOGE("Invalid input param id:%{public}d", id);
205         return nullptr;
206     }
207     for (const auto &subscriber : subscribeInfos_) {
208         if (subscriber.GetSubscribeId() == id) {
209             return &subscriber;
210         }
211     }
212     return nullptr;
213 }
214 } // namespace MMI
215 } // namespace OHOS
216