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
17package com.android.inputmethod.accessibility;
18
19import android.graphics.Rect;
20import android.util.Log;
21import android.view.MotionEvent;
22
23import com.android.inputmethod.keyboard.Key;
24import com.android.inputmethod.keyboard.KeyDetector;
25import com.android.inputmethod.keyboard.MoreKeysKeyboardView;
26import 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 */
32public 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
41    public MoreKeysKeyboardAccessibilityDelegate(final MoreKeysKeyboardView moreKeysKeyboardView,
42            final KeyDetector keyDetector) {
43        super(moreKeysKeyboardView, keyDetector);
44    }
45
46    public void setOpenAnnounce(final int resId) {
47        mOpenAnnounceResId = resId;
48    }
49
50    public void setCloseAnnounce(final int resId) {
51        mCloseAnnounceResId = resId;
52    }
53
54    public void onShowMoreKeysKeyboard() {
55        sendWindowStateChanged(mOpenAnnounceResId);
56    }
57
58    public void onDismissMoreKeysKeyboard() {
59        sendWindowStateChanged(mCloseAnnounceResId);
60    }
61
62    @Override
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
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
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