AccessibilityInputFilter.java revision 1cf70bbf96930662cab0e699d70b62865766ff52
1/*
2 * Copyright (C) 2011 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.server.accessibility;
18
19import android.content.Context;
20import android.os.PowerManager;
21import android.util.Slog;
22import android.view.InputDevice;
23import android.view.InputEvent;
24import android.view.InputFilter;
25import android.view.MotionEvent;
26import android.view.WindowManagerPolicy;
27import android.view.accessibility.AccessibilityEvent;
28
29class AccessibilityInputFilter extends InputFilter implements EventStreamTransformation {
30
31    private static final String TAG = AccessibilityInputFilter.class.getSimpleName();
32
33    private static final boolean DEBUG = false;
34
35    private static final int UNDEFINED_DEVICE_ID = -1;
36
37    /**
38     * Flag for enabling the screen magnification feature.
39     *
40     * @see #setEnabledFeatures(int)
41     */
42    static final int FLAG_FEATURE_SCREEN_MAGNIFIER = 0x00000001;
43
44    /**
45     * Flag for enabling the touch exploration feature.
46     *
47     * @see #setEnabledFeatures(int)
48     */
49    static final int FLAG_FEATURE_TOUCH_EXPLORATION = 0x00000002;
50
51    private final Context mContext;
52
53    private final PowerManager mPm;
54
55    private final AccessibilityManagerService mAms;
56
57    private int mCurrentDeviceId;
58
59    private boolean mInstalled;
60
61    private int mEnabledFeatures;
62
63    private TouchExplorer mTouchExplorer;
64    private ScreenMagnifier mScreenMagnifier;
65    private EventStreamTransformation mEventHandler;
66
67    AccessibilityInputFilter(Context context, AccessibilityManagerService service) {
68        super(context.getMainLooper());
69        mContext = context;
70        mAms = service;
71        mPm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
72    }
73
74    @Override
75    public void onInstalled() {
76        if (DEBUG) {
77            Slog.d(TAG, "Accessibility input filter installed.");
78        }
79        mInstalled = true;
80        disableFeatures();
81        enableFeatures();
82        super.onInstalled();
83    }
84
85    @Override
86    public void onUninstalled() {
87        if (DEBUG) {
88            Slog.d(TAG, "Accessibility input filter uninstalled.");
89        }
90        mInstalled = false;
91        disableFeatures();
92        super.onUninstalled();
93    }
94
95    @Override
96    public void onInputEvent(InputEvent event, int policyFlags) {
97        if (DEBUG) {
98            Slog.d(TAG, "Received event: " + event + ", policyFlags=0x"
99                    + Integer.toHexString(policyFlags));
100        }
101        if (mEventHandler == null) {
102            super.onInputEvent(event, policyFlags);
103            return;
104        }
105        if (event.getSource() != InputDevice.SOURCE_TOUCHSCREEN) {
106            super.onInputEvent(event, policyFlags);
107            return;
108        }
109        if ((policyFlags & WindowManagerPolicy.FLAG_PASS_TO_USER) == 0) {
110            mEventHandler.clear();
111            super.onInputEvent(event, policyFlags);
112            return;
113        }
114        final int deviceId = event.getDeviceId();
115        if (mCurrentDeviceId != deviceId) {
116            if (mCurrentDeviceId != UNDEFINED_DEVICE_ID) {
117                mEventHandler.clear();
118            }
119            mCurrentDeviceId = deviceId;
120        }
121        mPm.userActivity(event.getEventTime(), false);
122        MotionEvent motionEvent = (MotionEvent) event;
123        mEventHandler.onMotionEvent(motionEvent, policyFlags);
124    }
125
126    @Override
127    public void onMotionEvent(MotionEvent event, int policyFlags) {
128        sendInputEvent(event, policyFlags);
129    }
130
131    @Override
132    public void onAccessibilityEvent(AccessibilityEvent event) {
133        // TODO Implement this to inject the accessibility event
134        //      into the accessibility manager service similarly
135        //      to how this is done for input events.
136    }
137
138    @Override
139    public void setNext(EventStreamTransformation sink) {
140        /* do nothing */
141    }
142
143    @Override
144    public void clear() {
145        /* do nothing */
146    }
147
148    void setEnabledFeatures(int enabledFeatures) {
149        if (mEnabledFeatures == enabledFeatures) {
150            return;
151        }
152        if (mInstalled) {
153            disableFeatures();
154        }
155        mEnabledFeatures = enabledFeatures;
156        if (mInstalled) {
157            enableFeatures();
158        }
159    }
160
161    void notifyAccessibilityEvent(AccessibilityEvent event) {
162        if (mEventHandler != null) {
163            mEventHandler.onAccessibilityEvent(event);
164        }
165    }
166
167    private void enableFeatures() {
168        if ((mEnabledFeatures & FLAG_FEATURE_SCREEN_MAGNIFIER) != 0) {
169            mEventHandler = mScreenMagnifier = new ScreenMagnifier(mContext);
170            mEventHandler.setNext(this);
171        }
172        if ((mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) {
173            mTouchExplorer = new TouchExplorer(mContext, mAms);
174            mTouchExplorer.setNext(this);
175            if (mEventHandler != null) {
176                mEventHandler.setNext(mTouchExplorer);
177            } else {
178                mEventHandler = mTouchExplorer;
179            }
180        }
181    }
182
183    private void disableFeatures() {
184        if (mTouchExplorer != null) {
185            mTouchExplorer.clear();
186            mTouchExplorer.onDestroy();
187            mTouchExplorer = null;
188        }
189        if (mScreenMagnifier != null) {
190            mScreenMagnifier.clear();
191            mScreenMagnifier.onDestroy();
192            mScreenMagnifier = null;
193        }
194        mEventHandler = null;
195    }
196
197    @Override
198    public void onDestroy() {
199        /* ignore */
200    }
201}
202