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_command_handler.h"
17
18 #include "ability_manager_client.h"
19 #include "bytrace_adapter.h"
20 #include "cJSON.h"
21 #include "config_policy_utils.h"
22 #include "define_multimodal.h"
23 #include "dfx_hisysevent.h"
24 #include "error_multimodal.h"
25 #include "file_ex.h"
26 #include "input_event_data_transformation.h"
27 #include "input_event_handler.h"
28 #include "mmi_log.h"
29 #include "net_packet.h"
30 #include "proto.h"
31 #include "timer_manager.h"
32 #include "util_ex.h"
33
34 namespace OHOS {
35 namespace MMI {
36 namespace {
37 constexpr int32_t MAX_PREKEYS_NUM = 4;
38 constexpr int32_t MAX_SEQUENCEKEYS_NUM = 10;
39 constexpr int64_t MAX_DELAY_TIME = 1000000;
40 constexpr int64_t SECONDS_SYSTEM = 1000;
41 constexpr int32_t SPECIAL_KEY_DOWN_DELAY = 150;
42 constexpr int32_t MAX_SHORT_KEY_DOWN_DURATION = 4000;
43 constexpr int32_t MIN_SHORT_KEY_DOWN_DURATION = 0;
44 constexpr int32_t ERROR_DELAY_VALUE = -1000;
45 constexpr int32_t TOUCH_MAX_THRESHOLD = 15;
46 constexpr int32_t COMMON_PARAMETER_ERROR = 401;
47 constexpr size_t SINGEL_KNUCKLE_SIZE = 1;
48 constexpr size_t DOUBLE_KNUCKLE_SIZE = 2;
49 constexpr int32_t NONE_CLICK_STATE = 0;
50 constexpr int32_t CLICK_STATE = 1;
51 constexpr int32_t DOUBLE_CLICK_INTERVAL_TIME = 260;
52
53 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "KeyCommandHandler" };
54 const std::string shortKeyFileName = "/data/service/el1/public/multimodalinput/Settings.xml";
55 const std::string SINGLE_KNUCKLE_ABILITY = "SingleKnuckleDoubleClickGesture";
56 const std::string DOUBLE_KNUCKLE_ABILITY = "DoubleKnuckleDoubleClickGesture";
57 enum SpecialType {
58 SPECIAL_ALL = 0,
59 SUBSCRIBER_BEFORE_DELAY = 1,
60 KEY_DOWN_ACTION = 2
61 };
62 const std::map<int32_t, SpecialType> SPECIAL_KEYS = {
63 { KeyEvent::KEYCODE_POWER, SpecialType::KEY_DOWN_ACTION },
64 { KeyEvent::KEYCODE_VOLUME_DOWN, SpecialType::SPECIAL_ALL },
65 { KeyEvent::KEYCODE_VOLUME_UP, SpecialType::SPECIAL_ALL }
66 };
67 struct JsonParser {
68 JsonParser() = default;
~JsonParserOHOS::MMI::__anon811c4e070111::JsonParser69 ~JsonParser()
70 {
71 if (json_ != nullptr) {
72 cJSON_Delete(json_);
73 }
74 }
operator cJSON*OHOS::MMI::__anon811c4e070111::JsonParser75 operator cJSON *()
76 {
77 return json_;
78 }
79 cJSON *json_ { nullptr };
80 };
81
IsSpecialType(int32_t keyCode,SpecialType type)82 bool IsSpecialType(int32_t keyCode, SpecialType type)
83 {
84 auto it = SPECIAL_KEYS.find(keyCode);
85 if (it == SPECIAL_KEYS.end()) {
86 return false;
87 }
88 return (it->second == SpecialType::SPECIAL_ALL || it->second == type);
89 }
90
GetBusinessId(const cJSON * jsonData,std::string & businessIdValue,std::vector<std::string> & businessIds)91 bool GetBusinessId(const cJSON* jsonData, std::string &businessIdValue, std::vector<std::string> &businessIds)
92 {
93 if (!cJSON_IsObject(jsonData)) {
94 MMI_HILOGE("jsonData is not object");
95 return false;
96 }
97 cJSON *businessId = cJSON_GetObjectItemCaseSensitive(jsonData, "businessId");
98 if (!cJSON_IsString(businessId)) {
99 MMI_HILOGE("businessId is not string");
100 return false;
101 }
102 businessIdValue = businessId->valuestring;
103 businessIds.push_back(businessIdValue);
104 return true;
105 }
106
GetPreKeys(const cJSON * jsonData,ShortcutKey & shortcutKey)107 bool GetPreKeys(const cJSON* jsonData, ShortcutKey &shortcutKey)
108 {
109 if (!cJSON_IsObject(jsonData)) {
110 MMI_HILOGE("jsonData is not object");
111 return false;
112 }
113 cJSON* preKey = cJSON_GetObjectItemCaseSensitive(jsonData, "preKey");
114 if (!cJSON_IsArray(preKey)) {
115 MMI_HILOGE("preKey number must be array");
116 return false;
117 }
118 int32_t preKeySize = cJSON_GetArraySize(preKey);
119 if (preKeySize > MAX_PREKEYS_NUM) {
120 MMI_HILOGE("preKeySize number must less and equal four");
121 return false;
122 }
123 for (int32_t i = 0; i < preKeySize; ++i) {
124 cJSON *preKeyJson = cJSON_GetArrayItem(preKey, i);
125 if (!cJSON_IsNumber(preKeyJson)) {
126 MMI_HILOGE("preKeyJson is not number");
127 return false;
128 }
129 if (preKeyJson->valueint < 0) {
130 MMI_HILOGE("preKeyJson must be number and bigger or equal than 0");
131 return false;
132 }
133 if (!shortcutKey.preKeys.emplace(preKeyJson->valueint).second) {
134 MMI_HILOGE("preKeyJson must be unduplicated");
135 return false;
136 }
137 }
138 return true;
139 }
140
GetTrigger(const cJSON * jsonData,int32_t & triggerType)141 bool GetTrigger(const cJSON* jsonData, int32_t &triggerType)
142 {
143 if (!cJSON_IsObject(jsonData)) {
144 MMI_HILOGE("jsonData is not object");
145 return false;
146 }
147 cJSON *trigger = cJSON_GetObjectItemCaseSensitive(jsonData, "trigger");
148 if (!cJSON_IsString(trigger)) {
149 MMI_HILOGE("trigger is not string");
150 return false;
151 }
152 if (((std::strcmp(trigger->valuestring, "key_up") != 0)
153 && (std::strcmp(trigger->valuestring, "key_down") != 0))) {
154 MMI_HILOGE("trigger must be one of [key_up, key_down]");
155 return false;
156 }
157 if (std::strcmp(trigger->valuestring, "key_up") == 0) {
158 triggerType = KeyEvent::KEY_ACTION_UP;
159 } else {
160 triggerType = KeyEvent::KEY_ACTION_DOWN;
161 }
162 return true;
163 }
164
GetKeyDownDuration(const cJSON * jsonData,int32_t & keyDownDurationInt)165 bool GetKeyDownDuration(const cJSON* jsonData, int32_t &keyDownDurationInt)
166 {
167 if (!cJSON_IsObject(jsonData)) {
168 MMI_HILOGE("jsonData is not object");
169 return false;
170 }
171 cJSON *keyDownDuration = cJSON_GetObjectItemCaseSensitive(jsonData, "keyDownDuration");
172 if (!cJSON_IsNumber(keyDownDuration)) {
173 MMI_HILOGE("keyDownDuration is not number");
174 return false;
175 }
176 if (keyDownDuration->valueint < 0) {
177 MMI_HILOGE("keyDownDuration must be number and bigger and equal zero");
178 return false;
179 }
180 keyDownDurationInt = keyDownDuration->valueint;
181 return true;
182 }
183
GetKeyFinalKey(const cJSON * jsonData,int32_t & finalKeyInt)184 bool GetKeyFinalKey(const cJSON* jsonData, int32_t &finalKeyInt)
185 {
186 if (!cJSON_IsObject(jsonData)) {
187 MMI_HILOGE("jsonData is not object");
188 return false;
189 }
190 cJSON *finalKey = cJSON_GetObjectItemCaseSensitive(jsonData, "finalKey");
191 if (!cJSON_IsNumber(finalKey)) {
192 MMI_HILOGE("finalKey must be number");
193 return false;
194 }
195 finalKeyInt = finalKey->valueint;
196 return true;
197 }
198
GetKeyVal(const cJSON * json,const std::string & key,std::string & value)199 void GetKeyVal(const cJSON* json, const std::string &key, std::string &value)
200 {
201 if (!cJSON_IsObject(json)) {
202 MMI_HILOGE("json is not object");
203 return;
204 }
205 cJSON *valueJson = cJSON_GetObjectItemCaseSensitive(json, key.c_str());
206 if (cJSON_IsString(valueJson)) {
207 value = valueJson->valuestring;
208 }
209 return;
210 }
211
GetEntities(const cJSON * jsonAbility,Ability & ability)212 bool GetEntities(const cJSON* jsonAbility, Ability &ability)
213 {
214 if (!cJSON_IsObject(jsonAbility)) {
215 MMI_HILOGE("jsonAbility is not object");
216 return false;
217 }
218 cJSON *entities = cJSON_GetObjectItemCaseSensitive(jsonAbility, "entities");
219 if (entities == nullptr) {
220 return true;
221 }
222 if (!cJSON_IsArray(entities)) {
223 MMI_HILOGE("entities must be array");
224 return false;
225 }
226 int32_t entitySize = cJSON_GetArraySize(entities);
227 for (int32_t i = 0; i < entitySize; i++) {
228 cJSON* entity = cJSON_GetArrayItem(entities, i);
229 if (!cJSON_IsString(entity)) {
230 MMI_HILOGE("entity is not string");
231 return false;
232 }
233 ability.entities.push_back(entity->valuestring);
234 }
235 return true;
236 }
237
GetParams(const cJSON * jsonAbility,Ability & ability)238 bool GetParams(const cJSON* jsonAbility, Ability &ability)
239 {
240 if (!cJSON_IsObject(jsonAbility)) {
241 MMI_HILOGE("jsonAbility is not object");
242 return false;
243 }
244 cJSON *params = cJSON_GetObjectItemCaseSensitive(jsonAbility, "params");
245 if (params == nullptr) {
246 return true;
247 }
248 if (!cJSON_IsArray(params)) {
249 MMI_HILOGE("params must be array");
250 return false;
251 }
252 int32_t paramsSize = cJSON_GetArraySize(params);
253 for (int32_t i = 0; i < paramsSize; ++i) {
254 cJSON* param = cJSON_GetArrayItem(params, i);
255 if (!cJSON_IsObject(param)) {
256 MMI_HILOGE("param must be object");
257 return false;
258 }
259 cJSON* key = cJSON_GetObjectItemCaseSensitive(param, "key");
260 if (!cJSON_IsString(key)) {
261 MMI_HILOGE("key is not string");
262 return false;
263 }
264 cJSON* value = cJSON_GetObjectItemCaseSensitive(param, "value");
265 if (!cJSON_IsString(value)) {
266 MMI_HILOGE("value is not string");
267 return false;
268 }
269 auto ret = ability.params.emplace(key->valuestring, value->valuestring);
270 if (!ret.second) {
271 MMI_HILOGW("Emplace to failed");
272 }
273 }
274 return true;
275 }
276
PackageAbility(const cJSON * jsonAbility,Ability & ability)277 bool PackageAbility(const cJSON* jsonAbility, Ability &ability)
278 {
279 if (!cJSON_IsObject(jsonAbility)) {
280 MMI_HILOGE("JsonAbility is not object");
281 return false;
282 }
283 GetKeyVal(jsonAbility, "bundleName", ability.bundleName);
284 GetKeyVal(jsonAbility, "abilityName", ability.abilityName);
285 GetKeyVal(jsonAbility, "action", ability.action);
286 GetKeyVal(jsonAbility, "type", ability.type);
287 GetKeyVal(jsonAbility, "deviceId", ability.deviceId);
288 GetKeyVal(jsonAbility, "uri", ability.uri);
289 if (!GetEntities(jsonAbility, ability)) {
290 MMI_HILOGE("Get centities failed");
291 return false;
292 }
293 if (!GetParams(jsonAbility, ability)) {
294 MMI_HILOGE("Get params failed");
295 return false;
296 }
297 return true;
298 }
299
ConvertToShortcutKey(const cJSON * jsonData,ShortcutKey & shortcutKey,std::vector<std::string> & businessIds)300 bool ConvertToShortcutKey(const cJSON* jsonData, ShortcutKey &shortcutKey, std::vector<std::string> &businessIds)
301 {
302 if (!cJSON_IsObject(jsonData)) {
303 MMI_HILOGE("jsonData is not object");
304 return false;
305 }
306 if (!GetBusinessId(jsonData, shortcutKey.businessId, businessIds)) {
307 MMI_HILOGW("Get abilityKey failed");
308 }
309 if (!GetPreKeys(jsonData, shortcutKey)) {
310 MMI_HILOGE("Get preKeys failed");
311 return false;
312 }
313 if (!GetKeyFinalKey(jsonData, shortcutKey.finalKey)) {
314 MMI_HILOGE("Get finalKey failed");
315 return false;
316 }
317 if (!GetTrigger(jsonData, shortcutKey.triggerType)) {
318 MMI_HILOGE("Get trigger failed");
319 return false;
320 }
321 if (!GetKeyDownDuration(jsonData, shortcutKey.keyDownDuration)) {
322 MMI_HILOGE("Get downDuration failed");
323 return false;
324 }
325 cJSON *ability = cJSON_GetObjectItemCaseSensitive(jsonData, "ability");
326 if (!cJSON_IsObject(ability)) {
327 MMI_HILOGE("ability is not object");
328 return false;
329 }
330 if (!PackageAbility(ability, shortcutKey.ability)) {
331 MMI_HILOGE("Package ability failed");
332 return false;
333 }
334 return true;
335 }
336
GetKeyCode(const cJSON * jsonData,int32_t & keyCodeInt)337 bool GetKeyCode(const cJSON* jsonData, int32_t &keyCodeInt)
338 {
339 if (!cJSON_IsObject(jsonData)) {
340 MMI_HILOGE("jsonData is not object");
341 return false;
342 }
343 cJSON *keyCode = cJSON_GetObjectItemCaseSensitive(jsonData, "keyCode");
344 if (!cJSON_IsNumber(keyCode)) {
345 MMI_HILOGE("keyCode is not number");
346 return false;
347 }
348 if (keyCode->valueint < 0) {
349 MMI_HILOGE("keyCode must be number and bigger and equal zero");
350 return false;
351 }
352 keyCodeInt = keyCode->valueint;
353 return true;
354 }
355
GetKeyAction(const cJSON * jsonData,int32_t & keyActionInt)356 bool GetKeyAction(const cJSON* jsonData, int32_t &keyActionInt)
357 {
358 if (!cJSON_IsObject(jsonData)) {
359 MMI_HILOGE("jsonData is not object");
360 return false;
361 }
362 cJSON *keyAction = cJSON_GetObjectItemCaseSensitive(jsonData, "keyAction");
363 if (!cJSON_IsNumber(keyAction)) {
364 MMI_HILOGE("keyAction is not number");
365 return false;
366 }
367 if ((keyAction->valueint != KeyEvent::KEY_ACTION_DOWN) && (keyAction->valueint != KeyEvent::KEY_ACTION_UP)) {
368 MMI_HILOGE("keyAction must be down or up");
369 return false;
370 }
371 keyActionInt = keyAction->valueint;
372 return true;
373 }
374
GetDelay(const cJSON * jsonData,int64_t & delayInt)375 bool GetDelay(const cJSON* jsonData, int64_t &delayInt)
376 {
377 if (!cJSON_IsObject(jsonData)) {
378 MMI_HILOGE("jsonData is not object");
379 return false;
380 }
381 cJSON *delay = cJSON_GetObjectItemCaseSensitive(jsonData, "delay");
382 if (!cJSON_IsNumber(delay)) {
383 MMI_HILOGE("delay is not number");
384 return false;
385 }
386 if ((delay->valueint < 0) || (delay->valueint > MAX_DELAY_TIME)) {
387 MMI_HILOGE("delay must be number and bigger and equal zero and less than max delay");
388 return false;
389 }
390 delayInt = delay->valueint * SECONDS_SYSTEM;
391 return true;
392 }
393
GetAbilityStartDelay(const cJSON * jsonData,int64_t & abilityStartDelayInt)394 bool GetAbilityStartDelay(const cJSON* jsonData, int64_t &abilityStartDelayInt)
395 {
396 if (!cJSON_IsObject(jsonData)) {
397 MMI_HILOGE("jsonData is not object");
398 return false;
399 }
400 cJSON *abilityStartDelay = cJSON_GetObjectItemCaseSensitive(jsonData, "abilityStartDelay");
401 if (!cJSON_IsNumber(abilityStartDelay)) {
402 MMI_HILOGE("abilityStartDelay is not number");
403 return false;
404 }
405 if ((abilityStartDelay->valueint < 0) || (abilityStartDelay->valueint > MAX_DELAY_TIME)) {
406 MMI_HILOGE("abilityStartDelay must be number and bigger and equal zero and less than max delay time");
407 return false;
408 }
409 abilityStartDelayInt = abilityStartDelay->valueint;
410 return true;
411 }
412
PackageSequenceKey(const cJSON * sequenceKeysJson,SequenceKey & sequenceKey)413 bool PackageSequenceKey(const cJSON* sequenceKeysJson, SequenceKey &sequenceKey)
414 {
415 if (!cJSON_IsObject(sequenceKeysJson)) {
416 MMI_HILOGE("sequenceKeysJson is not object");
417 return false;
418 }
419 if (!GetKeyCode(sequenceKeysJson, sequenceKey.keyCode)) {
420 MMI_HILOGE("Get keyCode failed");
421 return false;
422 }
423 if (!GetKeyAction(sequenceKeysJson, sequenceKey.keyAction)) {
424 MMI_HILOGE("Get keyAction failed");
425 return false;
426 }
427 if (!GetDelay(sequenceKeysJson, sequenceKey.delay)) {
428 MMI_HILOGE("Get delay failed");
429 return false;
430 }
431 return true;
432 }
433
GetSequenceKeys(const cJSON * jsonData,Sequence & sequence)434 bool GetSequenceKeys(const cJSON* jsonData, Sequence &sequence)
435 {
436 if (!cJSON_IsObject(jsonData)) {
437 MMI_HILOGE("jsonData is not object");
438 return false;
439 }
440 cJSON* sequenceKeys = cJSON_GetObjectItemCaseSensitive(jsonData, "sequenceKeys");
441 if (!cJSON_IsArray(sequenceKeys)) {
442 MMI_HILOGE("sequenceKeys number must be array");
443 return false;
444 }
445 int32_t sequenceKeysSize = cJSON_GetArraySize(sequenceKeys);
446 if (sequenceKeysSize > MAX_SEQUENCEKEYS_NUM) {
447 MMI_HILOGE("sequenceKeysSize number must less and equal %{public}d", MAX_SEQUENCEKEYS_NUM);
448 return false;
449 }
450 for (int32_t i = 0; i < sequenceKeysSize; ++i) {
451 cJSON *sequenceKeysJson = cJSON_GetArrayItem(sequenceKeys, i);
452 if (!cJSON_IsObject(sequenceKeysJson)) {
453 MMI_HILOGE("sequenceKeysJson is not object");
454 return false;
455 }
456 SequenceKey sequenceKey;
457 if (!PackageSequenceKey(sequenceKeysJson, sequenceKey)) {
458 MMI_HILOGE("Packege sequenceKey failed");
459 return false;
460 }
461 sequence.sequenceKeys.push_back(sequenceKey);
462 }
463 return true;
464 }
465
IsSequenceKeysValid(const Sequence & sequence)466 bool IsSequenceKeysValid(const Sequence &sequence)
467 {
468 if (sequence.sequenceKeys.empty()) {
469 MMI_HILOGE("sequenceKeys can not be empty");
470 return false;
471 }
472
473 if (sequence.sequenceKeys.size() > MAX_SEQUENCEKEYS_NUM) {
474 MMI_HILOGE("sequenceKeys size must less or equal to %{public}d", MAX_SEQUENCEKEYS_NUM);
475 return false;
476 }
477
478 std::map<int32_t, SequenceKey> sequenceKeys;
479 for (const SequenceKey& item : sequence.sequenceKeys) {
480 if (sequenceKeys.find(item.keyCode) == sequenceKeys.end()) {
481 auto it = sequenceKeys.emplace(item.keyCode, item);
482 if (!it.second) {
483 MMI_HILOGE("Emplace duplicated");
484 return false;
485 }
486 } else {
487 if (sequenceKeys[item.keyCode].keyAction == item.keyAction) {
488 MMI_HILOGE("sequenceKeys illegal");
489 return false;
490 }
491 sequenceKeys[item.keyCode].keyAction = item.keyAction;
492 sequenceKeys[item.keyCode].delay = item.delay;
493 }
494 }
495 return true;
496 }
497
ConvertToKeySequence(const cJSON * jsonData,Sequence & sequence)498 bool ConvertToKeySequence(const cJSON* jsonData, Sequence &sequence)
499 {
500 if (!cJSON_IsObject(jsonData)) {
501 MMI_HILOGE("jsonData is not object");
502 return false;
503 }
504 if (!GetSequenceKeys(jsonData, sequence)) {
505 MMI_HILOGE("Get sequenceKeys failed");
506 return false;
507 }
508 if (!IsSequenceKeysValid(sequence)) {
509 MMI_HILOGE("Sequence invalid");
510 return false;
511 }
512 if (!GetAbilityStartDelay(jsonData, sequence.abilityStartDelay)) {
513 MMI_HILOGE("Get abilityStartDelay failed");
514 return false;
515 }
516 cJSON *ability = cJSON_GetObjectItemCaseSensitive(jsonData, "ability");
517 if (!cJSON_IsObject(ability)) {
518 MMI_HILOGE("ability is not object");
519 return false;
520 }
521 if (!PackageAbility(ability, sequence.ability)) {
522 MMI_HILOGE("Package ability failed");
523 return false;
524 }
525 return true;
526 }
527
GenerateKey(const ShortcutKey & key)528 std::string GenerateKey(const ShortcutKey& key)
529 {
530 std::set<int32_t> preKeys = key.preKeys;
531 std::stringstream ss;
532 for (const auto& preKey : preKeys) {
533 ss << preKey << ",";
534 }
535 ss << key.finalKey << ",";
536 ss << key.triggerType;
537 return std::string(ss.str());
538 }
539
ParseShortcutKeys(const JsonParser & parser,std::map<std::string,ShortcutKey> & shortcutKeyMap,std::vector<std::string> & businessIds)540 bool ParseShortcutKeys(const JsonParser& parser, std::map<std::string, ShortcutKey>& shortcutKeyMap,
541 std::vector<std::string>& businessIds)
542 {
543 cJSON* shortkeys = cJSON_GetObjectItemCaseSensitive(parser.json_, "Shortkeys");
544 if (!cJSON_IsArray(shortkeys)) {
545 MMI_HILOGE("shortkeys is not array");
546 return false;
547 }
548 int32_t shortkeysSize = cJSON_GetArraySize(shortkeys);
549 for (int32_t i = 0; i < shortkeysSize; ++i) {
550 ShortcutKey shortcutKey;
551 cJSON *shortkey = cJSON_GetArrayItem(shortkeys, i);
552 if (!cJSON_IsObject(shortkey)) {
553 continue;
554 }
555 if (!ConvertToShortcutKey(shortkey, shortcutKey, businessIds)) {
556 continue;
557 }
558 std::string key = GenerateKey(shortcutKey);
559 if (shortcutKeyMap.find(key) == shortcutKeyMap.end()) {
560 if (!shortcutKeyMap.emplace(key, shortcutKey).second) {
561 MMI_HILOGW("Duplicate shortcutKey:%{public}s", key.c_str());
562 }
563 }
564 }
565 return true;
566 }
567
ParseSequences(const JsonParser & parser,std::vector<Sequence> & sequenceVec)568 bool ParseSequences(const JsonParser& parser, std::vector<Sequence>& sequenceVec)
569 {
570 cJSON* sequences = cJSON_GetObjectItemCaseSensitive(parser.json_, "Sequences");
571 if (!cJSON_IsArray(sequences)) {
572 MMI_HILOGE("sequences is not array");
573 return false;
574 }
575 int32_t sequencesSize = cJSON_GetArraySize(sequences);
576 for (int32_t i = 0; i < sequencesSize; ++i) {
577 Sequence seq;
578 cJSON *sequence = cJSON_GetArrayItem(sequences, i);
579 if (!cJSON_IsObject(sequence)) {
580 continue;
581 }
582 if (!ConvertToKeySequence(sequence, seq)) {
583 continue;
584 }
585 sequenceVec.push_back(seq);
586 }
587 return true;
588 }
589
ParseTwoFingerGesture(const JsonParser & parser,TwoFingerGesture & gesture)590 bool ParseTwoFingerGesture(const JsonParser& parser, TwoFingerGesture& gesture)
591 {
592 cJSON *jsonData = cJSON_GetObjectItemCaseSensitive(parser.json_, "TwoFingerGesture");
593 if (!cJSON_IsObject(jsonData)) {
594 MMI_HILOGE("TwoFingerGesture is not object");
595 return false;
596 }
597 if (!GetAbilityStartDelay(jsonData, gesture.abilityStartDelay)) {
598 MMI_HILOGE("Get abilityStartDelay failed");
599 return false;
600 }
601 cJSON *ability = cJSON_GetObjectItemCaseSensitive(jsonData, "ability");
602 if (!cJSON_IsObject(ability)) {
603 MMI_HILOGE("ability is not object");
604 return false;
605 }
606 if (!PackageAbility(ability, gesture.ability)) {
607 MMI_HILOGE("Package ability failed");
608 return false;
609 }
610 gesture.active = true;
611 return true;
612 }
613
IsPackageKnuckleGesture(const cJSON * jsonData,const std::string knuckleGesture,Ability & launchAbility)614 bool IsPackageKnuckleGesture(const cJSON* jsonData, const std::string knuckleGesture, Ability &launchAbility)
615 {
616 cJSON *knuckleGestureData = cJSON_GetObjectItemCaseSensitive(jsonData, knuckleGesture.c_str());
617 if (!cJSON_IsObject(knuckleGestureData)) {
618 MMI_HILOGE("KnuckleGestureData is not object");
619 return false;
620 }
621 cJSON *ability = cJSON_GetObjectItemCaseSensitive(knuckleGestureData, "ability");
622 if (!cJSON_IsObject(ability)) {
623 MMI_HILOGE("Ability is not object");
624 return false;
625 }
626 if (!PackageAbility(ability, launchAbility)) {
627 MMI_HILOGE("Package ability failed");
628 return false;
629 }
630 return true;
631 }
632
IsParseKnuckleGesture(const JsonParser & parser,const std::string ability,KnuckleGesture & knuckleGesture)633 bool IsParseKnuckleGesture(const JsonParser &parser, const std::string ability, KnuckleGesture &knuckleGesture)
634 {
635 cJSON *jsonData = cJSON_GetObjectItemCaseSensitive(parser.json_, "KnuckleGesture");
636 if (!cJSON_IsObject(jsonData)) {
637 MMI_HILOGE("KnuckleGesture is not object");
638 return false;
639 }
640 if (!IsPackageKnuckleGesture(jsonData, ability, knuckleGesture.ability)) {
641 MMI_HILOGE("Package knuckle gesture failed");
642 return false;
643 }
644 return true;
645 }
646 } // namespace
647
648 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)649 void KeyCommandHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
650 {
651 CHKPV(keyEvent);
652 if (OnHandleEvent(keyEvent)) {
653 MMI_HILOGD("The keyEvent start launch an ability, keyCode:%{public}d", keyEvent->GetKeyCode());
654 BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::KEY_LAUNCH_EVENT);
655 return;
656 }
657 CHKPV(nextHandler_);
658 nextHandler_->HandleKeyEvent(keyEvent);
659 }
660 #endif // OHOS_BUILD_ENABLE_KEYBOARD
661
662 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)663 void KeyCommandHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
664 {
665 CHKPV(pointerEvent);
666 CHKPV(nextHandler_);
667 nextHandler_->HandlePointerEvent(pointerEvent);
668 }
669 #endif // OHOS_BUILD_ENABLE_POINTER
670
671 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)672 void KeyCommandHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
673 {
674 CHKPV(pointerEvent);
675 CHKPV(nextHandler_);
676 OnHandleTouchEvent(pointerEvent);
677 if (isKnuckleState_) {
678 MMI_HILOGD("current pointer event is knuckle");
679 return;
680 }
681 nextHandler_->HandleTouchEvent(pointerEvent);
682 }
683
OnHandleTouchEvent(const std::shared_ptr<PointerEvent> & touchEvent)684 void KeyCommandHandler::OnHandleTouchEvent(const std::shared_ptr<PointerEvent> &touchEvent)
685 {
686 CALL_DEBUG_ENTER;
687 CHKPV(touchEvent);
688 if (!isParseConfig_) {
689 if (!ParseConfig()) {
690 MMI_HILOGE("Parse configFile failed");
691 return;
692 }
693 isParseConfig_ = true;
694 }
695
696 switch (touchEvent->GetPointerAction()) {
697 case PointerEvent::POINTER_ACTION_CANCEL:
698 case PointerEvent::POINTER_ACTION_UP: {
699 HandlePointerActionUpEvent(touchEvent);
700 break;
701 }
702 case PointerEvent::POINTER_ACTION_MOVE: {
703 HandlePointerActionMoveEvent(touchEvent);
704 break;
705 }
706 case PointerEvent::POINTER_ACTION_DOWN: {
707 HandlePointerActionDownEvent(touchEvent);
708 break;
709 }
710 default:
711 // Don't care about other actions
712 MMI_HILOGW("other action not match.");
713 break;
714 }
715 }
716
HandlePointerActionDownEvent(const std::shared_ptr<PointerEvent> & touchEvent)717 void KeyCommandHandler::HandlePointerActionDownEvent(const std::shared_ptr<PointerEvent> &touchEvent)
718 {
719 CALL_DEBUG_ENTER;
720 CHKPV(touchEvent);
721 auto id = touchEvent->GetPointerId();
722 PointerEvent::PointerItem item;
723 touchEvent->GetPointerItem(id, item);
724 int32_t toolType = item.GetToolType();
725 MMI_HILOGD("Pointer tool type: %{public}d", toolType);
726 switch (toolType) {
727 case PointerEvent::TOOL_TYPE_FINGER: {
728 isKnuckleState_ = false;
729 HandleFingerGestureDownEvent(touchEvent);
730 break;
731 }
732 case PointerEvent::TOOL_TYPE_KNUCKLE: {
733 HandleKnuckleGestureDownEvent(touchEvent);
734 break;
735 }
736 default: {
737 // other tool type are not processed
738 isKnuckleState_ = false;
739 MMI_HILOGD("Current touch event tool type: %{public}d", toolType);
740 break;
741 }
742 }
743 }
744
HandlePointerActionMoveEvent(const std::shared_ptr<PointerEvent> & touchEvent)745 void KeyCommandHandler::HandlePointerActionMoveEvent(const std::shared_ptr<PointerEvent> &touchEvent)
746 {
747 CALL_DEBUG_ENTER;
748 if (!twoFingerGesture_.active) {
749 return;
750 }
751 if (twoFingerGesture_.timerId == -1) {
752 MMI_HILOGW("Two finger gesture timer id is -1.");
753 return;
754 }
755 auto id = touchEvent->GetPointerId();
756 auto pos = std::find_if(std::begin(twoFingerGesture_.touches), std::end(twoFingerGesture_.touches),
757 [id](const auto& item) { return item.id == id; });
758 if (pos == std::end(twoFingerGesture_.touches)) {
759 return;
760 }
761 PointerEvent::PointerItem item;
762 touchEvent->GetPointerItem(id, item);
763 auto dx = std::abs(pos->x - item.GetDisplayX());
764 auto dy = std::abs(pos->y - item.GetDisplayY());
765 if (dx > TOUCH_MAX_THRESHOLD || dy > TOUCH_MAX_THRESHOLD) {
766 StopTwoFingerGesture();
767 }
768 }
769
HandlePointerActionUpEvent(const std::shared_ptr<PointerEvent> & touchEvent)770 void KeyCommandHandler::HandlePointerActionUpEvent(const std::shared_ptr<PointerEvent> &touchEvent)
771 {
772 CALL_DEBUG_ENTER;
773 CHKPV(touchEvent);
774 auto id = touchEvent->GetPointerId();
775 PointerEvent::PointerItem item;
776 touchEvent->GetPointerItem(id, item);
777 int32_t toolType = item.GetToolType();
778 switch (toolType) {
779 case PointerEvent::TOOL_TYPE_FINGER: {
780 HandleFingerGestureUpEvent(touchEvent);
781 break;
782 }
783 case PointerEvent::TOOL_TYPE_KNUCKLE: {
784 HandleKnuckleGestureUpEvent(touchEvent);
785 break;
786 }
787 default: {
788 // other tool type are not processed
789 MMI_HILOGW("Current touch event tool type: %{public}d", toolType);
790 break;
791 }
792 }
793 }
794
HandleFingerGestureDownEvent(const std::shared_ptr<PointerEvent> & touchEvent)795 void KeyCommandHandler::HandleFingerGestureDownEvent(const std::shared_ptr<PointerEvent> &touchEvent)
796 {
797 CALL_DEBUG_ENTER;
798 if (!twoFingerGesture_.active) {
799 MMI_HILOGD("Two finger gesture is not active");
800 return;
801 }
802 auto num = touchEvent->GetPointerIds().size();
803 if (num == TwoFingerGesture::MAX_TOUCH_NUM) {
804 StartTwoFingerGesture();
805 } else {
806 StopTwoFingerGesture();
807 }
808 if (num > 0 && num <= TwoFingerGesture::MAX_TOUCH_NUM) {
809 auto id = touchEvent->GetPointerId();
810 PointerEvent::PointerItem item;
811 touchEvent->GetPointerItem(id, item);
812 twoFingerGesture_.touches[num - 1].id = id;
813 twoFingerGesture_.touches[num - 1].x = item.GetDisplayX();
814 twoFingerGesture_.touches[num - 1].y = item.GetDisplayY();
815 }
816 }
817
HandleFingerGestureUpEvent(const std::shared_ptr<PointerEvent> & touchEvent)818 void KeyCommandHandler::HandleFingerGestureUpEvent(const std::shared_ptr<PointerEvent> &touchEvent)
819 {
820 CALL_DEBUG_ENTER;
821 CHKPV(touchEvent);
822 if (!twoFingerGesture_.active) {
823 MMI_HILOGD("Two finger gesture is not active");
824 return;
825 }
826 StopTwoFingerGesture();
827 }
828
HandleKnuckleGestureDownEvent(const std::shared_ptr<PointerEvent> & touchEvent)829 void KeyCommandHandler::HandleKnuckleGestureDownEvent(const std::shared_ptr<PointerEvent> &touchEvent)
830 {
831 CALL_DEBUG_ENTER;
832 CHKPV(touchEvent);
833
834 auto id = touchEvent->GetPointerId();
835 PointerEvent::PointerItem item;
836 touchEvent->GetPointerItem(id, item);
837 if (item.GetToolType() != PointerEvent::TOOL_TYPE_KNUCKLE) {
838 MMI_HILOGW("Touch event tool type: %{public}d not knuckle", item.GetToolType());
839 return;
840 }
841 size_t size = touchEvent->GetPointerIds().size();
842 if (size == SINGEL_KNUCKLE_SIZE) {
843 SingleKnuckleGestureProcesser(touchEvent);
844 } else if (size == DOUBLE_KNUCKLE_SIZE) {
845 DoubleKnuckleGestureProcesser(touchEvent);
846 } else {
847 MMI_HILOGW("Other kunckle size not process, size: %{public}zu", size);
848 return;
849 }
850 }
851
HandleKnuckleGestureUpEvent(const std::shared_ptr<PointerEvent> & touchEvent)852 void KeyCommandHandler::HandleKnuckleGestureUpEvent(const std::shared_ptr<PointerEvent> &touchEvent)
853 {
854 CALL_DEBUG_ENTER;
855 CHKPV(touchEvent);
856 size_t size = touchEvent->GetPointerIds().size();
857 if (size == SINGEL_KNUCKLE_SIZE) {
858 singleKnuckleGesture_.lastPointerUpTime = touchEvent->GetActionTime();
859 } else if (size == DOUBLE_KNUCKLE_SIZE) {
860 doubleKnuckleGesture_.lastPointerUpTime = touchEvent->GetActionTime();
861 } else {
862 MMI_HILOGW("Other kunckle size not process, size: %{public}zu", size);
863 return;
864 }
865 }
866
SingleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> & touchEvent)867 void KeyCommandHandler::SingleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> &touchEvent)
868 {
869 CALL_DEBUG_ENTER;
870 CHKPV(touchEvent);
871 KnuckleGestureProcesser(touchEvent, singleKnuckleGesture_);
872 }
873
DoubleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> & touchEvent)874 void KeyCommandHandler::DoubleKnuckleGestureProcesser(const std::shared_ptr<PointerEvent> &touchEvent)
875 {
876 CALL_DEBUG_ENTER;
877 CHKPV(touchEvent);
878 if (singleKnuckleGesture_.state != NONE_CLICK_STATE) {
879 MMI_HILOGD("Single knuckle gesture not process");
880 singleKnuckleGesture_.state = NONE_CLICK_STATE;
881 if (singleKnuckleGesture_.timerId != -1) {
882 TimerMgr->RemoveTimer(singleKnuckleGesture_.timerId);
883 singleKnuckleGesture_.timerId = -1;
884 }
885 }
886 KnuckleGestureProcesser(touchEvent, doubleKnuckleGesture_);
887 }
888
KnuckleGestureProcesser(const std::shared_ptr<PointerEvent> & touchEvent,KnuckleGesture & knuckleGesture)889 void KeyCommandHandler::KnuckleGestureProcesser(const std::shared_ptr<PointerEvent> &touchEvent,
890 KnuckleGesture &knuckleGesture)
891 {
892 CALL_DEBUG_ENTER;
893 CHKPV(touchEvent);
894 int32_t state = knuckleGesture.state;
895 switch (state) {
896 case NONE_CLICK_STATE: {
897 MMI_HILOGD("Knuckle gesture first down event");
898 knuckleGesture.timerId = TimerMgr->AddTimer(DOUBLE_CLICK_INTERVAL_TIME, 1, [&knuckleGesture]() {
899 MMI_HILOGD("Knuckle gesture processor timer callback");
900 knuckleGesture.timerId = -1;
901 knuckleGesture.state = NONE_CLICK_STATE;
902 });
903 knuckleGesture.lastPointerDownEvent = touchEvent;
904 knuckleGesture.state = CLICK_STATE;
905 isKnuckleState_ = true;
906 break;
907 }
908 case CLICK_STATE: {
909 MMI_HILOGD("Knuckle gesture second down event");
910 knuckleGesture.downToPrevUpTime = touchEvent->GetActionTime() - knuckleGesture.lastPointerUpTime;
911 if (knuckleGesture.downToPrevUpTime < (static_cast<int64_t>(DOUBLE_CLICK_INTERVAL_TIME) * SECONDS_SYSTEM)) {
912 MMI_HILOGD("knuckle gesture start launch ability");
913 LaunchAbility(knuckleGesture.ability, 0);
914 if (knuckleGesture.timerId != -1) {
915 TimerMgr->RemoveTimer(knuckleGesture.timerId);
916 knuckleGesture.timerId = -1;
917 }
918 knuckleGesture.state = NONE_CLICK_STATE;
919 isKnuckleState_ = true;
920 }
921 break;
922 }
923 default: {
924 MMI_HILOGW("other state: %{public}d not process", state);
925 break;
926 }
927 }
928 }
929
StartTwoFingerGesture()930 void KeyCommandHandler::StartTwoFingerGesture()
931 {
932 CALL_DEBUG_ENTER;
933 twoFingerGesture_.timerId = TimerMgr->AddTimer(twoFingerGesture_.abilityStartDelay, 1, [this]() {
934 LaunchAbility(twoFingerGesture_.ability, twoFingerGesture_.abilityStartDelay);
935 twoFingerGesture_.timerId = -1;
936 });
937 }
938
StopTwoFingerGesture()939 void KeyCommandHandler::StopTwoFingerGesture()
940 {
941 CALL_DEBUG_ENTER;
942 if (twoFingerGesture_.timerId != -1) {
943 TimerMgr->RemoveTimer(twoFingerGesture_.timerId);
944 twoFingerGesture_.timerId = -1;
945 }
946 }
947 #endif // OHOS_BUILD_ENABLE_TOUCH
948
ParseConfig()949 bool KeyCommandHandler::ParseConfig()
950 {
951 const char *testPathSuffix = "/etc/multimodalinput/ability_launch_config.json";
952 char buf[MAX_PATH_LEN] = { 0 };
953 char *filePath = GetOneCfgFile(testPathSuffix, buf, MAX_PATH_LEN);
954 std::string defaultConfig = "/system/etc/multimodalinput/ability_launch_config.json";
955 if (filePath == nullptr || filePath[0] == '\0' || strlen(filePath) > MAX_PATH_LEN) {
956 MMI_HILOGD("Can not get customization config file");
957 return ParseJson(defaultConfig);
958 }
959 std::string customConfig = filePath;
960 MMI_HILOGD("The configuration file path is :%{public}s", customConfig.c_str());
961 return ParseJson(customConfig) || ParseJson(defaultConfig);
962 }
963
ParseJson(const std::string & configFile)964 bool KeyCommandHandler::ParseJson(const std::string &configFile)
965 {
966 CALL_DEBUG_ENTER;
967 std::string jsonStr = ReadJsonFile(configFile);
968 if (jsonStr.empty()) {
969 MMI_HILOGE("Read configFile failed");
970 return false;
971 }
972 JsonParser parser;
973 parser.json_ = cJSON_Parse(jsonStr.c_str());
974 if (!cJSON_IsObject(parser.json_)) {
975 MMI_HILOGE("Parser.json_ is not object");
976 return false;
977 }
978
979 bool isParseShortKeys = ParseShortcutKeys(parser, shortcutKeys_, businessIds_);
980 bool isParseSequences = ParseSequences(parser, sequences_);
981 bool isParseTwoFingerGesture = ParseTwoFingerGesture(parser, twoFingerGesture_);
982 bool isParseSingleKnuckleGesture = IsParseKnuckleGesture(parser, SINGLE_KNUCKLE_ABILITY, singleKnuckleGesture_);
983 bool isParseDoubleKnuckleGesture = IsParseKnuckleGesture(parser, DOUBLE_KNUCKLE_ABILITY, doubleKnuckleGesture_);
984 if (!isParseShortKeys && !isParseSequences && !isParseTwoFingerGesture && !isParseSingleKnuckleGesture &&
985 !isParseDoubleKnuckleGesture) {
986 MMI_HILOGE("Parse configFile failed");
987 return false;
988 }
989
990 Print();
991 PrintSeq();
992 return true;
993 }
994
Print()995 void KeyCommandHandler::Print()
996 {
997 MMI_HILOGD("shortcutKey count:%{public}zu", shortcutKeys_.size());
998 int32_t row = 0;
999 for (const auto &item : shortcutKeys_) {
1000 MMI_HILOGD("row:%{public}d", row++);
1001 auto &shortcutKey = item.second;
1002 for (const auto &prekey : shortcutKey.preKeys) {
1003 MMI_HILOGD("preKey:%{public}d", prekey);
1004 }
1005 MMI_HILOGD("finalKey:%{public}d, keyDownDuration:%{public}d, triggerType:%{public}d,"
1006 " bundleName:%{public}s, abilityName:%{public}s", shortcutKey.finalKey,
1007 shortcutKey.keyDownDuration, shortcutKey.triggerType,
1008 shortcutKey.ability.bundleName.c_str(), shortcutKey.ability.abilityName.c_str());
1009 }
1010 }
1011
PrintSeq()1012 void KeyCommandHandler::PrintSeq()
1013 {
1014 MMI_HILOGD("sequences count:%{public}zu", sequences_.size());
1015 int32_t row = 0;
1016 for (const auto &item : sequences_) {
1017 MMI_HILOGD("row:%{public}d", row++);
1018 for (const auto& sequenceKey : item.sequenceKeys) {
1019 MMI_HILOGD("keyCode:%{public}d, keyAction:%{public}d, delay:%{public}" PRId64,
1020 sequenceKey.keyCode, sequenceKey.keyAction, sequenceKey.delay);
1021 }
1022 MMI_HILOGD("bundleName:%{public}s, abilityName:%{public}s",
1023 item.ability.bundleName.c_str(), item.ability.abilityName.c_str());
1024 }
1025 }
1026
OnHandleEvent(const std::shared_ptr<KeyEvent> key)1027 bool KeyCommandHandler::OnHandleEvent(const std::shared_ptr<KeyEvent> key)
1028 {
1029 CALL_DEBUG_ENTER;
1030 CHKPF(key);
1031 if (!isParseConfig_) {
1032 if (!ParseConfig()) {
1033 MMI_HILOGE("Parse configFile failed");
1034 return false;
1035 }
1036 isParseConfig_ = true;
1037 }
1038
1039 bool isHandled = HandleShortKeys(key);
1040 isHandled = HandleSequences(key) || isHandled;
1041 if (isHandled) {
1042 return true;
1043 }
1044
1045 if (!specialKeys_.empty() && specialKeys_.find(key->GetKeyCode()) != specialKeys_.end()) {
1046 HandleSpecialKeys(key->GetKeyCode(), key->GetAction());
1047 return true;
1048 }
1049
1050 if (IsSpecialType(key->GetKeyCode(), SpecialType::SUBSCRIBER_BEFORE_DELAY)) {
1051 auto tmpKey = KeyEvent::Clone(key);
1052 int32_t timerId = TimerMgr->AddTimer(SPECIAL_KEY_DOWN_DELAY, 1, [this, tmpKey] () {
1053 MMI_HILOGD("Timer callback");
1054 auto it = specialTimers_.find(tmpKey->GetKeyCode());
1055 if (it != specialTimers_.end() && !it->second.empty()) {
1056 it->second.pop_front();
1057 }
1058 InputHandler->GetSubscriberHandler()->HandleKeyEvent(tmpKey);
1059 });
1060 if (timerId < 0) {
1061 MMI_HILOGE("Add timer failed");
1062 return false;
1063 }
1064
1065 auto it = specialTimers_.find(key->GetKeyCode());
1066 if (it == specialTimers_.end()) {
1067 std::list<int32_t> timerIds;
1068 timerIds.push_back(timerId);
1069 auto it = specialTimers_.emplace(key->GetKeyCode(), timerIds);
1070 if (!it.second) {
1071 MMI_HILOGE("Keycode duplicated");
1072 return false;
1073 }
1074 } else {
1075 it->second.push_back(timerId);
1076 }
1077 MMI_HILOGD("Add timer success");
1078 return true;
1079 }
1080
1081 return false;
1082 }
1083
HandleShortKeys(const std::shared_ptr<KeyEvent> keyEvent)1084 bool KeyCommandHandler::HandleShortKeys(const std::shared_ptr<KeyEvent> keyEvent)
1085 {
1086 CALL_DEBUG_ENTER;
1087 CHKPF(keyEvent);
1088 if (shortcutKeys_.empty()) {
1089 MMI_HILOGD("No shortkeys configuration data");
1090 return false;
1091 }
1092 if (IsKeyMatch(lastMatchedKey_, keyEvent)) {
1093 MMI_HILOGD("The same key is waiting timeout, skip");
1094 return true;
1095 }
1096 if (currentLaunchAbilityKey_.timerId >= 0 && IsKeyMatch(currentLaunchAbilityKey_, keyEvent)) {
1097 MMI_HILOGD("repeat, current key %{public}d has launched ability", currentLaunchAbilityKey_.finalKey);
1098 return true;
1099 }
1100 DfxHisysevent::GetComboStartTime();
1101 if (lastMatchedKey_.timerId >= 0) {
1102 MMI_HILOGD("Remove timer:%{public}d", lastMatchedKey_.timerId);
1103 TimerMgr->RemoveTimer(lastMatchedKey_.timerId);
1104 }
1105 ResetLastMatchedKey();
1106 for (auto &item : shortcutKeys_) {
1107 ShortcutKey &shortcutKey = item.second;
1108 if (!IsKeyMatch(shortcutKey, keyEvent)) {
1109 MMI_HILOGD("Not key matched, next");
1110 continue;
1111 }
1112 int32_t delay = GetKeyDownDurationFromXml(shortcutKey.businessId);
1113 if (delay >= MIN_SHORT_KEY_DOWN_DURATION && delay <= MAX_SHORT_KEY_DOWN_DURATION) {
1114 MMI_HILOGD("User defined new short key down duration: %{public}d", delay);
1115 shortcutKey.keyDownDuration = delay;
1116 }
1117 shortcutKey.Print();
1118 if (shortcutKey.triggerType == KeyEvent::KEY_ACTION_DOWN) {
1119 return HandleKeyDown(shortcutKey);
1120 } else if (shortcutKey.triggerType == KeyEvent::KEY_ACTION_UP) {
1121 return HandleKeyUp(keyEvent, shortcutKey);
1122 } else {
1123 return HandleKeyCancel(shortcutKey);
1124 }
1125 }
1126 return HandleConsumedKeyEvent(keyEvent);
1127 }
1128
HandleConsumedKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)1129 bool KeyCommandHandler::HandleConsumedKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
1130 {
1131 CALL_DEBUG_ENTER;
1132 CHKPF(keyEvent);
1133 if (currentLaunchAbilityKey_.finalKey == keyEvent->GetKeyCode()
1134 && keyEvent->GetKeyAction() == KeyEvent::KEY_ACTION_UP) {
1135 MMI_HILOGD("Handle consumed key event, cancel opration");
1136 ResetCurrentLaunchAbilityKey();
1137 auto keyEventCancel = std::make_shared<KeyEvent>(*keyEvent);
1138 keyEventCancel->SetKeyAction(KeyEvent::KEY_ACTION_CANCEL);
1139 auto inputEventNormalizeHandler = InputHandler->GetEventNormalizeHandler();
1140 CHKPF(inputEventNormalizeHandler);
1141 inputEventNormalizeHandler->HandleKeyEvent(keyEventCancel);
1142 return true;
1143 }
1144 return false;
1145 }
1146
IsRepeatKeyEvent(const SequenceKey & sequenceKey)1147 bool KeyCommandHandler::IsRepeatKeyEvent(const SequenceKey &sequenceKey)
1148 {
1149 for (size_t i = keys_.size(); i > 0; --i) {
1150 if (keys_[i-1].keyCode == sequenceKey.keyCode) {
1151 if (keys_[i-1].keyAction == sequenceKey.keyAction) {
1152 MMI_HILOGD("Is repeat key, keyCode:%{public}d", sequenceKey.keyCode);
1153 return true;
1154 }
1155 MMI_HILOGD("Is not repeat key");
1156 return false;
1157 }
1158 }
1159 return false;
1160 }
1161
HandleSequences(const std::shared_ptr<KeyEvent> keyEvent)1162 bool KeyCommandHandler::HandleSequences(const std::shared_ptr<KeyEvent> keyEvent)
1163 {
1164 CALL_DEBUG_ENTER;
1165 CHKPF(keyEvent);
1166 if (sequences_.empty()) {
1167 MMI_HILOGD("No sequences configuration data");
1168 return false;
1169 }
1170
1171 if (!AddSequenceKey(keyEvent)) {
1172 MMI_HILOGD("Add new sequence key failed");
1173 return false;
1174 }
1175
1176 if (filterSequences_.empty()) {
1177 filterSequences_ = sequences_;
1178 }
1179
1180 bool isLaunchAbility = false;
1181 std::vector<Sequence> tempSeqs;
1182 for (Sequence& item : filterSequences_) {
1183 if (HandleSequence(item, isLaunchAbility)) {
1184 tempSeqs.push_back(item);
1185 }
1186 }
1187
1188 if (isLaunchAbility) {
1189 for (const auto& item : keys_) {
1190 if (IsSpecialType(item.keyCode, SpecialType::KEY_DOWN_ACTION)) {
1191 HandleSpecialKeys(item.keyCode, item.keyAction);
1192 }
1193 InputHandler->GetSubscriberHandler()->RemoveSubscriberKeyUpTimer(item.keyCode);
1194 RemoveSubscribedTimer(item.keyCode);
1195 }
1196 }
1197
1198 if (tempSeqs.empty()) {
1199 MMI_HILOGD("No matching sequence found");
1200 } else {
1201 filterSequences_ = tempSeqs;
1202 }
1203 return isLaunchAbility;
1204 }
1205
AddSequenceKey(const std::shared_ptr<KeyEvent> keyEvent)1206 bool KeyCommandHandler::AddSequenceKey(const std::shared_ptr<KeyEvent> keyEvent)
1207 {
1208 CALL_DEBUG_ENTER;
1209 CHKPF(keyEvent);
1210 SequenceKey sequenceKey;
1211 sequenceKey.keyCode = keyEvent->GetKeyCode();
1212 sequenceKey.keyAction = keyEvent->GetKeyAction();
1213 sequenceKey.actionTime = keyEvent->GetActionTime();
1214 size_t size = keys_.size();
1215 if (size > 0) {
1216 if (keys_[size - 1].actionTime > sequenceKey.actionTime) {
1217 MMI_HILOGE("The current event time is greater than the last event time");
1218 ResetSequenceKeys();
1219 return false;
1220 }
1221 if ((sequenceKey.actionTime - keys_[size - 1].actionTime) > MAX_DELAY_TIME) {
1222 MMI_HILOGD("The delay time is greater than the maximum delay time");
1223 ResetSequenceKeys();
1224 } else {
1225 if (IsRepeatKeyEvent(sequenceKey)) {
1226 MMI_HILOGD("This is a repeat key event, don't add");
1227 return false;
1228 }
1229 keys_[size - 1].delay = sequenceKey.actionTime - keys_[size - 1].actionTime;
1230 InterruptTimers();
1231 }
1232 }
1233 if (size > MAX_SEQUENCEKEYS_NUM) {
1234 MMI_HILOGD("The save key size more than the max size");
1235 return false;
1236 }
1237 keys_.push_back(sequenceKey);
1238 return true;
1239 }
1240
HandleSequence(Sequence & sequence,bool & isLaunchAbility)1241 bool KeyCommandHandler::HandleSequence(Sequence &sequence, bool &isLaunchAbility)
1242 {
1243 CALL_DEBUG_ENTER;
1244 size_t keysSize = keys_.size();
1245 size_t sequenceKeysSize = sequence.sequenceKeys.size();
1246 if (keysSize > sequenceKeysSize) {
1247 MMI_HILOGD("The save sequence not matching ability sequence");
1248 return false;
1249 }
1250
1251 for (size_t i = 0; i < keysSize; ++i) {
1252 if (keys_[i] != sequence.sequenceKeys[i]) {
1253 MMI_HILOGD("The keyCode or keyAction not matching");
1254 return false;
1255 }
1256 int64_t delay = sequence.sequenceKeys[i].delay;
1257 if (((i + 1) != keysSize) && (delay != 0) && (keys_[i].delay >= delay)) {
1258 MMI_HILOGD("Delay is not matching");
1259 return false;
1260 }
1261 }
1262
1263 if (keysSize == sequenceKeysSize) {
1264 if (sequence.abilityStartDelay == 0) {
1265 MMI_HILOGD("Start launch ability immediately");
1266 LaunchAbility(sequence);
1267 isLaunchAbility = true;
1268 return true;
1269 }
1270 sequence.timerId = TimerMgr->AddTimer(sequence.abilityStartDelay, 1, [this, sequence] () {
1271 MMI_HILOGD("Timer callback");
1272 LaunchAbility(sequence);
1273 });
1274 if (sequence.timerId < 0) {
1275 MMI_HILOGE("Add Timer failed");
1276 return false;
1277 }
1278 MMI_HILOGD("Add timer success");
1279 isLaunchAbility = true;
1280 }
1281 return true;
1282 }
1283
IsKeyMatch(const ShortcutKey & shortcutKey,const std::shared_ptr<KeyEvent> & key)1284 bool KeyCommandHandler::IsKeyMatch(const ShortcutKey &shortcutKey, const std::shared_ptr<KeyEvent> &key)
1285 {
1286 CALL_DEBUG_ENTER;
1287 CHKPF(key);
1288 if ((key->GetKeyCode() != shortcutKey.finalKey) || (shortcutKey.triggerType != key->GetKeyAction())) {
1289 return false;
1290 }
1291 if ((shortcutKey.preKeys.size() + 1) != key->GetKeyItems().size()) {
1292 return false;
1293 }
1294 for (const auto &item : key->GetKeyItems()) {
1295 int32_t keyCode = item.GetKeyCode();
1296 if (SkipFinalKey(keyCode, key)) {
1297 continue;
1298 }
1299 if (shortcutKey.preKeys.find(keyCode) == shortcutKey.preKeys.end()) {
1300 return false;
1301 }
1302 }
1303 MMI_HILOGD("Leave, key matched");
1304 return true;
1305 }
1306
SkipFinalKey(const int32_t keyCode,const std::shared_ptr<KeyEvent> & key)1307 bool KeyCommandHandler::SkipFinalKey(const int32_t keyCode, const std::shared_ptr<KeyEvent> &key)
1308 {
1309 CHKPF(key);
1310 return keyCode == key->GetKeyCode();
1311 }
1312
HandleKeyDown(ShortcutKey & shortcutKey)1313 bool KeyCommandHandler::HandleKeyDown(ShortcutKey &shortcutKey)
1314 {
1315 CALL_DEBUG_ENTER;
1316 if (shortcutKey.keyDownDuration == 0) {
1317 MMI_HILOGD("Start launch ability immediately");
1318 LaunchAbility(shortcutKey);
1319 return true;
1320 }
1321 shortcutKey.timerId = TimerMgr->AddTimer(shortcutKey.keyDownDuration, 1, [this, shortcutKey] () {
1322 MMI_HILOGD("Timer callback");
1323 currentLaunchAbilityKey_ = shortcutKey;
1324 LaunchAbility(shortcutKey);
1325 });
1326 if (shortcutKey.timerId < 0) {
1327 MMI_HILOGE("Add Timer failed");
1328 return false;
1329 }
1330 MMI_HILOGD("Add timer success");
1331 lastMatchedKey_ = shortcutKey;
1332 if (InputHandler->GetSubscriberHandler()->IsKeyEventSubscribed(shortcutKey.finalKey, shortcutKey.triggerType)) {
1333 MMI_HILOGD("current shortcutKey %{public}d is subSubcribed", shortcutKey.finalKey);
1334 return false;
1335 }
1336 return true;
1337 }
1338
GetKeyDownDurationFromXml(const std::string & businessId)1339 int32_t KeyCommandHandler::GetKeyDownDurationFromXml(const std::string &businessId)
1340 {
1341 CALL_DEBUG_ENTER;
1342 std::shared_ptr<NativePreferences::Preferences> pref =
1343 NativePreferences::PreferencesHelper::GetPreferences(shortKeyFileName, errno);
1344 CHKPR(pref, ERROR_DELAY_VALUE);
1345 return pref->GetInt(businessId, ERROR_DELAY_VALUE);
1346 }
1347
HandleKeyUp(const std::shared_ptr<KeyEvent> & keyEvent,const ShortcutKey & shortcutKey)1348 bool KeyCommandHandler::HandleKeyUp(const std::shared_ptr<KeyEvent> &keyEvent, const ShortcutKey &shortcutKey)
1349 {
1350 CALL_DEBUG_ENTER;
1351 CHKPF(keyEvent);
1352 if (shortcutKey.keyDownDuration == 0) {
1353 MMI_HILOGD("Start launch ability immediately");
1354 LaunchAbility(shortcutKey);
1355 return true;
1356 }
1357 std::optional<KeyEvent::KeyItem> keyItem = keyEvent->GetKeyItem();
1358 if (!keyItem) {
1359 MMI_HILOGE("The keyItem is nullopt");
1360 return false;
1361 }
1362 auto upTime = keyEvent->GetActionTime();
1363 auto downTime = keyItem->GetDownTime();
1364 MMI_HILOGD("upTime:%{public}" PRId64 ",downTime:%{public}" PRId64 ",keyDownDuration:%{public}d",
1365 upTime, downTime, shortcutKey.keyDownDuration);
1366 if (upTime - downTime >= static_cast<int64_t>(shortcutKey.keyDownDuration) * 1000) {
1367 MMI_HILOGD("Skip, upTime - downTime >= duration");
1368 return false;
1369 }
1370 MMI_HILOGD("Start launch ability immediately");
1371 LaunchAbility(shortcutKey);
1372 return true;
1373 }
1374
HandleKeyCancel(ShortcutKey & shortcutKey)1375 bool KeyCommandHandler::HandleKeyCancel(ShortcutKey &shortcutKey)
1376 {
1377 CALL_DEBUG_ENTER;
1378 if (shortcutKey.timerId < 0) {
1379 MMI_HILOGE("Skip, timerid less than 0");
1380 }
1381 auto timerId = shortcutKey.timerId;
1382 shortcutKey.timerId = -1;
1383 TimerMgr->RemoveTimer(timerId);
1384 MMI_HILOGD("timerId:%{public}d", timerId);
1385 return false;
1386 }
1387
LaunchAbility(const Ability & ability,int64_t delay)1388 void KeyCommandHandler::LaunchAbility(const Ability &ability, int64_t delay)
1389 {
1390 CALL_DEBUG_ENTER;
1391 AAFwk::Want want;
1392 want.SetElementName(ability.deviceId, ability.bundleName, ability.abilityName);
1393 want.SetAction(ability.action);
1394 want.SetUri(ability.uri);
1395 want.SetType(ability.uri);
1396 for (const auto &entity : ability.entities) {
1397 want.AddEntity(entity);
1398 }
1399 for (const auto &item : ability.params) {
1400 want.SetParam(item.first, item.second);
1401 }
1402 DfxHisysevent::CalcComboStartTimes(delay);
1403 DfxHisysevent::ReportComboStartTimes();
1404 MMI_HILOGD("Start launch ability, bundleName:%{public}s", ability.bundleName.c_str());
1405 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
1406 if (err != ERR_OK) {
1407 MMI_HILOGE("LaunchAbility failed, bundleName:%{public}s, err:%{public}d", ability.bundleName.c_str(), err);
1408 }
1409 MMI_HILOGD("End launch ability, bundleName:%{public}s", ability.bundleName.c_str());
1410 }
1411
LaunchAbility(const ShortcutKey & key)1412 void KeyCommandHandler::LaunchAbility(const ShortcutKey &key)
1413 {
1414 CALL_INFO_TRACE;
1415 LaunchAbility(key.ability, lastMatchedKey_.keyDownDuration);
1416 ResetLastMatchedKey();
1417 }
1418
LaunchAbility(const Sequence & sequence)1419 void KeyCommandHandler::LaunchAbility(const Sequence &sequence)
1420 {
1421 CALL_INFO_TRACE;
1422 LaunchAbility(sequence.ability, sequence.abilityStartDelay);
1423 }
1424
Print() const1425 void ShortcutKey::Print() const
1426 {
1427 for (const auto &prekey: preKeys) {
1428 MMI_HILOGI("Eventkey matched, preKey:%{public}d", prekey);
1429 }
1430 MMI_HILOGD("Eventkey matched, finalKey:%{public}d, bundleName:%{public}s",
1431 finalKey, ability.bundleName.c_str());
1432 }
1433
RemoveSubscribedTimer(int32_t keyCode)1434 void KeyCommandHandler::RemoveSubscribedTimer(int32_t keyCode)
1435 {
1436 CALL_DEBUG_ENTER;
1437 auto iter = specialTimers_.find(keyCode);
1438 if (iter != specialTimers_.end()) {
1439 for (auto& item : iter->second) {
1440 TimerMgr->RemoveTimer(item);
1441 }
1442 specialTimers_.erase(keyCode);
1443 MMI_HILOGD("Remove timer success");
1444 }
1445 }
1446
HandleSpecialKeys(int32_t keyCode,int32_t keyAction)1447 void KeyCommandHandler::HandleSpecialKeys(int32_t keyCode, int32_t keyAction)
1448 {
1449 CALL_DEBUG_ENTER;
1450 auto iter = specialKeys_.find(keyCode);
1451 if (keyAction == KeyEvent::KEY_ACTION_UP) {
1452 if (iter != specialKeys_.end()) {
1453 specialKeys_.erase(iter);
1454 return;
1455 }
1456 }
1457
1458 if (keyAction == KeyEvent::KEY_ACTION_DOWN) {
1459 if (iter == specialKeys_.end()) {
1460 auto it = specialKeys_.emplace(keyCode, keyAction);
1461 if (!it.second) {
1462 MMI_HILOGD("KeyCode duplicated");
1463 return;
1464 }
1465 }
1466 }
1467 }
1468
InterruptTimers()1469 void KeyCommandHandler::InterruptTimers()
1470 {
1471 for (Sequence& item : filterSequences_) {
1472 if (item.timerId >= 0) {
1473 MMI_HILOGD("The key sequence change, close the timer");
1474 TimerMgr->RemoveTimer(item.timerId);
1475 item.timerId = -1;
1476 }
1477 }
1478 }
1479
UpdateSettingsXml(const std::string & businessId,int32_t delay)1480 int32_t KeyCommandHandler::UpdateSettingsXml(const std::string &businessId, int32_t delay)
1481 {
1482 CALL_DEBUG_ENTER;
1483 if (businessId.empty() || businessIds_.empty()) {
1484 MMI_HILOGE("businessId or businessIds_ is empty");
1485 return COMMON_PARAMETER_ERROR;
1486 }
1487 if (std::find(businessIds_.begin(), businessIds_.end(), businessId) == businessIds_.end()) {
1488 MMI_HILOGE("%{public}s not in the config file", businessId.c_str());
1489 return COMMON_PARAMETER_ERROR;
1490 }
1491 if (delay < MIN_SHORT_KEY_DOWN_DURATION || delay > MAX_SHORT_KEY_DOWN_DURATION) {
1492 MMI_HILOGE("delay is not in valid range.");
1493 return COMMON_PARAMETER_ERROR;
1494 }
1495 std::shared_ptr<NativePreferences::Preferences> pref =
1496 NativePreferences::PreferencesHelper::GetPreferences(shortKeyFileName, errno);
1497 CHKPR(pref, errno);
1498 pref->PutInt(businessId, delay);
1499 int32_t ret = pref->FlushSync();
1500 if (ret != RET_OK) {
1501 MMI_HILOGE("Flush Sync failed, ret: %{public}d", ret);
1502 return ret;
1503 }
1504 return RET_OK;
1505 }
1506
GetSingleKnuckleGesture()1507 KnuckleGesture KeyCommandHandler::GetSingleKnuckleGesture()
1508 {
1509 return singleKnuckleGesture_;
1510 }
GetDoubleKnuckleGesture()1511 KnuckleGesture KeyCommandHandler::GetDoubleKnuckleGesture()
1512 {
1513 return doubleKnuckleGesture_;
1514 }
1515 } // namespace MMI
1516 } // namespace OHOS
1517