Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d0274980 authored by Arthur Hung's avatar Arthur Hung
Browse files

RELAND Introduce system shortcut key unit tests

Provide an enviroment that could verify if a key or a combination keys
could be processed properly by the policy and execute the shortcut
behavior.

This includes these tests to for phone device:

CombinationKeyTests - test cases for combination keys
                        - power + volume down
                        - power + volume up
                        - volume down + volume up

PowerKeyGestureTests - test cases for power key gesture
                        - short press
                        - double presses
                        - long press

Bug: 193278327
Test: atest PowerKeyGestureTests CombinationKeyTests
Test: atest PlatformScenarioTests:PowerMenuTest
Change-Id: Ib7908a769cafac91ff405f49f5529e90fe068b1b
parent 6070aa3e
Loading
Loading
Loading
Loading
+57 −19
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@ import android.view.autofill.AutofillManagerInternal;
import com.android.internal.R;
import com.android.internal.accessibility.AccessibilityShortcutController;
import com.android.internal.accessibility.util.AccessibilityUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.AssistUtils;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.logging.MetricsLogger;
@@ -225,6 +226,7 @@ import java.io.PrintWriter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;

/**
 * WindowManagerPolicy implementation for the Android phone UI.  This
@@ -438,6 +440,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }
    };

    private Supplier<GlobalActions> mGlobalActionsFactory;
    private GlobalActions mGlobalActions;
    private Handler mHandler;

@@ -1545,7 +1548,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    void showGlobalActionsInternal() {
        if (mGlobalActions == null) {
            mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);
            mGlobalActions = mGlobalActionsFactory.get();
        }
        final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
        mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
@@ -1869,11 +1872,45 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mDefaultDisplayPolicy = mDefaultDisplayRotation.getDisplayPolicy();
    }

    /** Point of injection for test dependencies. */
    @VisibleForTesting
    static class Injector {
        private final Context mContext;
        private final WindowManagerFuncs mWindowManagerFuncs;

        Injector(Context context, WindowManagerFuncs funcs) {
            mContext = context;
            mWindowManagerFuncs = funcs;
        }

        Context getContext() {
            return mContext;
        }

        WindowManagerFuncs getWindowManagerFuncs() {
            return mWindowManagerFuncs;
        }

        AccessibilityShortcutController getAccessibilityShortcutController(
                Context context, Handler handler, int initialUserId) {
            return new AccessibilityShortcutController(context, handler, initialUserId);
        }

        Supplier<GlobalActions> getGlobalActionsFactory() {
            return () -> new GlobalActions(mContext, mWindowManagerFuncs);
        }
    }

    /** {@inheritDoc} */
    @Override
    public void init(Context context, WindowManagerFuncs windowManagerFuncs) {
        mContext = context;
        mWindowManagerFuncs = windowManagerFuncs;
    public void init(Context context, WindowManagerFuncs funcs) {
        init(new Injector(context, funcs));
    }

    @VisibleForTesting
    void init(Injector injector) {
        mContext = injector.getContext();
        mWindowManagerFuncs = injector.getWindowManagerFuncs();
        mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
        mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
@@ -1888,8 +1925,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mHasFeatureLeanback = mPackageManager.hasSystemFeature(FEATURE_LEANBACK);
        mHasFeatureAuto = mPackageManager.hasSystemFeature(FEATURE_AUTOMOTIVE);
        mHasFeatureHdmiCec = mPackageManager.hasSystemFeature(FEATURE_HDMI_CEC);
        mAccessibilityShortcutController =
                new AccessibilityShortcutController(mContext, new Handler(), mCurrentUserId);
        mAccessibilityShortcutController = injector.getAccessibilityShortcutController(
                mContext, new Handler(), mCurrentUserId);
        mGlobalActionsFactory = injector.getGlobalActionsFactory();
        mLogger = new MetricsLogger();

        mScreenOffSleepTokenAcquirer = mActivityTaskManagerInternal
@@ -1904,7 +1942,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                res.getBoolean(com.android.internal.R.bool.config_wakeOnBackKeyPress);

        // Init display burn-in protection
        boolean burnInProtectionEnabled = context.getResources().getBoolean(
        boolean burnInProtectionEnabled = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_enableBurnInProtection);
        // Allow a system property to override this. Used by developer settings.
        boolean burnInProtectionDevMode =
@@ -1922,7 +1960,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                maxVertical = -4;
                maxRadius = (isRoundWindow()) ? 6 : -1;
            } else {
                Resources resources = context.getResources();
                Resources resources = mContext.getResources();
                minHorizontal = resources.getInteger(
                        com.android.internal.R.integer.config_burnInProtectionMinHorizontalOffset);
                maxHorizontal = resources.getInteger(
@@ -1935,21 +1973,21 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                        com.android.internal.R.integer.config_burnInProtectionMaxRadius);
            }
            mBurnInProtectionHelper = new BurnInProtectionHelper(
                    context, minHorizontal, maxHorizontal, minVertical, maxVertical, maxRadius);
                    mContext, minHorizontal, maxHorizontal, minVertical, maxVertical, maxRadius);
        }

        mHandler = new PolicyHandler();
        mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
        mSettingsObserver = new SettingsObserver(mHandler);
        mSettingsObserver.observe();
        mModifierShortcutManager = new ModifierShortcutManager(context);
        mUiMode = context.getResources().getInteger(
        mModifierShortcutManager = new ModifierShortcutManager(mContext);
        mUiMode = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_defaultUiModeType);
        mHomeIntent =  new Intent(Intent.ACTION_MAIN, null);
        mHomeIntent.addCategory(Intent.CATEGORY_HOME);
        mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
        mEnableCarDockHomeCapture = context.getResources().getBoolean(
        mEnableCarDockHomeCapture = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_enableCarDockHomeLaunch);
        mCarDockIntent =  new Intent(Intent.ACTION_MAIN, null);
        mCarDockIntent.addCategory(Intent.CATEGORY_CAR_DOCK);
