• 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_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