• 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 "dfx_hisysevent.h"
19 #include "ability_manager_client.h"
20 #include "bytrace_adapter.h"
21 #include "cJSON.h"
22 #include "config_policy_utils.h"
23 #include "define_multimodal.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 OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "KeyCommandHandler" };
43 enum SpecialType {
44     SPECIAL_ALL = 0,
45     SUBSCRIBER_BEFORE_DELAY = 1,
46     KEY_DOWN_ACTION = 2
47 };
48 const std::map<int32_t, SpecialType> SPECIAL_KEYS = {
49     { KeyEvent::KEYCODE_POWER, SpecialType::KEY_DOWN_ACTION },
50     { KeyEvent::KEYCODE_VOLUME_DOWN, SpecialType::SPECIAL_ALL },
51     { KeyEvent::KEYCODE_VOLUME_UP, SpecialType::SPECIAL_ALL }
52 };
53 struct JsonParser {
54     JsonParser() = default;
~JsonParserOHOS::MMI::__anona024e3270111::JsonParser55     ~JsonParser()
56     {
57         if (json_ != nullptr) {
58             cJSON_Delete(json_);
59         }
60     }
operator cJSON*OHOS::MMI::__anona024e3270111::JsonParser61     operator cJSON *()
62     {
63         return json_;
64     }
65     cJSON *json_ { nullptr };
66 };
67 
IsSpecialType(int32_t keyCode,SpecialType type)68 bool IsSpecialType(int32_t keyCode, SpecialType type)
69 {
70     auto it = SPECIAL_KEYS.find(keyCode);
71     if (it == SPECIAL_KEYS.end()) {
72         return false;
73     }
74     return (it->second == SpecialType::SPECIAL_ALL || it->second == type);
75 }
76 
GetPreKeys(const cJSON * jsonData,ShortcutKey & shortcutKey)77 bool GetPreKeys(const cJSON* jsonData, ShortcutKey &shortcutKey)
78 {
79     if (!cJSON_IsObject(jsonData)) {
80         MMI_HILOGE("jsonData is not object");
81         return false;
82     }
83     cJSON* preKey = cJSON_GetObjectItemCaseSensitive(jsonData, "preKey");
84     if (!cJSON_IsArray(preKey)) {
85         MMI_HILOGE("preKey number must be array");
86         return false;
87     }
88     int32_t preKeySize = cJSON_GetArraySize(preKey);
89     if (preKeySize > MAX_PREKEYS_NUM) {
90         MMI_HILOGE("preKeySize number must less and equal four");
91         return false;
92     }
93     for (int32_t i = 0; i < preKeySize; ++i) {
94         cJSON *preKeyJson = cJSON_GetArrayItem(preKey, i);
95         if (!cJSON_IsNumber(preKeyJson)) {
96             MMI_HILOGE("preKeyJson is not number");
97             return false;
98         }
99         if (preKeyJson->valueint < 0) {
100             MMI_HILOGE("preKeyJson must be number and bigger or equal than 0");
101             return false;
102         }
103         if (!shortcutKey.preKeys.emplace(preKeyJson->valueint).second) {
104             MMI_HILOGE("preKeyJson must be unduplicated");
105             return false;
106         }
107     }
108     return true;
109 }
110 
GetTrigger(const cJSON * jsonData,int32_t & triggerType)111 bool GetTrigger(const cJSON* jsonData, int32_t &triggerType)
112 {
113     if (!cJSON_IsObject(jsonData)) {
114         MMI_HILOGE("jsonData is not object");
115         return false;
116     }
117     cJSON *trigger = cJSON_GetObjectItemCaseSensitive(jsonData, "trigger");
118     if (!cJSON_IsString(trigger)) {
119         MMI_HILOGE("trigger is not string");
120         return false;
121     }
122     if (((std::strcmp(trigger->valuestring, "key_up") != 0)
123         && (std::strcmp(trigger->valuestring, "key_down") != 0))) {
124         MMI_HILOGE("trigger must be one of [key_up, key_down]");
125         return false;
126     }
127     if (std::strcmp(trigger->valuestring, "key_up") == 0) {
128         triggerType = KeyEvent::KEY_ACTION_UP;
129     } else {
130         triggerType = KeyEvent::KEY_ACTION_DOWN;
131     }
132     return true;
133 }
134 
GetKeyDownDuration(const cJSON * jsonData,int32_t & keyDownDurationInt)135 bool GetKeyDownDuration(const cJSON* jsonData, int32_t &keyDownDurationInt)
136 {
137     if (!cJSON_IsObject(jsonData)) {
138         MMI_HILOGE("jsonData is not object");
139         return false;
140     }
141     cJSON *keyDownDuration = cJSON_GetObjectItemCaseSensitive(jsonData, "keyDownDuration");
142     if (!cJSON_IsNumber(keyDownDuration)) {
143         MMI_HILOGE("keyDownDuration is not number");
144         return false;
145     }
146     if (keyDownDuration->valueint < 0) {
147         MMI_HILOGE("keyDownDuration must be number and bigger and equal zero");
148         return false;
149     }
150     keyDownDurationInt = keyDownDuration->valueint;
151     return true;
152 }
153 
GetKeyFinalKey(const cJSON * jsonData,int32_t & finalKeyInt)154 bool GetKeyFinalKey(const cJSON* jsonData, int32_t &finalKeyInt)
155 {
156     if (!cJSON_IsObject(jsonData)) {
157         MMI_HILOGE("jsonData is not object");
158         return false;
159     }
160     cJSON *finalKey = cJSON_GetObjectItemCaseSensitive(jsonData, "finalKey");
161     if (!cJSON_IsNumber(finalKey)) {
162         MMI_HILOGE("finalKey must be number");
163         return false;
164     }
165     finalKeyInt = finalKey->valueint;
166     return true;
167 }
168 
GetKeyVal(const cJSON * json,const std::string & key,std::string & value)169 void GetKeyVal(const cJSON* json, const std::string &key, std::string &value)
170 {
171     if (!cJSON_IsObject(json)) {
172         MMI_HILOGE("json is not object");
173         return;
174     }
175     cJSON *valueJson = cJSON_GetObjectItemCaseSensitive(json, key.c_str());
176     if (cJSON_IsString(valueJson)) {
177         value = valueJson->valuestring;
178     }
179     return;
180 }
181 
GetEntities(const cJSON * jsonAbility,Ability & ability)182 bool GetEntities(const cJSON* jsonAbility, Ability &ability)
183 {
184     if (!cJSON_IsObject(jsonAbility)) {
185         MMI_HILOGE("jsonAbility is not object");
186         return false;
187     }
188     cJSON *entities = cJSON_GetObjectItemCaseSensitive(jsonAbility, "entities");
189     if (!cJSON_IsArray(entities)) {
190         MMI_HILOGE("entities must be array");
191         return false;
192     }
193     int32_t entitySize = cJSON_GetArraySize(entities);
194     for (int32_t i = 0; i < entitySize; i++) {
195         cJSON* entity = cJSON_GetArrayItem(entities, i);
196         if (!cJSON_IsString(entity)) {
197             MMI_HILOGE("entity is not string");
198             return false;
199         }
200         ability.entities.push_back(entity->valuestring);
201     }
202     return true;
203 }
204 
GetParams(const cJSON * jsonAbility,Ability & ability)205 bool GetParams(const cJSON* jsonAbility, Ability &ability)
206 {
207     if (!cJSON_IsObject(jsonAbility)) {
208         MMI_HILOGE("jsonAbility is not object");
209         return false;
210     }
211     cJSON *params = cJSON_GetObjectItemCaseSensitive(jsonAbility, "params");
212     if (!cJSON_IsArray(params)) {
213         MMI_HILOGE("params must be array");
214         return false;
215     }
216     int32_t paramsSize = cJSON_GetArraySize(params);
217     for (int32_t i = 0; i < paramsSize; ++i) {
218         cJSON* param = cJSON_GetArrayItem(params, i);
219         if (!cJSON_IsObject(param)) {
220             MMI_HILOGE("param must be object");
221             return false;
222         }
223         cJSON* key = cJSON_GetObjectItemCaseSensitive(param, "key");
224         if (!cJSON_IsString(key)) {
225             MMI_HILOGE("key is not string");
226             return false;
227         }
228         cJSON* value = cJSON_GetObjectItemCaseSensitive(param, "value");
229         if (!cJSON_IsString(value)) {
230             MMI_HILOGE("value is not string");
231             return false;
232         }
233         auto ret = ability.params.emplace(key->valuestring, value->valuestring);
234         if (!ret.second) {
235             MMI_HILOGW("Emplace to failed");
236         }
237     }
238     return true;
239 }
240 
PackageAbility(const cJSON * jsonAbility,Ability & ability)241 bool PackageAbility(const cJSON* jsonAbility, Ability &ability)
242 {
243     if (!cJSON_IsObject(jsonAbility)) {
244         MMI_HILOGE("JsonAbility is not object");
245         return false;
246     }
247     GetKeyVal(jsonAbility, "bundleName", ability.bundleName);
248     GetKeyVal(jsonAbility, "abilityName", ability.abilityName);
249     GetKeyVal(jsonAbility, "action", ability.action);
250     GetKeyVal(jsonAbility, "type", ability.type);
251     GetKeyVal(jsonAbility, "deviceId", ability.deviceId);
252     GetKeyVal(jsonAbility, "uri", ability.uri);
253     if (!GetEntities(jsonAbility, ability)) {
254         MMI_HILOGE("Get centities failed");
255         return false;
256     }
257     if (!GetParams(jsonAbility, ability)) {
258         MMI_HILOGE("Get params failed");
259         return false;
260     }
261     return true;
262 }
263 
ConvertToShortcutKey(const cJSON * jsonData,ShortcutKey & shortcutKey)264 bool ConvertToShortcutKey(const cJSON* jsonData, ShortcutKey &shortcutKey)
265 {
266     if (!cJSON_IsObject(jsonData)) {
267         MMI_HILOGE("jsonData is not object");
268         return false;
269     }
270     if (!GetPreKeys(jsonData, shortcutKey)) {
271         MMI_HILOGE("Get preKeys failed");
272         return false;
273     }
274     if (!GetKeyFinalKey(jsonData, shortcutKey.finalKey)) {
275         MMI_HILOGE("Get finalKey failed");
276         return false;
277     }
278     if (!GetTrigger(jsonData, shortcutKey.triggerType)) {
279         MMI_HILOGE("Get trigger failed");
280         return false;
281     }
282     if (!GetKeyDownDuration(jsonData, shortcutKey.keyDownDuration)) {
283         MMI_HILOGE("Get downDuration failed");
284         return false;
285     }
286     cJSON *ability = cJSON_GetObjectItemCaseSensitive(jsonData, "ability");
287     if (!cJSON_IsObject(ability)) {
288         MMI_HILOGE("ability is not object");
289         return false;
290     }
291     if (!PackageAbility(ability, shortcutKey.ability)) {
292         MMI_HILOGE("Package ability failed");
293         return false;
294     }
295     return true;
296 }
297 
GetKeyCode(const cJSON * jsonData,int32_t & keyCodeInt)298 bool GetKeyCode(const cJSON* jsonData, int32_t &keyCodeInt)
299 {
300     if (!cJSON_IsObject(jsonData)) {
301         MMI_HILOGE("jsonData is not object");
302         return false;
303     }
304     cJSON *keyCode = cJSON_GetObjectItemCaseSensitive(jsonData, "keyCode");
305     if (!cJSON_IsNumber(keyCode)) {
306         MMI_HILOGE("keyCode is not number");
307         return false;
308     }
309     if (keyCode->valueint < 0) {
310         MMI_HILOGE("keyCode must be number and bigger and equal zero");
311         return false;
312     }
313     keyCodeInt = keyCode->valueint;
314     return true;
315 }
316 
GetKeyAction(const cJSON * jsonData,int32_t & keyActionInt)317 bool GetKeyAction(const cJSON* jsonData, int32_t &keyActionInt)
318 {
319     if (!cJSON_IsObject(jsonData)) {
320         MMI_HILOGE("jsonData is not object");
321         return false;
322     }
323     cJSON *keyAction = cJSON_GetObjectItemCaseSensitive(jsonData, "keyAction");
324     if (!cJSON_IsNumber(keyAction)) {
325         MMI_HILOGE("keyAction is not number");
326         return false;
327     }
328     if ((keyAction->valueint != KeyEvent::KEY_ACTION_DOWN) && (keyAction->valueint != KeyEvent::KEY_ACTION_UP)) {
329         MMI_HILOGE("keyAction must be down or up");
330         return false;
331     }
332     keyActionInt = keyAction->valueint;
333     return true;
334 }
335 
GetDelay(const cJSON * jsonData,int64_t & delayInt)336 bool GetDelay(const cJSON* jsonData, int64_t &delayInt)
337 {
338     if (!cJSON_IsObject(jsonData)) {
339         MMI_HILOGE("jsonData is not object");
340         return false;
341     }
342     cJSON *delay = cJSON_GetObjectItemCaseSensitive(jsonData, "delay");
343     if (!cJSON_IsNumber(delay)) {
344         MMI_HILOGE("delay is not number");
345         return false;
346     }
347     if ((delay->valueint < 0) || (delay->valueint > MAX_DELAY_TIME)) {
348         MMI_HILOGE("delay must be number and bigger and equal zero and less than max delay");
349         return false;
350     }
351     delayInt = delay->valueint * SECONDS_SYSTEM;
352     return true;
353 }
354 
GetAlibityStartDelay(const cJSON * jsonData,int64_t & abilityStartDelayInt)355 bool GetAlibityStartDelay(const cJSON* jsonData, int64_t &abilityStartDelayInt)
356 {
357     if (!cJSON_IsObject(jsonData)) {
358         MMI_HILOGE("jsonData is not object");
359         return false;
360     }
361     cJSON *abilityStartDelay = cJSON_GetObjectItemCaseSensitive(jsonData, "abilityStartDelay");
362     if (!cJSON_IsNumber(abilityStartDelay)) {
363         MMI_HILOGE("abilityStartDelay is not number");
364         return false;
365     }
366     if ((abilityStartDelay->valueint < 0) || (abilityStartDelay->valueint > MAX_DELAY_TIME)) {
367         MMI_HILOGE("abilityStartDelay must be number and bigger and equal zero and less than max delay time");
368         return false;
369     }
370     abilityStartDelayInt = abilityStartDelay->valueint * SECONDS_SYSTEM;
371     return true;
372 }
373 
PackageSequenceKey(const cJSON * sequenceKeysJson,SequenceKey & sequenceKey)374 bool PackageSequenceKey(const cJSON* sequenceKeysJson, SequenceKey &sequenceKey)
375 {
376     if (!cJSON_IsObject(sequenceKeysJson)) {
377         MMI_HILOGE("sequenceKeysJson is not object");
378         return false;
379     }
380     if (!GetKeyCode(sequenceKeysJson, sequenceKey.keyCode)) {
381         MMI_HILOGE("Get keyCode failed");
382         return false;
383     }
384     if (!GetKeyAction(sequenceKeysJson, sequenceKey.keyAction)) {
385         MMI_HILOGE("Get keyAction failed");
386         return false;
387     }
388     if (!GetDelay(sequenceKeysJson, sequenceKey.delay)) {
389         MMI_HILOGE("Get delay failed");
390         return false;
391     }
392     return true;
393 }
394 
GetSequenceKeys(const cJSON * jsonData,Sequence & sequence)395 bool GetSequenceKeys(const cJSON* jsonData, Sequence &sequence)
396 {
397     if (!cJSON_IsObject(jsonData)) {
398         MMI_HILOGE("jsonData is not object");
399         return false;
400     }
401     cJSON* sequenceKeys = cJSON_GetObjectItemCaseSensitive(jsonData, "sequenceKeys");
402     if (!cJSON_IsArray(sequenceKeys)) {
403         MMI_HILOGE("sequenceKeys number must be array");
404         return false;
405     }
406     int32_t sequenceKeysSize = cJSON_GetArraySize(sequenceKeys);
407     if (sequenceKeysSize > MAX_SEQUENCEKEYS_NUM) {
408         MMI_HILOGE("sequenceKeysSize number must less and equal %{public}d", MAX_SEQUENCEKEYS_NUM);
409         return false;
410     }
411     for (int32_t i = 0; i < sequenceKeysSize; ++i) {
412         cJSON *sequenceKeysJson = cJSON_GetArrayItem(sequenceKeys, i);
413         if (!cJSON_IsObject(sequenceKeysJson)) {
414             MMI_HILOGE("sequenceKeysJson is not object");
415             return false;
416         }
417         SequenceKey sequenceKey;
418         if (!PackageSequenceKey(sequenceKeysJson, sequenceKey)) {
419             MMI_HILOGE("Packege sequenceKey failed");
420             return false;
421         }
422         sequence.sequenceKeys.push_back(sequenceKey);
423     }
424     return true;
425 }
426 
IsSequenceKeysValid(const Sequence & sequence)427 bool IsSequenceKeysValid(const Sequence &sequence)
428 {
429     if (sequence.sequenceKeys.empty()) {
430         MMI_HILOGE("sequenceKeys can not be empty");
431         return false;
432     }
433 
434     if (sequence.sequenceKeys.size() > MAX_SEQUENCEKEYS_NUM) {
435         MMI_HILOGE("sequenceKeys size must less or equal to %{public}d", MAX_SEQUENCEKEYS_NUM);
436         return false;
437     }
438 
439     std::map<int32_t, SequenceKey> sequenceKeys;
440     for (const SequenceKey& item : sequence.sequenceKeys) {
441         if (sequenceKeys.find(item.keyCode) == sequenceKeys.end()) {
442             auto it = sequenceKeys.emplace(item.keyCode, item);
443             if (!it.second) {
444                 MMI_HILOGE("Emplace duplicated");
445                 return false;
446             }
447         } else {
448             if (sequenceKeys[item.keyCode].keyAction == item.keyAction) {
449                 MMI_HILOGE("sequenceKeys illegal");
450                 return false;
451             }
452             sequenceKeys[item.keyCode].keyAction = item.keyAction;
453             sequenceKeys[item.keyCode].delay = item.delay;
454         }
455     }
456     return true;
457 }
458 
ConvertToKeySequence(const cJSON * jsonData,Sequence & sequence)459 bool ConvertToKeySequence(const cJSON* jsonData, Sequence &sequence)
460 {
461     if (!cJSON_IsObject(jsonData)) {
462         MMI_HILOGE("jsonData is not object");
463         return false;
464     }
465     if (!GetSequenceKeys(jsonData, sequence)) {
466         MMI_HILOGE("Get sequenceKeys failed");
467         return false;
468     }
469     if (!IsSequenceKeysValid(sequence)) {
470         MMI_HILOGE("Sequence invalid");
471         return false;
472     }
473     if (!GetAlibityStartDelay(jsonData, sequence.abilityStartDelay)) {
474         MMI_HILOGE("Get abilityStartDelay failed");
475         return false;
476     }
477     cJSON *ability = cJSON_GetObjectItemCaseSensitive(jsonData, "ability");
478     if (!cJSON_IsObject(ability)) {
479         MMI_HILOGE("ability is not object");
480         return false;
481     }
482     if (!PackageAbility(ability, sequence.ability)) {
483         MMI_HILOGE("Package ability failed");
484         return false;
485     }
486     return true;
487 }
488 
GenerateKey(const ShortcutKey & key)489 std::string GenerateKey(const ShortcutKey& key)
490 {
491     std::set<int32_t> preKeys = key.preKeys;
492     std::stringstream ss;
493     for (const auto& preKey : preKeys) {
494         ss << preKey << ",";
495     }
496     ss << key.finalKey << ",";
497     ss << key.triggerType;
498     return std::string(ss.str());
499 }
500 
ParseShortcutKeys(const JsonParser & parser,std::map<std::string,ShortcutKey> & shortcutKeyMap)501 bool ParseShortcutKeys(const JsonParser& parser, std::map<std::string, ShortcutKey>& shortcutKeyMap)
502 {
503     cJSON* shortkeys = cJSON_GetObjectItemCaseSensitive(parser.json_, "Shortkeys");
504     if (!cJSON_IsArray(shortkeys)) {
505         MMI_HILOGE("shortkeys is not array");
506         return false;
507     }
508     int32_t shortkeysSize = cJSON_GetArraySize(shortkeys);
509     for (int32_t i = 0; i < shortkeysSize; ++i) {
510         ShortcutKey shortcutKey;
511         cJSON *shortkey = cJSON_GetArrayItem(shortkeys, i);
512         if (!cJSON_IsObject(shortkey)) {
513             continue;
514         }
515         if (!ConvertToShortcutKey(shortkey, shortcutKey)) {
516             continue;
517         }
518         std::string key = GenerateKey(shortcutKey);
519         if (shortcutKeyMap.find(key) == shortcutKeyMap.end()) {
520             if (!shortcutKeyMap.emplace(key, shortcutKey).second) {
521                 MMI_HILOGW("Duplicate shortcutKey:%{public}s", key.c_str());
522             }
523         }
524     }
525     return true;
526 }
527 
ParseSequences(const JsonParser & parser,std::vector<Sequence> & sequenceVec)528 bool ParseSequences(const JsonParser& parser, std::vector<Sequence>& sequenceVec)
529 {
530     cJSON* sequences = cJSON_GetObjectItemCaseSensitive(parser.json_, "Sequences");
531     if (!cJSON_IsArray(sequences)) {
532         MMI_HILOGE("sequences is not array");
533         return false;
534     }
535     int32_t sequencesSize = cJSON_GetArraySize(sequences);
536     for (int32_t i = 0; i < sequencesSize; ++i) {
537         Sequence seq;
538         cJSON *sequence = cJSON_GetArrayItem(sequences, i);
539         if (!cJSON_IsObject(sequence)) {
540             continue;
541         }
542         if (!ConvertToKeySequence(sequence, seq)) {
543             continue;
544         }
545         sequenceVec.push_back(seq);
546     }
547     return true;
548 }
549 } // namespace
550 
551 #ifdef OHOS_BUILD_ENABLE_KEYBOARD
HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)552 void KeyCommandHandler::HandleKeyEvent(const std::shared_ptr<KeyEvent> keyEvent)
553 {
554     CHKPV(keyEvent);
555     if (OnHandleEvent(keyEvent)) {
556         MMI_HILOGD("The keyEvent start launch an ability, keyCode:%{public}d", keyEvent->GetKeyCode());
557         BytraceAdapter::StartBytrace(keyEvent, BytraceAdapter::KEY_LAUNCH_EVENT);
558         return;
559     }
560     CHKPV(nextHandler_);
561     nextHandler_->HandleKeyEvent(keyEvent);
562 }
563 #endif // OHOS_BUILD_ENABLE_KEYBOARD
564 
565 #ifdef OHOS_BUILD_ENABLE_POINTER
HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)566 void KeyCommandHandler::HandlePointerEvent(const std::shared_ptr<PointerEvent> pointerEvent)
567 {
568     CHKPV(pointerEvent);
569     CHKPV(nextHandler_);
570     nextHandler_->HandlePointerEvent(pointerEvent);
571 }
572 #endif // OHOS_BUILD_ENABLE_POINTER
573 
574 #ifdef OHOS_BUILD_ENABLE_TOUCH
HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)575 void KeyCommandHandler::HandleTouchEvent(const std::shared_ptr<PointerEvent> pointerEvent)
576 {
577     CHKPV(pointerEvent);
578     CHKPV(nextHandler_);
579     nextHandler_->HandleTouchEvent(pointerEvent);
580 }
581 #endif // OHOS_BUILD_ENABLE_TOUCH
582 
ParseConfig()583 bool KeyCommandHandler::ParseConfig()
584 {
585     const char *testPathSuffix = "/etc/multimodalinput/ability_launch_config.json";
586     char buf[MAX_PATH_LEN] = { 0 };
587     char *filePath = GetOneCfgFile(testPathSuffix, buf, MAX_PATH_LEN);
588     std::string defaultConfig = "/system/etc/multimodalinput/ability_launch_config.json";
589     if (filePath == NULL || filePath[0] == '\0' || strlen(filePath) > MAX_PATH_LEN) {
590         MMI_HILOGD("Can not get customization config file");
591         return ParseJson(defaultConfig);
592     }
593     std::string customConfig = filePath;
594     MMI_HILOGD("The configuration file path is :%{public}s", customConfig.c_str());
595     return ParseJson(customConfig) || ParseJson(defaultConfig);
596 }
597 
ParseJson(const std::string & configFile)598 bool KeyCommandHandler::ParseJson(const std::string &configFile)
599 {
600     CALL_DEBUG_ENTER;
601     std::string jsonStr = ReadJsonFile(configFile);
602     if (jsonStr.empty()) {
603         MMI_HILOGE("Read configFile failed");
604         return false;
605     }
606     JsonParser parser;
607     parser.json_ = cJSON_Parse(jsonStr.c_str());
608     if (!cJSON_IsObject(parser.json_)) {
609         MMI_HILOGE("Parser.json_ is not object");
610         return false;
611     }
612 
613     bool isParseShortKeys = ParseShortcutKeys(parser, shortcutKeys_);
614     bool isParseSequences = ParseSequences(parser, sequences_);
615     if (!isParseShortKeys && !isParseSequences) {
616         MMI_HILOGE("Parse configFile failed");
617         return false;
618     }
619 
620     Print();
621     PrintSeq();
622     return true;
623 }
624 
Print()625 void KeyCommandHandler::Print()
626 {
627     MMI_HILOGD("shortcutKey count:%{public}zu", shortcutKeys_.size());
628     int32_t row = 0;
629     for (const auto &item : shortcutKeys_) {
630         MMI_HILOGD("row:%{public}d", row++);
631         auto &shortcutKey = item.second;
632         for (const auto &prekey : shortcutKey.preKeys) {
633             MMI_HILOGD("preKey:%{public}d", prekey);
634         }
635         MMI_HILOGD("finalKey:%{public}d, keyDownDuration:%{public}d, triggerType:%{public}d,"
636                    " bundleName:%{public}s, abilityName:%{public}s", shortcutKey.finalKey,
637                    shortcutKey.keyDownDuration, shortcutKey.triggerType,
638                    shortcutKey.ability.bundleName.c_str(), shortcutKey.ability.abilityName.c_str());
639     }
640 }
641 
PrintSeq()642 void KeyCommandHandler::PrintSeq()
643 {
644     MMI_HILOGD("sequences count:%{public}zu", sequences_.size());
645     int32_t row = 0;
646     for (const auto &item : sequences_) {
647         MMI_HILOGD("row:%{public}d", row++);
648         for (const auto& sequenceKey : item.sequenceKeys) {
649             MMI_HILOGD("keyCode:%{public}d, keyAction:%{public}d, delay:%{public}" PRId64,
650                        sequenceKey.keyCode, sequenceKey.keyAction, sequenceKey.delay);
651         }
652         MMI_HILOGD("bundleName:%{public}s, abilityName:%{public}s",
653                    item.ability.bundleName.c_str(), item.ability.abilityName.c_str());
654     }
655 }
656 
OnHandleEvent(const std::shared_ptr<KeyEvent> key)657 bool KeyCommandHandler::OnHandleEvent(const std::shared_ptr<KeyEvent> key)
658 {
659     CALL_DEBUG_ENTER;
660     CHKPF(key);
661     if (!isParseConfig_) {
662         if (!ParseConfig()) {
663             MMI_HILOGE("Parse configFile failed");
664             return false;
665         }
666         isParseConfig_ = true;
667     }
668 
669     bool isHandled = HandleShortKeys(key);
670     isHandled = HandleSequences(key) || isHandled;
671     if (isHandled) {
672         return true;
673     }
674 
675     if (!specialKeys_.empty() && specialKeys_.find(key->GetKeyCode()) != specialKeys_.end()) {
676         HandleSpecialKeys(key->GetKeyCode(), key->GetAction());
677         return true;
678     }
679 
680     if (IsSpecialType(key->GetKeyCode(), SpecialType::SUBSCRIBER_BEFORE_DELAY)) {
681         auto tmpKey = KeyEvent::Clone(key);
682         int32_t timerId = TimerMgr->AddTimer(SPECIAL_KEY_DOWN_DELAY, 1, [this, tmpKey] () {
683             MMI_HILOGD("Timer callback");
684             auto it = specialTimers_.find(tmpKey->GetKeyCode());
685             if (it != specialTimers_.end() && !it->second.empty()) {
686                 it->second.pop_front();
687             }
688             InputHandler->GetSubscriberHandler()->HandleKeyEvent(tmpKey);
689         });
690         if (timerId < 0) {
691             MMI_HILOGE("Add timer failed");
692             return false;
693         }
694 
695         auto it = specialTimers_.find(key->GetKeyCode());
696         if (it == specialTimers_.end()) {
697             std::list<int32_t> timerIds;
698             timerIds.push_back(timerId);
699             auto it = specialTimers_.emplace(key->GetKeyCode(), timerIds);
700             if (!it.second) {
701                 MMI_HILOGE("Keycode duplicated");
702                 return false;
703             }
704         } else {
705             it->second.push_back(timerId);
706         }
707         MMI_HILOGD("Add timer success");
708         return true;
709     }
710 
711     return false;
712 }
713 
HandleShortKeys(const std::shared_ptr<KeyEvent> keyEvent)714 bool KeyCommandHandler::HandleShortKeys(const std::shared_ptr<KeyEvent> keyEvent)
715 {
716     CALL_DEBUG_ENTER;
717     CHKPF(keyEvent);
718     if (shortcutKeys_.empty()) {
719         MMI_HILOGD("No shortkeys configuration data");
720         return false;
721     }
722     if (IsKeyMatch(lastMatchedKey_, keyEvent)) {
723         MMI_HILOGD("The same key is waiting timeout, skip");
724         return true;
725     }
726     DfxHisysevent::GetComboStartTime();
727     if (lastMatchedKey_.timerId >= 0) {
728         MMI_HILOGD("Remove timer:%{public}d", lastMatchedKey_.timerId);
729         TimerMgr->RemoveTimer(lastMatchedKey_.timerId);
730     }
731     ResetLastMatchedKey();
732     for (auto &item : shortcutKeys_) {
733         ShortcutKey &shortcutKey = item.second;
734         if (!IsKeyMatch(shortcutKey, keyEvent)) {
735             MMI_HILOGD("Not key matched, next");
736             continue;
737         }
738         shortcutKey.Print();
739         if (shortcutKey.triggerType == KeyEvent::KEY_ACTION_DOWN) {
740             return HandleKeyDown(shortcutKey);
741         } else if (shortcutKey.triggerType == KeyEvent::KEY_ACTION_UP) {
742             return HandleKeyUp(keyEvent, shortcutKey);
743         } else {
744             return HandleKeyCancel(shortcutKey);
745         }
746     }
747     return false;
748 }
749 
IsRepeatKeyEvent(const SequenceKey & sequenceKey)750 bool KeyCommandHandler::IsRepeatKeyEvent(const SequenceKey &sequenceKey)
751 {
752     for (size_t i = keys_.size(); i > 0; --i) {
753         if (keys_[i-1].keyCode == sequenceKey.keyCode) {
754             if (keys_[i-1].keyAction == sequenceKey.keyAction) {
755                 MMI_HILOGD("Is repeat key, keyCode:%{public}d", sequenceKey.keyCode);
756                 return true;
757             }
758             MMI_HILOGD("Is not repeat key");
759             return false;
760         }
761     }
762     return false;
763 }
764 
HandleSequences(const std::shared_ptr<KeyEvent> keyEvent)765 bool KeyCommandHandler::HandleSequences(const std::shared_ptr<KeyEvent> keyEvent)
766 {
767     CALL_DEBUG_ENTER;
768     CHKPF(keyEvent);
769     if (sequences_.empty()) {
770         MMI_HILOGD("No sequences configuration data");
771         return false;
772     }
773 
774     if (!AddSequenceKey(keyEvent)) {
775         MMI_HILOGW("Add new sequence key failed");
776         return false;
777     }
778 
779     if (filterSequences_.empty()) {
780         filterSequences_ = sequences_;
781     }
782 
783     bool isLaunchAbility = false;
784     std::vector<Sequence> tempSeqs;
785     for (Sequence& item : filterSequences_) {
786         if (HandleSequence(item, isLaunchAbility)) {
787             tempSeqs.push_back(item);
788         }
789     }
790 
791     if (isLaunchAbility) {
792         for (const auto& item : keys_) {
793             if (IsSpecialType(item.keyCode, SpecialType::KEY_DOWN_ACTION)) {
794                 HandleSpecialKeys(item.keyCode, item.keyAction);
795             }
796             InputHandler->GetSubscriberHandler()->RemoveSubscriberKeyUpTimer(item.keyCode);
797             RemoveSubscribedTimer(item.keyCode);
798         }
799     }
800 
801     if (tempSeqs.empty()) {
802         MMI_HILOGD("No matching sequence found");
803     } else {
804         filterSequences_ = tempSeqs;
805     }
806     return isLaunchAbility;
807 }
808 
AddSequenceKey(const std::shared_ptr<KeyEvent> keyEvent)809 bool KeyCommandHandler::AddSequenceKey(const std::shared_ptr<KeyEvent> keyEvent)
810 {
811     CALL_DEBUG_ENTER;
812     CHKPF(keyEvent);
813     SequenceKey sequenceKey;
814     sequenceKey.keyCode = keyEvent->GetKeyCode();
815     sequenceKey.keyAction = keyEvent->GetKeyAction();
816     sequenceKey.actionTime = keyEvent->GetActionTime();
817     size_t size = keys_.size();
818     if (size > 0) {
819         if (keys_[size - 1].actionTime > sequenceKey.actionTime) {
820             MMI_HILOGE("The current event time is greater than the last event time");
821             ResetSequenceKeys();
822             return false;
823         }
824         if ((sequenceKey.actionTime - keys_[size - 1].actionTime) > MAX_DELAY_TIME) {
825             MMI_HILOGD("The delay time is greater than the maximum delay time");
826             ResetSequenceKeys();
827         } else {
828             if (IsRepeatKeyEvent(sequenceKey)) {
829                 MMI_HILOGD("This is a repeat key event, don't add");
830                 return false;
831             }
832             keys_[size - 1].delay = sequenceKey.actionTime - keys_[size - 1].actionTime;
833             InterruptTimers();
834         }
835     }
836     if (size > MAX_SEQUENCEKEYS_NUM) {
837         MMI_HILOGD("The save key size more than the max size");
838         return false;
839     }
840     keys_.push_back(sequenceKey);
841     return true;
842 }
843 
HandleSequence(Sequence & sequence,bool & isLaunchAbility)844 bool KeyCommandHandler::HandleSequence(Sequence &sequence, bool &isLaunchAbility)
845 {
846     CALL_DEBUG_ENTER;
847     size_t keysSize = keys_.size();
848     size_t sequenceKeysSize = sequence.sequenceKeys.size();
849     if (keysSize > sequenceKeysSize) {
850         MMI_HILOGD("The save sequence not matching ability sequence");
851         return false;
852     }
853 
854     for (size_t i = 0; i < keysSize; ++i) {
855         if (keys_[i] != sequence.sequenceKeys[i]) {
856             MMI_HILOGD("The keyCode or keyAction not matching");
857             return false;
858         }
859         int64_t delay = sequence.sequenceKeys[i].delay;
860         if (((i + 1) != keysSize) && (delay != 0) && (keys_[i].delay >= delay)) {
861             MMI_HILOGD("Delay is not matching");
862             return false;
863         }
864     }
865 
866     if (keysSize == sequenceKeysSize) {
867         if (sequence.abilityStartDelay == 0) {
868             MMI_HILOGD("Start launch ability immediately");
869             LaunchAbility(sequence);
870             isLaunchAbility = true;
871             return true;
872         }
873         sequence.timerId = TimerMgr->AddTimer(sequence.abilityStartDelay/SECONDS_SYSTEM, 1, [this, sequence] () {
874             MMI_HILOGD("Timer callback");
875             LaunchAbility(sequence);
876         });
877         if (sequence.timerId < 0) {
878             MMI_HILOGE("Add Timer failed");
879             return false;
880         }
881         MMI_HILOGD("Add timer success");
882         isLaunchAbility = true;
883     }
884     return true;
885 }
886 
IsKeyMatch(const ShortcutKey & shortcutKey,const std::shared_ptr<KeyEvent> & key)887 bool KeyCommandHandler::IsKeyMatch(const ShortcutKey &shortcutKey, const std::shared_ptr<KeyEvent> &key)
888 {
889     CALL_DEBUG_ENTER;
890     CHKPF(key);
891     if ((key->GetKeyCode() != shortcutKey.finalKey) || (shortcutKey.triggerType != key->GetKeyAction())) {
892         return false;
893     }
894     if ((shortcutKey.preKeys.size() + 1) != key->GetKeyItems().size()) {
895         return false;
896     }
897     for (const auto &item : key->GetKeyItems()) {
898         int32_t keyCode = item.GetKeyCode();
899         if (SkipFinalKey(keyCode, key)) {
900             continue;
901         }
902         if (shortcutKey.preKeys.find(keyCode) == shortcutKey.preKeys.end()) {
903             return false;
904         }
905     }
906     MMI_HILOGD("Leave, key matched");
907     return true;
908 }
909 
SkipFinalKey(const int32_t keyCode,const std::shared_ptr<KeyEvent> & key)910 bool KeyCommandHandler::SkipFinalKey(const int32_t keyCode, const std::shared_ptr<KeyEvent> &key)
911 {
912     CHKPF(key);
913     return keyCode == key->GetKeyCode();
914 }
915 
HandleKeyDown(ShortcutKey & shortcutKey)916 bool KeyCommandHandler::HandleKeyDown(ShortcutKey &shortcutKey)
917 {
918     CALL_DEBUG_ENTER;
919     if (shortcutKey.keyDownDuration == 0) {
920         MMI_HILOGD("Start launch ability immediately");
921         LaunchAbility(shortcutKey);
922         return true;
923     }
924     shortcutKey.timerId = TimerMgr->AddTimer(shortcutKey.keyDownDuration, 1, [this, shortcutKey] () {
925         MMI_HILOGD("Timer callback");
926         LaunchAbility(shortcutKey);
927     });
928     if (shortcutKey.timerId < 0) {
929         MMI_HILOGE("Add Timer failed");
930         return false;
931     }
932     MMI_HILOGD("Add timer success");
933     lastMatchedKey_ = shortcutKey;
934     return true;
935 }
936 
HandleKeyUp(const std::shared_ptr<KeyEvent> & keyEvent,const ShortcutKey & shortcutKey)937 bool KeyCommandHandler::HandleKeyUp(const std::shared_ptr<KeyEvent> &keyEvent, const ShortcutKey &shortcutKey)
938 {
939     CALL_DEBUG_ENTER;
940     CHKPF(keyEvent);
941     if (shortcutKey.keyDownDuration == 0) {
942         MMI_HILOGD("Start launch ability immediately");
943         LaunchAbility(shortcutKey);
944         return true;
945     }
946     const KeyEvent::KeyItem* keyItem = keyEvent->GetKeyItem();
947     CHKPF(keyItem);
948     auto upTime = keyEvent->GetActionTime();
949     auto downTime = keyItem->GetDownTime();
950     MMI_HILOGD("upTime:%{public}" PRId64 ",downTime:%{public}" PRId64 ",keyDownDuration:%{public}d",
951         upTime, downTime, shortcutKey.keyDownDuration);
952     if (upTime - downTime >= static_cast<int64_t>(shortcutKey.keyDownDuration) * 1000) {
953         MMI_HILOGD("Skip, upTime - downTime >= duration");
954         return false;
955     }
956     MMI_HILOGD("Start launch ability immediately");
957     LaunchAbility(shortcutKey);
958     return true;
959 }
960 
HandleKeyCancel(ShortcutKey & shortcutKey)961 bool KeyCommandHandler::HandleKeyCancel(ShortcutKey &shortcutKey)
962 {
963     CALL_DEBUG_ENTER;
964     if (shortcutKey.timerId < 0) {
965         MMI_HILOGE("Skip, timerid less than 0");
966     }
967     auto timerId = shortcutKey.timerId;
968     shortcutKey.timerId = -1;
969     TimerMgr->RemoveTimer(timerId);
970     MMI_HILOGD("timerId:%{public}d", timerId);
971     return false;
972 }
973 
LaunchAbility(const ShortcutKey & key)974 void KeyCommandHandler::LaunchAbility(const ShortcutKey &key)
975 {
976     AAFwk::Want want;
977     want.SetElementName(key.ability.deviceId, key.ability.bundleName, key.ability.abilityName);
978     want.SetAction(key.ability.action);
979     want.SetUri(key.ability.uri);
980     want.SetType(key.ability.uri);
981     for (const auto &entity : key.ability.entities) {
982         want.AddEntity(entity);
983     }
984     for (const auto &item : key.ability.params) {
985         want.SetParam(item.first, item.second);
986     }
987     DfxHisysevent::CalcComboStartTimes(lastMatchedKey_.keyDownDuration);
988     DfxHisysevent::ReportComboStartTimes();
989     MMI_HILOGD("Start launch ability, bundleName:%{public}s", key.ability.bundleName.c_str());
990     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
991     if (err != ERR_OK) {
992         MMI_HILOGE("LaunchAbility failed, bundleName:%{public}s, err:%{public}d", key.ability.bundleName.c_str(), err);
993     }
994     ResetLastMatchedKey();
995     MMI_HILOGD("End launch ability, bundleName:%{public}s", key.ability.bundleName.c_str());
996 }
997 
LaunchAbility(const Sequence & sequence)998 void KeyCommandHandler::LaunchAbility(const Sequence &sequence)
999 {
1000     AAFwk::Want want;
1001     want.SetElementName(sequence.ability.deviceId, sequence.ability.bundleName, sequence.ability.abilityName);
1002     want.SetAction(sequence.ability.action);
1003     want.SetUri(sequence.ability.uri);
1004     want.SetType(sequence.ability.uri);
1005     for (const auto &entity : sequence.ability.entities) {
1006         want.AddEntity(entity);
1007     }
1008     for (const auto &item : sequence.ability.params) {
1009         want.SetParam(item.first, item.second);
1010     }
1011     DfxHisysevent::CalcComboStartTimes(sequence.abilityStartDelay);
1012     DfxHisysevent::ReportComboStartTimes();
1013     ResetSequenceKeys();
1014     MMI_HILOGD("Start launch ability, bundleName:%{public}s", sequence.ability.bundleName.c_str());
1015     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
1016     if (err != ERR_OK) {
1017         MMI_HILOGE("LaunchAbility failed, bundleName:%{public}s, err:%{public}d",
1018                    sequence.ability.bundleName.c_str(), err);
1019     }
1020     MMI_HILOGD("End launch ability, bundleName:%{public}s", sequence.ability.bundleName.c_str());
1021 }
1022 
Print() const1023 void ShortcutKey::Print() const
1024 {
1025     for (const auto &prekey: preKeys) {
1026         MMI_HILOGI("Eventkey matched, preKey:%{public}d", prekey);
1027     }
1028     MMI_HILOGD("Eventkey matched, finalKey:%{public}d, bundleName:%{public}s",
1029         finalKey, ability.bundleName.c_str());
1030 }
1031 
RemoveSubscribedTimer(int32_t keyCode)1032 void KeyCommandHandler::RemoveSubscribedTimer(int32_t keyCode)
1033 {
1034     CALL_DEBUG_ENTER;
1035     auto iter = specialTimers_.find(keyCode);
1036     if (iter != specialTimers_.end()) {
1037         for (auto& item : iter->second) {
1038             TimerMgr->RemoveTimer(item);
1039         }
1040         specialTimers_.erase(keyCode);
1041         MMI_HILOGD("Remove timer success");
1042     }
1043 }
1044 
HandleSpecialKeys(int32_t keyCode,int32_t keyAction)1045 void KeyCommandHandler::HandleSpecialKeys(int32_t keyCode, int32_t keyAction)
1046 {
1047     CALL_DEBUG_ENTER;
1048     auto iter = specialKeys_.find(keyCode);
1049     if (keyAction == KeyEvent::KEY_ACTION_UP) {
1050         if (iter != specialKeys_.end()) {
1051             specialKeys_.erase(iter);
1052             return;
1053         }
1054     }
1055 
1056     if (keyAction == KeyEvent::KEY_ACTION_DOWN) {
1057         if (iter == specialKeys_.end()) {
1058             auto it = specialKeys_.emplace(keyCode, keyAction);
1059             if (!it.second) {
1060                 MMI_HILOGD("KeyCode duplicated");
1061                 return;
1062             }
1063         }
1064     }
1065 }
1066 
InterruptTimers()1067 void KeyCommandHandler::InterruptTimers()
1068 {
1069     for (Sequence& item : filterSequences_) {
1070         if (item.timerId >= 0) {
1071             MMI_HILOGD("The key sequence change, close the timer");
1072             TimerMgr->RemoveTimer(item.timerId);
1073             item.timerId = -1;
1074         }
1075     }
1076 }
1077 } // namespace MMI
1078 } // namespace OHOS