AccessibilityInputFilter.java revision 45af84a483165f06c04d74baba67f90da29c6ad2
10029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown/*
20029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Copyright (C) 2011 The Android Open Source Project
30029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown *
40029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
50029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * you may not use this file except in compliance with the License.
60029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * You may obtain a copy of the License at
70029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown *
80029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
90029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown *
100029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Unless required by applicable law or agreed to in writing, software
110029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
120029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * See the License for the specific language governing permissions and
140029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * limitations under the License.
150029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */
160029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
170029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownpackage com.android.server.accessibility;
180029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
190029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.content.Context;
20d1ff736d01cebaee70b76f012b660ae549c252b9Svetoslav Ganovimport android.os.PowerManager;
210029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.util.Slog;
22736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovimport android.view.InputDevice;
230029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.InputEvent;
24c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganovimport android.view.InputFilter;
250029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.MotionEvent;
260029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.WindowManagerPolicy;
2786783474fdec98a22bc22e224462767eab13e273Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent;
280029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
291cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganovclass AccessibilityInputFilter extends InputFilter implements EventStreamTransformation {
301cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
311cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    private static final String TAG = AccessibilityInputFilter.class.getSimpleName();
321cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
33736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov    private static final boolean DEBUG = false;
340029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
351cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    private static final int UNDEFINED_DEVICE_ID = -1;
361cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
371cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    /**
381cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov     * Flag for enabling the screen magnification feature.
391cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov     *
401cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov     * @see #setEnabledFeatures(int)
411cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov     */
421cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    static final int FLAG_FEATURE_SCREEN_MAGNIFIER = 0x00000001;
431cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
441cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    /**
451cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov     * Flag for enabling the touch exploration feature.
461cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov     *
471cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov     * @see #setEnabledFeatures(int)
481cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov     */
491cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    static final int FLAG_FEATURE_TOUCH_EXPLORATION = 0x00000002;
501cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
510029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    private final Context mContext;
520029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
53d1ff736d01cebaee70b76f012b660ae549c252b9Svetoslav Ganov    private final PowerManager mPm;
54d1ff736d01cebaee70b76f012b660ae549c252b9Svetoslav Ganov
55e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov    private final AccessibilityManagerService mAms;
564213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
571cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    private int mCurrentDeviceId;
58736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
591cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    private boolean mInstalled;
601cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
611cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    private int mEnabledFeatures;
624213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
631cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    private TouchExplorer mTouchExplorer;
641cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    private ScreenMagnifier mScreenMagnifier;
651cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    private EventStreamTransformation mEventHandler;
66736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
671cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    AccessibilityInputFilter(Context context, AccessibilityManagerService service) {
680029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        super(context.getMainLooper());
690029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        mContext = context;
70e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov        mAms = service;
711cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        mPm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
720029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
730029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
740029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    @Override
750029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    public void onInstalled() {
760029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        if (DEBUG) {
770029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            Slog.d(TAG, "Accessibility input filter installed.");
780029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
791cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        mInstalled = true;
801cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        disableFeatures();
811cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        enableFeatures();
820029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        super.onInstalled();
830029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
840029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
850029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    @Override
860029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    public void onUninstalled() {
870029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        if (DEBUG) {
880029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            Slog.d(TAG, "Accessibility input filter uninstalled.");
890029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
901cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        mInstalled = false;
911cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        disableFeatures();
920029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        super.onUninstalled();
930029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
940029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
950029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    @Override
960029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    public void onInputEvent(InputEvent event, int policyFlags) {
970029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        if (DEBUG) {
98736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            Slog.d(TAG, "Received event: " + event + ", policyFlags=0x"
99736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov                    + Integer.toHexString(policyFlags));
1000029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
1011cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        if (mEventHandler == null) {
1021cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            super.onInputEvent(event, policyFlags);
1031cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            return;
1041cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        }
1051cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        if (event.getSource() != InputDevice.SOURCE_TOUCHSCREEN) {
1061cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            super.onInputEvent(event, policyFlags);
1071cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            return;
1081cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        }
1091cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        if ((policyFlags & WindowManagerPolicy.FLAG_PASS_TO_USER) == 0) {
1101cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mEventHandler.clear();
1111cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            super.onInputEvent(event, policyFlags);
1121cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            return;
1131cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        }
1141cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        final int deviceId = event.getDeviceId();
1151cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        if (mCurrentDeviceId != deviceId) {
1161cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            if (mCurrentDeviceId != UNDEFINED_DEVICE_ID) {
1171cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov                mEventHandler.clear();
1180029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            }
1191cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mCurrentDeviceId = deviceId;
1201cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        }
1211cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        mPm.userActivity(event.getEventTime(), false);
12245af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov        MotionEvent rawEvent = (MotionEvent) event;
12345af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov        MotionEvent transformedEvent = MotionEvent.obtain(rawEvent);
12445af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov        mEventHandler.onMotionEvent(transformedEvent, rawEvent, policyFlags);
12545af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov        transformedEvent.recycle();
1261cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    }
1271cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
1281cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    @Override
12945af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov    public void onMotionEvent(MotionEvent transformedEvent, MotionEvent rawEvent,
13045af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov            int policyFlags) {
13145af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov        sendInputEvent(transformedEvent, policyFlags);
1321cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    }
1331cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
1341cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    @Override
1351cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    public void onAccessibilityEvent(AccessibilityEvent event) {
1361cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        // TODO Implement this to inject the accessibility event
1371cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        //      into the accessibility manager service similarly
1381cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        //      to how this is done for input events.
1391cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    }
1401cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
1411cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    @Override
1421cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    public void setNext(EventStreamTransformation sink) {
1431cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        /* do nothing */
1441cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    }
1451cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
1461cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    @Override
1471cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    public void clear() {
1481cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        /* do nothing */
1491cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    }
1501cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
1511cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    void setEnabledFeatures(int enabledFeatures) {
1521cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        if (mEnabledFeatures == enabledFeatures) {
1531cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            return;
1541cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        }
1551cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        if (mInstalled) {
1561cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            disableFeatures();
1571cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        }
1581cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        mEnabledFeatures = enabledFeatures;
1591cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        if (mInstalled) {
1601cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            enableFeatures();
1611cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        }
1621cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    }
1631cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
1641cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    void notifyAccessibilityEvent(AccessibilityEvent event) {
1651cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        if (mEventHandler != null) {
1661cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mEventHandler.onAccessibilityEvent(event);
1671cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        }
1681cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    }
1691cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
1701cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    private void enableFeatures() {
1711cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        if ((mEnabledFeatures & FLAG_FEATURE_SCREEN_MAGNIFIER) != 0) {
1721cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mEventHandler = mScreenMagnifier = new ScreenMagnifier(mContext);
1731cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mEventHandler.setNext(this);
1741cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        }
1751cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        if ((mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) {
1761cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mTouchExplorer = new TouchExplorer(mContext, mAms);
1771cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mTouchExplorer.setNext(this);
1781cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            if (mEventHandler != null) {
1791cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov                mEventHandler.setNext(mTouchExplorer);
180736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            } else {
1811cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov                mEventHandler = mTouchExplorer;
182736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov            }
1830029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
1840029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
18586783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov
1861cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    private void disableFeatures() {
187ee33ad24cdc31ed0d7f99e110e041b0a63c9b0f1Svetoslav Ganov        if (mTouchExplorer != null) {
1881cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mTouchExplorer.clear();
1891cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mTouchExplorer.onDestroy();
1901cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mTouchExplorer = null;
1911cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        }
1921cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        if (mScreenMagnifier != null) {
1931cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mScreenMagnifier.clear();
1941cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mScreenMagnifier.onDestroy();
1951cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov            mScreenMagnifier = null;
196ee33ad24cdc31ed0d7f99e110e041b0a63c9b0f1Svetoslav Ganov        }
1971cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        mEventHandler = null;
1981cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    }
1991cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
2001cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    @Override
2011cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov    public void onDestroy() {
2021cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov        /* ignore */
20386783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov    }
2040029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown}
205