• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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" + accessibilityEvent.eventType)
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}