@@ -1964,7 +2002,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mVrHeadsetHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mBroadcastWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                "PhoneWindowManager.mBroadcastWakeLock");
        mPowerKeyWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
@@ -2036,9 +2074,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {

        readConfigurationDependentBehaviors();

        mDisplayFoldController = DisplayFoldController.create(context, DEFAULT_DISPLAY);
        mDisplayFoldController = DisplayFoldController.create(mContext, DEFAULT_DISPLAY);

        mAccessibilityManager = (AccessibilityManager) context.getSystemService(
        mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(
                Context.ACCESSIBILITY_SERVICE);

        // register for dock events
@@ -2048,7 +2086,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        filter.addAction(UiModeManager.ACTION_ENTER_DESK_MODE);
        filter.addAction(UiModeManager.ACTION_EXIT_DESK_MODE);
        filter.addAction(Intent.ACTION_DOCK_EVENT);
        Intent intent = context.registerReceiver(mDockReceiver, filter);
        Intent intent = mContext.registerReceiver(mDockReceiver, filter);
        if (intent != null) {
            // Retrieve current sticky dock event broadcast.
            mDefaultDisplayPolicy.setDockMode(intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
@@ -2059,13 +2097,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        filter = new IntentFilter();
        filter.addAction(Intent.ACTION_DREAMING_STARTED);
        filter.addAction(Intent.ACTION_DREAMING_STOPPED);
        context.registerReceiver(mDreamReceiver, filter);
        mContext.registerReceiver(mDreamReceiver, filter);

        // register for multiuser-relevant broadcasts
        filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
        context.registerReceiver(mMultiuserReceiver, filter);
        mContext.registerReceiver(mMultiuserReceiver, filter);

        mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
        mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
        mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
                com.android.internal.R.array.config_safeModeEnabledVibePattern);

+78 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.policy;

import static android.view.KeyEvent.KEYCODE_POWER;
import static android.view.KeyEvent.KEYCODE_VOLUME_DOWN;
import static android.view.KeyEvent.KEYCODE_VOLUME_UP;

import static com.android.server.policy.PhoneWindowManager.POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS;
import static com.android.server.policy.PhoneWindowManager.POWER_VOLUME_UP_BEHAVIOR_MUTE;

import android.view.ViewConfiguration;

import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * Test class for combination key shortcuts.
 *
 * Build/Install/Run:
 *  atest WmTests:CombinationKeyTests
 */
@MediumTest
@RunWith(AndroidJUnit4.class)
public class CombinationKeyTests extends ShortcutKeyTestBase {
    private static final long A11Y_KEY_HOLD_MILLIS = 3500;

    /**
     * Power-VolDown to take screenshot.
     */
    @Test
    public void testPowerVolumeDown() {
        sendKeyCombination(new int[]{KEYCODE_POWER, KEYCODE_VOLUME_DOWN},
                ViewConfiguration.get(mContext).getScreenshotChordKeyTimeout());
        mPhoneWindowManager.assertTakeScreenshotCalled();
    }

    /**
     * Power-VolUp to show global actions or mute audio. (Phone default behavior)
     */
    @Test
    public void testPowerVolumeUp() {
        // Show global actions.
        mPhoneWindowManager.overridePowerVolumeUp(POWER_VOLUME_UP_BEHAVIOR_GLOBAL_ACTIONS);
        sendKeyCombination(new int[]{KEYCODE_POWER, KEYCODE_VOLUME_UP}, 0);
        mPhoneWindowManager.assertShowGlobalActionsCalled();

        // Mute audio (hold over 100ms).
        mPhoneWindowManager.overridePowerVolumeUp(POWER_VOLUME_UP_BEHAVIOR_MUTE);
        sendKeyCombination(new int[]{KEYCODE_POWER, KEYCODE_VOLUME_UP}, 100);
        mPhoneWindowManager.assertVolumeMute();
    }

    /**
     * VolDown-VolUp and hold 3 secs to enable accessibility service.
     */
    @Test
    public void testVolumeDownVolumeUp() {
        sendKeyCombination(new int[]{KEYCODE_VOLUME_DOWN, KEYCODE_VOLUME_UP}, A11Y_KEY_HOLD_MILLIS);
        mPhoneWindowManager.assertAccessibilityKeychordCalled();
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -43,11 +43,11 @@ import java.util.concurrent.TimeUnit;
 * Test class for {@link KeyCombinationManager}.
 *
 * Build/Install/Run:
 *  atest KeyCombinationTests
 *  atest KeyCombinationManagerTests
 */

@SmallTest
public class KeyCombinationTests {
public class KeyCombinationManagerTests {
    private KeyCombinationManager mKeyCombinationManager;

    private final CountDownLatch mAction1Triggered = new CountDownLatch(1);
+84 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.policy;

import static android.view.KeyEvent.KEYCODE_POWER;
import static android.view.KeyEvent.KEYCODE_VOLUME_UP;

import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_ASSISTANT;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_GLOBAL_ACTIONS;

import android.view.Display;

import org.junit.Test;

/**
 * Test class for power key gesture.
 *
 * Build/Install/Run:
 *  atest WmTests:PowerKeyGestureTests
 */
public class PowerKeyGestureTests extends ShortcutKeyTestBase {
    /**
     * Power single press to turn screen on/off.
     */
    @Test
    public void testPowerSinglePress() {
        sendKey(KEYCODE_POWER);
        mPhoneWindowManager.assertPowerSleep();

        // turn screen on when begin from non-interactive.
        mPhoneWindowManager.overrideDisplayState(Display.STATE_OFF);
        sendKey(KEYCODE_POWER);
        mPhoneWindowManager.assertPowerWakeUp();
        mPhoneWindowManager.assertNoPowerSleep();
    }

    /**
     * Power double press to trigger camera.
     */
    @Test
    public void testPowerDoublePress() {
        sendKey(KEYCODE_POWER);
        sendKey(KEYCODE_POWER);
        mPhoneWindowManager.assertCameraLaunch();
    }

    /**
     * Power long press to show assistant or global actions.
     */
    @Test
    public void testPowerLongPress() {
        // Show assistant.
        mPhoneWindowManager.overrideLongPressOnPower(LONG_PRESS_POWER_ASSISTANT);
        sendKey(KEYCODE_POWER, true);
        mPhoneWindowManager.assertAssistLaunch();

        // Show global actions.
        mPhoneWindowManager.overrideLongPressOnPower(LONG_PRESS_POWER_GLOBAL_ACTIONS);
        sendKey(KEYCODE_POWER, true);
        mPhoneWindowManager.assertShowGlobalActionsCalled();
    }

    /**
     * Ignore power press if combination key already triggered.
     */
    @Test
    public void testIgnoreSinglePressWhenCombinationKeyTriggered() {
        sendKeyCombination(new int[]{KEYCODE_POWER, KEYCODE_VOLUME_UP}, 0);
        mPhoneWindowManager.assertNoPowerSleep();
    }
}
+169 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.policy;

import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.KeyEvent.KEYCODE_ALT_LEFT;
import static android.view.KeyEvent.KEYCODE_ALT_RIGHT;
import static android.view.KeyEvent.KEYCODE_CTRL_LEFT;
import static android.view.KeyEvent.KEYCODE_CTRL_RIGHT;
import static android.view.KeyEvent.KEYCODE_META_LEFT;
import static android.view.KeyEvent.KEYCODE_META_RIGHT;
import static android.view.KeyEvent.KEYCODE_SHIFT_LEFT;
import static android.view.KeyEvent.KEYCODE_SHIFT_RIGHT;
import static android.view.KeyEvent.META_ALT_LEFT_ON;
import static android.view.KeyEvent.META_ALT_ON;
import static android.view.KeyEvent.META_ALT_RIGHT_ON;
import static android.view.KeyEvent.META_CTRL_LEFT_ON;
import static android.view.KeyEvent.META_CTRL_ON;
import static android.view.KeyEvent.META_CTRL_RIGHT_ON;
import static android.view.KeyEvent.META_META_LEFT_ON;
import static android.view.KeyEvent.META_META_ON;
import static android.view.KeyEvent.META_META_RIGHT_ON;
import static android.view.KeyEvent.META_SHIFT_LEFT_ON;
import static android.view.KeyEvent.META_SHIFT_ON;
import static android.view.KeyEvent.META_SHIFT_RIGHT_ON;

import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;

import static com.android.server.policy.WindowManagerPolicy.ACTION_PASS_TO_USER;

import static java.util.Collections.unmodifiableMap;

import android.content.Context;
import android.os.Looper;
import android.os.SystemClock;
import android.util.ArrayMap;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.ViewConfiguration;

import org.junit.After;
import org.junit.Before;

import java.util.Map;

class ShortcutKeyTestBase {
    TestPhoneWindowManager mPhoneWindowManager;
    final Context mContext = getInstrumentation().getTargetContext();

    /** Modifier key to meta state */
    private static final Map<Integer, Integer> MODIFIER;
    static {
        final Map<Integer, Integer> map = new ArrayMap<>();
        map.put(KEYCODE_CTRL_LEFT, META_CTRL_LEFT_ON | META_CTRL_ON);
        map.put(KEYCODE_CTRL_RIGHT, META_CTRL_RIGHT_ON | META_CTRL_ON);
        map.put(KEYCODE_ALT_LEFT, META_ALT_LEFT_ON | META_ALT_ON);
        map.put(KEYCODE_ALT_RIGHT, META_ALT_RIGHT_ON | META_ALT_ON);
        map.put(KEYCODE_SHIFT_LEFT, META_SHIFT_LEFT_ON | META_SHIFT_ON);
        map.put(KEYCODE_SHIFT_RIGHT, META_SHIFT_RIGHT_ON | META_SHIFT_ON);
        map.put(KEYCODE_META_LEFT, META_META_LEFT_ON | META_META_ON);
        map.put(KEYCODE_META_RIGHT, META_META_RIGHT_ON | META_META_ON);

        MODIFIER = unmodifiableMap(map);
    }

    @Before
    public void setUp() {
        if (Looper.myLooper() == null) {
            Looper.prepare();
        }

        mPhoneWindowManager = new TestPhoneWindowManager(mContext);
    }

    @After
    public void tearDown() {
        mPhoneWindowManager.tearDown();
    }

    void sendKeyCombination(int[] keyCodes, long duration) {
        final long downTime = SystemClock.uptimeMillis();
        final int count = keyCodes.length;
        final KeyEvent[] events = new KeyEvent[count];
        int metaState = 0;
        for (int i = 0; i < count; i++) {
            final int keyCode = keyCodes[i];
            final KeyEvent event = new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN, keyCode,
                    0 /*repeat*/, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/,
                    0 /*flags*/, InputDevice.SOURCE_KEYBOARD);
            event.setDisplayId(DEFAULT_DISPLAY);
            events[i] = event;
            // The order is important here, metaState could be updated and applied to the next key.
            metaState |= MODIFIER.getOrDefault(keyCode, 0);
        }

        for (KeyEvent event: events) {
            interceptKey(event);
        }

        try {
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        for (KeyEvent event: events) {
            final long eventTime = SystemClock.uptimeMillis();
            final int keyCode = event.getKeyCode();
            final KeyEvent upEvent = new KeyEvent(downTime, eventTime, KeyEvent.ACTION_UP, keyCode,
                    0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/, 0 /*flags*/,
                    InputDevice.SOURCE_KEYBOARD);
            interceptKey(upEvent);
            metaState &= ~MODIFIER.getOrDefault(keyCode, 0);
        }
    }

    void sendKey(int keyCode) {
        sendKey(keyCode, false);
    }

    void sendKey(int keyCode, boolean longPress) {
        final long downTime = SystemClock.uptimeMillis();
        final KeyEvent event = new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN, keyCode,
                0 /*repeat*/, 0 /*metaState*/, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/,
                0 /*flags*/, InputDevice.SOURCE_KEYBOARD);
        event.setDisplayId(DEFAULT_DISPLAY);
        interceptKey(event);

        if (longPress) {
            final long nextDownTime = downTime + ViewConfiguration.getLongPressTimeout();
            final KeyEvent nextDownevent = new KeyEvent(downTime, nextDownTime,
                    KeyEvent.ACTION_DOWN, keyCode, 1 /*repeat*/, 0 /*metaState*/,
                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/,
                    KeyEvent.FLAG_LONG_PRESS /*flags*/, InputDevice.SOURCE_KEYBOARD);
            interceptKey(nextDownevent);
        }

        final long eventTime = longPress
                ? SystemClock.uptimeMillis() + ViewConfiguration.getLongPressTimeout()
                : SystemClock.uptimeMillis();
        final KeyEvent upEvent = new KeyEvent(downTime, eventTime, KeyEvent.ACTION_UP, keyCode,
                0 /*repeat*/, 0 /*metaState*/, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/,
                0 /*flags*/, InputDevice.SOURCE_KEYBOARD);
        interceptKey(upEvent);
    }

    private void interceptKey(KeyEvent keyEvent) {
        int actions = mPhoneWindowManager.interceptKeyBeforeQueueing(keyEvent);
        if ((actions & ACTION_PASS_TO_USER) != 0) {
            if (0 == mPhoneWindowManager.interceptKeyBeforeDispatching(keyEvent)) {
                mPhoneWindowManager.dispatchUnhandledKey(keyEvent);
            }
        }
    }
}
Loading