1/* 2 * Copyright (c) 2023 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 16import AccessibilityUtils from '../utils/AccessibilityUtils' 17import ResourceUtils from '../utils/ResourceUtils' 18import Logger from '../utils/Logger' 19 20const wantedAttribute = ["componentId", "componentType", "bundleName", "text", "hintText", "description", 21 "focusable", "clickable", "longClickable", "accessibilityFocused", "windowId"] 22 23export default class AccessibilityManager { 24 private static instance = null 25 accessibleContext = null 26 currentPageElementArray = null 27 targetElement = { 28 KEY: "text", 29 VALUE: null 30 } 31 32 static getInstance() { 33 if (this.instance == null) { 34 this.instance = new AccessibilityManager() 35 } 36 return this.instance 37 } 38 39 onStart(context) { 40 Logger.info("AccessibilityManager onStart") 41 this.accessibleContext = context 42 } 43 44 onStop() { 45 Logger.info("AccessibilityManager onStop") 46 this.accessibleContext = null 47 } 48 49 onEvent(accessibilityEvent) { 50 Logger.info("AccessibilityManager onEvent") 51 switch (accessibilityEvent.eventType) { 52 case "rightThenDown": 53 this.getCurrentPageAllElement() 54 break 55 case "leftThenDown": 56 this.printAllElementInfo() 57 break 58 case "left": 59 this.setAccessibilityFocused() 60 break 61 case "right": 62 this.clearAccessibilityFocus() 63 break 64 case "down": 65 this.clickTargetElement() 66 break 67 default: 68 break 69 } 70 } 71 72 async getCurrentPageAllElement() { 73 Logger.info("AccessibilityManager getCurrentPageAllElement") 74 let rootElement = null 75 try { 76 rootElement = await this.accessibleContext.getWindowRootElement() 77 } catch (error) { 78 Logger.error("AccessibilityExtAbility Failed to getWindowRootElement. Cause: " + JSON.stringify(error)) 79 } 80 this.currentPageElementArray = await AccessibilityUtils.createElementArray(rootElement) 81 } 82 83 async printAllElementInfo() { 84 Logger.info("AccessibilityManager printAllElementInfo") 85 if (this.currentPageElementArray == null || this.currentPageElementArray.length == 0) { 86 Logger.error("AccessibilityManager currentPageElementArray is null") 87 return 88 } 89 let info = null 90 for (let element of this.currentPageElementArray) { 91 info = await AccessibilityUtils.getElementWantedInfo(element, wantedAttribute) 92 Logger.info("AccessibilityManager element information: " + info) 93 } 94 } 95 96 async setAccessibilityFocused() { 97 Logger.info("AccessibilityManager setAccessibilityFocused") 98 this.targetElement.VALUE = ResourceUtils.getStringByName(this.accessibleContext, "accessibility_focus") 99 let element = await AccessibilityUtils.findElementByKey(this.currentPageElementArray, this.targetElement) 100 if (element == null) { 101 Logger.error("AccessibilityManager Target element not found") 102 return 103 } 104 let isFocusable = await AccessibilityUtils.getAttributeValue(element, "focusable") 105 let isAccessibilityFocused = await AccessibilityUtils.getAttributeValue(element, "accessibilityFocused") 106 if (!isFocusable || isAccessibilityFocused) { 107 return 108 } 109 try { 110 element.performAction("accessibilityFocus") // 元素可执行的行为可通过actionNames()获取 111 Logger.info("AccessibilityManager Succeed in perform action: accessibilityFocus") 112 this.getCurrentPageAllElement() // 执行完动作后需更新界面信息 113 } catch (error) { 114 Logger.error("AccessibilityManager Failed to perform action: accessibilityFocus. Cause: " + JSON.stringify(error)) 115 } 116 } 117 118 async clearAccessibilityFocus() { 119 Logger.info("AccessibilityManager clearAccessibilityFocus") 120 this.targetElement.VALUE = ResourceUtils.getStringByName(this.accessibleContext, "accessibility_focus") 121 let element = await AccessibilityUtils.findElementByKey(this.currentPageElementArray, this.targetElement) 122 if (element == null) { 123 Logger.error("AccessibilityManager Target element not found") 124 return 125 } 126 let isAccessibilityFocused = await AccessibilityUtils.getAttributeValue(element, "accessibilityFocused") 127 if (!isAccessibilityFocused) { 128 return 129 } 130 try { 131 element.performAction("clearAccessibilityFocus").then(() => { 132 Logger.info("AccessibilityManager Succeed in perform action: clearAccessibilityFocus") 133 this.getCurrentPageAllElement() 134 }).catch((err) => { 135 Logger.error("AccessibilityManager Failed to perform action: clearAccessibilityFocus. Cause: " + JSON.stringify(err)) 136 }) 137 } catch (error) { 138 Logger.error("AccessibilityManager Failed to perform action: clearAccessibilityFocus. Cause: " + JSON.stringify(error)) 139 } 140 141 } 142 143 async clickTargetElement() { 144 Logger.info("AccessibilityManager clickTargetElement") 145 this.targetElement.VALUE = ResourceUtils.getStringByName(this.accessibleContext, "accessibility_not_clicked") 146 let tmpElementNotClicked = await AccessibilityUtils.findElementByKey(this.currentPageElementArray, this.targetElement) 147 this.targetElement.VALUE = ResourceUtils.getStringByName(this.accessibleContext, "accessibility_clicked") 148 let tmpElementClicked = await AccessibilityUtils.findElementByKey(this.currentPageElementArray, this.targetElement) 149 let element = null 150 if (tmpElementClicked != null) { 151 element = tmpElementClicked 152 } else if (tmpElementNotClicked != null) { 153 element = tmpElementNotClicked 154 } else { 155 Logger.error("AccessibilityManager Target element not found") 156 return 157 } 158 let isClickable = await AccessibilityUtils.getAttributeValue(element, "clickable") 159 if (!isClickable) { 160 Logger.error("AccessibilityManager Target element cannot be clicked") 161 return 162 } 163 try { 164 element.performAction("click").then((data) => { 165 Logger.info("AccessibilityManager Succeed in perform action: click") 166 this.getCurrentPageAllElement() 167 }).catch((err) => { 168 Logger.error("AccessibilityManager Failed to perform action: click. Cause: " + JSON.stringify(err)) 169 }) 170 } catch (error) { 171 Logger.error("AccessibilityManager Failed to perform action: click. Cause: " + JSON.stringify(error)) 172 } 173 174 } 175}