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