1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.inputmethod.accessibility;
18 
19 import android.graphics.Rect;
20 import android.util.Log;
21 import android.view.MotionEvent;
22 
23 import com.android.inputmethod.keyboard.Key;
24 import com.android.inputmethod.keyboard.KeyDetector;
25 import com.android.inputmethod.keyboard.MoreKeysKeyboardView;
26 import com.android.inputmethod.keyboard.PointerTracker;
27 
28 /**
29  * This class represents a delegate that can be registered in {@link MoreKeysKeyboardView} to
30  * enhance accessibility support via composition rather via inheritance.
31  */
32 public class MoreKeysKeyboardAccessibilityDelegate
33         extends KeyboardAccessibilityDelegate<MoreKeysKeyboardView> {
34     private static final String TAG = MoreKeysKeyboardAccessibilityDelegate.class.getSimpleName();
35 
36     private final Rect mMoreKeysKeyboardValidBounds = new Rect();
37     private static final int CLOSING_INSET_IN_PIXEL = 1;
38     private int mOpenAnnounceResId;
39     private int mCloseAnnounceResId;
40 
MoreKeysKeyboardAccessibilityDelegate(final MoreKeysKeyboardView moreKeysKeyboardView, final KeyDetector keyDetector)41     public MoreKeysKeyboardAccessibilityDelegate(final MoreKeysKeyboardView moreKeysKeyboardView,
42             final KeyDetector keyDetector) {
43         super(moreKeysKeyboardView, keyDetector);
44     }
45 
setOpenAnnounce(final int resId)46     public void setOpenAnnounce(final int resId) {
47         mOpenAnnounceResId = resId;
48     }
49 
setCloseAnnounce(final int resId)50     public void setCloseAnnounce(final int resId) {
51         mCloseAnnounceResId = resId;
52     }
53 
onShowMoreKeysKeyboard()54     public void onShowMoreKeysKeyboard() {
55         sendWindowStateChanged(mOpenAnnounceResId);
56     }
57 
onDismissMoreKeysKeyboard()58     public void onDismissMoreKeysKeyboard() {
59         sendWindowStateChanged(mCloseAnnounceResId);
60     }
61 
62     @Override
onHoverEnter(final MotionEvent event)63     protected void onHoverEnter(final MotionEvent event) {
64         if (DEBUG_HOVER) {
65             Log.d(TAG, "onHoverEnter: key=" + getHoverKeyOf(event));
66         }
67         super.onHoverEnter(event);
68         final int actionIndex = event.getActionIndex();
69         final int x = (int)event.getX(actionIndex);
70         final int y = (int)event.getY(actionIndex);
71         final int pointerId = event.getPointerId(actionIndex);
72         final long eventTime = event.getEventTime();
73         mKeyboardView.onDownEvent(x, y, pointerId, eventTime);
74     }
75 
76     @Override
onHoverMove(final MotionEvent event)77     protected void onHoverMove(final MotionEvent event) {
78         super.onHoverMove(event);
79         final int actionIndex = event.getActionIndex();
80         final int x = (int)event.getX(actionIndex);
81         final int y = (int)event.getY(actionIndex);
82         final int pointerId = event.getPointerId(actionIndex);
83         final long eventTime = event.getEventTime();
84         mKeyboardView.onMoveEvent(x, y, pointerId, eventTime);
85     }
86 
87     @Override
onHoverExit(final MotionEvent event)88     protected void onHoverExit(final MotionEvent event) {
89         final Key lastKey = getLastHoverKey();
90         if (DEBUG_HOVER) {
91             Log.d(TAG, "onHoverExit: key=" + getHoverKeyOf(event) + " last=" + lastKey);
92         }
93         if (lastKey != null) {
94             super.onHoverExitFrom(lastKey);
95         }
96         setLastHoverKey(null);
97         final int actionIndex = event.getActionIndex();
98         final int x = (int)event.getX(actionIndex);
99         final int y = (int)event.getY(actionIndex);
100         final int pointerId = event.getPointerId(actionIndex);
101         final long eventTime = event.getEventTime();
102         // A hover exit event at one pixel width or height area on the edges of more keys keyboard
103         // are treated as closing.
104         mMoreKeysKeyboardValidBounds.set(0, 0, mKeyboardView.getWidth(), mKeyboardView.getHeight());
105         mMoreKeysKeyboardValidBounds.inset(CLOSING_INSET_IN_PIXEL, CLOSING_INSET_IN_PIXEL);
106         if (mMoreKeysKeyboardValidBounds.contains(x, y)) {
107             // Invoke {@link MoreKeysKeyboardView#onUpEvent(int,int,int,long)} as if this hover
108             // exit event selects a key.
109             mKeyboardView.onUpEvent(x, y, pointerId, eventTime);
110             // TODO: Should fix this reference. This is a hack to clear the state of
111             // {@link PointerTracker}.
112             PointerTracker.dismissAllMoreKeysPanels();
113             return;
114         }
115         // Close the more keys keyboard.
116         // TODO: Should fix this reference. This is a hack to clear the state of
117         // {@link PointerTracker}.
118         PointerTracker.dismissAllMoreKeysPanels();
119     }
120 }
121