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

Commit 6eba2471 authored by Pechetty Sravani (xWF)'s avatar Pechetty Sravani (xWF)
Browse files

Revert "Revert "Revert "Allow focused privileged windows to capt..."

Revert submission 30763741-revert-30698369-revert-30412668-HWHJRSWUQP-SSEJIYIUHQ

Reason for revert: <Droidmonitor created revert due to b/383004544.Will be verified through ABTD for standard investigation.>

Reverted changes: /q/submissionid:30763741-revert-30698369-revert-30412668-HWHJRSWUQP-SSEJIYIUHQ

Change-Id: I183d48d59317691ba2e71d3b9adbb38529ddfb3d
parent 38771a70
Loading
Loading
Loading
Loading
+1 −3
Original line number Original line Diff line number Diff line
@@ -27,13 +27,11 @@ public class KeyInterceptionInfo {
    // Debug friendly name to help identify the window
    // Debug friendly name to help identify the window
    public final String windowTitle;
    public final String windowTitle;
    public final int windowOwnerUid;
    public final int windowOwnerUid;
    public final int inputFeaturesFlags;


    public KeyInterceptionInfo(int type, int flags, String title, int uid, int inputFeaturesFlags) {
    public KeyInterceptionInfo(int type, int flags, String title, int uid) {
        layoutParamsType = type;
        layoutParamsType = type;
        layoutParamsPrivateFlags = flags;
        layoutParamsPrivateFlags = flags;
        windowTitle = title;
        windowTitle = title;
        windowOwnerUid = uid;
        windowOwnerUid = uid;
        this.inputFeaturesFlags = inputFeaturesFlags;
    }
    }
}
}
+5 −48
Original line number Original line Diff line number Diff line
@@ -16,7 +16,6 @@


package com.android.server;
package com.android.server;


import static com.android.hardware.input.Flags.overridePowerKeyBehaviorInFocusedWindow;
import static com.android.internal.R.integer.config_defaultMinEmergencyGestureTapDurationMillis;
import static com.android.internal.R.integer.config_defaultMinEmergencyGestureTapDurationMillis;


import android.app.ActivityManager;
import android.app.ActivityManager;
@@ -104,7 +103,7 @@ public class GestureLauncherService extends SystemService {
    /**
    /**
     * Number of taps required to launch camera shortcut.
     * Number of taps required to launch camera shortcut.
     */
     */
    public static final int CAMERA_POWER_TAP_COUNT_THRESHOLD = 2;
    private static final int CAMERA_POWER_TAP_COUNT_THRESHOLD = 2;


    /** The listener that receives the gesture event. */
    /** The listener that receives the gesture event. */
    private final GestureEventListener mGestureListener = new GestureEventListener();
    private final GestureEventListener mGestureListener = new GestureEventListener();
@@ -209,9 +208,7 @@ public class GestureLauncherService extends SystemService {
    }
    }


    @VisibleForTesting
    @VisibleForTesting
    public GestureLauncherService(
    GestureLauncherService(Context context, MetricsLogger metricsLogger,
            Context context,
            MetricsLogger metricsLogger,
            UiEventLogger uiEventLogger) {
            UiEventLogger uiEventLogger) {
        super(context);
        super(context);
        mContext = context;
        mContext = context;
@@ -503,46 +500,6 @@ public class GestureLauncherService extends SystemService {
                || isEmergencyGestureEnabled(resources);
                || isEmergencyGestureEnabled(resources);
    }
    }


    /**
     * Processes a power key event in GestureLauncherService without performing an action. This
     * method is called on every KEYCODE_POWER ACTION_DOWN event and ensures that, even if
     * KEYCODE_POWER events are passed to and handled by the app, the GestureLauncherService still
     * keeps track of all running KEYCODE_POWER events for its gesture detection and relevant
     * actions.
     */
    public void processPowerKeyDown(KeyEvent event) {
        if (mEmergencyGestureEnabled && mEmergencyGesturePowerButtonCooldownPeriodMs >= 0
                && event.getEventTime() - mLastEmergencyGestureTriggered
                < mEmergencyGesturePowerButtonCooldownPeriodMs) {
            return;
        }
        if (event.isLongPress()) {
            return;
        }

        final long powerTapInterval;

        synchronized (this) {
            powerTapInterval = event.getEventTime() - mLastPowerDown;
            mLastPowerDown = event.getEventTime();
            if (powerTapInterval >= POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS) {
                // Tap too slow, reset consecutive tap counts.
                mFirstPowerDown = event.getEventTime();
                mPowerButtonConsecutiveTaps = 1;
                mPowerButtonSlowConsecutiveTaps = 1;
            } else if (powerTapInterval >= CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS) {
                // Tap too slow for shortcuts
                mFirstPowerDown = event.getEventTime();
                mPowerButtonConsecutiveTaps = 1;
                mPowerButtonSlowConsecutiveTaps++;
            } else if (powerTapInterval > 0) {
                // Fast consecutive tap
                mPowerButtonConsecutiveTaps++;
                mPowerButtonSlowConsecutiveTaps++;
            }
        }
    }

    /**
    /**
     * Attempts to intercept power key down event by detecting certain gesture patterns
     * Attempts to intercept power key down event by detecting certain gesture patterns
     *
     *
@@ -550,8 +507,8 @@ public class GestureLauncherService extends SystemService {
     * @param outLaunched true if some action is taken as part of the key intercept (eg, app launch)
     * @param outLaunched true if some action is taken as part of the key intercept (eg, app launch)
     * @return true if the key down event is intercepted
     * @return true if the key down event is intercepted
     */
     */
    public boolean interceptPowerKeyDown(
    public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive,
            KeyEvent event, boolean interactive, MutableBoolean outLaunched) {
            MutableBoolean outLaunched) {
        if (mEmergencyGestureEnabled && mEmergencyGesturePowerButtonCooldownPeriodMs >= 0
        if (mEmergencyGestureEnabled && mEmergencyGesturePowerButtonCooldownPeriodMs >= 0
                && event.getEventTime() - mLastEmergencyGestureTriggered
                && event.getEventTime() - mLastEmergencyGestureTriggered
                < mEmergencyGesturePowerButtonCooldownPeriodMs) {
                < mEmergencyGesturePowerButtonCooldownPeriodMs) {
@@ -589,7 +546,7 @@ public class GestureLauncherService extends SystemService {
                mFirstPowerDown  = event.getEventTime();
                mFirstPowerDown  = event.getEventTime();
                mPowerButtonConsecutiveTaps = 1;
                mPowerButtonConsecutiveTaps = 1;
                mPowerButtonSlowConsecutiveTaps++;
                mPowerButtonSlowConsecutiveTaps++;
            } else if (!overridePowerKeyBehaviorInFocusedWindow() || powerTapInterval > 0) {
            } else {
                // Fast consecutive tap
                // Fast consecutive tap
                mPowerButtonConsecutiveTaps++;
                mPowerButtonConsecutiveTaps++;
                mPowerButtonSlowConsecutiveTaps++;
                mPowerButtonSlowConsecutiveTaps++;
+5 −227
Original line number Original line Diff line number Diff line
@@ -88,12 +88,10 @@ import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGest
import static com.android.hardware.input.Flags.inputManagerLifecycleSupport;
import static com.android.hardware.input.Flags.inputManagerLifecycleSupport;
import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
import static com.android.hardware.input.Flags.modifierShortcutDump;
import static com.android.hardware.input.Flags.modifierShortcutDump;
import static com.android.hardware.input.Flags.overridePowerKeyBehaviorInFocusedWindow;
import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_KEYCHORD_DELAY;
import static com.android.server.GestureLauncherService.CAMERA_POWER_TAP_COUNT_THRESHOLD;
import static com.android.server.flags.Flags.modifierShortcutManagerMultiuser;
import static com.android.server.flags.Flags.modifierShortcutManagerMultiuser;
import static com.android.server.flags.Flags.newBugreportKeyboardShortcut;
import static com.android.server.flags.Flags.newBugreportKeyboardShortcut;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_KEYCHORD_DELAY;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED;
@@ -433,16 +431,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    private static final String ACTION_VOICE_ASSIST_RETAIL =
    private static final String ACTION_VOICE_ASSIST_RETAIL =
            "android.intent.action.VOICE_ASSIST_RETAIL";
            "android.intent.action.VOICE_ASSIST_RETAIL";


    /**
     * Maximum amount of time in milliseconds between consecutive power onKeyDown events to be
     * considered a multi-press, only used for the power button.
     * Note: To maintain backwards compatibility for the power button, we are measuring the times
     * between consecutive down events instead of the first tap's up event and the second tap's
     * down event.
     */
    @VisibleForTesting public static final int POWER_MULTI_PRESS_TIMEOUT_MILLIS =
            ViewConfiguration.getMultiPressTimeout();

    /**
    /**
     * Lock protecting internal state.  Must not call out into window
     * Lock protecting internal state.  Must not call out into window
     * manager with lock held.  (This lock will be acquired in places
     * manager with lock held.  (This lock will be acquired in places
@@ -504,32 +492,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {


    private WindowWakeUpPolicy mWindowWakeUpPolicy;
    private WindowWakeUpPolicy mWindowWakeUpPolicy;


    /**
     * The three variables below are used for custom power key gesture detection in
     * PhoneWindowManager. They are used to detect when the power button has been double pressed
     * and, when it does happen, makes the behavior overrideable by the app.
     *
     * We cannot use the {@link PowerKeyRule} for this because multi-press power gesture detection
     * and behaviors are handled by {@link com.android.server.GestureLauncherService}, and the
     * {@link PowerKeyRule} only handles single and long-presses of the power button. As a result,
     * overriding the double tap behavior requires custom gesture detection here that mimics the
     * logic in {@link com.android.server.GestureLauncherService}.
     *
     * Long-term, it would be beneficial to move all power gesture detection to
     * {@link PowerKeyRule} so that this custom logic isn't required.
     */
    // Time of last power down event.
    private long mLastPowerDown;

    // Number of power button events consecutively triggered (within a specific timeout threshold).
    private int mPowerButtonConsecutiveTaps = 0;

    // Whether a double tap of the power button has been detected.
    volatile boolean mDoubleTapPowerDetected;

    // Runnable that is queued on a delay when the first power keyDown event is sent to the app.
    private Runnable mPowerKeyDelayedRunnable = null;

    boolean mSafeMode;
    boolean mSafeMode;


    // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
    // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
@@ -1135,11 +1097,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mPowerKeyHandled = mPowerKeyHandled || hungUp
        mPowerKeyHandled = mPowerKeyHandled || hungUp
                || handledByPowerManager || isKeyGestureTriggered
                || handledByPowerManager || isKeyGestureTriggered
                || mKeyCombinationManager.isPowerKeyIntercepted();
                || mKeyCombinationManager.isPowerKeyIntercepted();

        if (overridePowerKeyBehaviorInFocusedWindow()) {
            mPowerKeyHandled |= mDoubleTapPowerDetected;
        }

        if (!mPowerKeyHandled) {
        if (!mPowerKeyHandled) {
            if (!interactive) {
            if (!interactive) {
                wakeUpFromWakeKey(event);
                wakeUpFromWakeKey(event);
@@ -2712,21 +2669,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            if (mShouldEarlyShortPressOnPower) {
            if (mShouldEarlyShortPressOnPower) {
                return;
                return;
            }
            }
            // TODO(b/380433365): Remove deferring single power press action when refactoring.
            if (overridePowerKeyBehaviorInFocusedWindow()) {
                mDeferredKeyActionExecutor.cancelQueuedAction(KEYCODE_POWER);
                mDeferredKeyActionExecutor.queueKeyAction(
                        KEYCODE_POWER,
                        downTime,
                        () -> {
                            powerPress(downTime, 1 /*count*/, displayId);
                        });
            } else {
            powerPress(downTime, 1 /*count*/, displayId);
            powerPress(downTime, 1 /*count*/, displayId);
        }
        }


        }

        @Override
        @Override
        long getLongPressTimeoutMs() {
        long getLongPressTimeoutMs() {
            if (getResolvedLongPressOnPowerBehavior() == LONG_PRESS_POWER_ASSISTANT) {
            if (getResolvedLongPressOnPowerBehavior() == LONG_PRESS_POWER_ASSISTANT) {
@@ -2755,18 +2700,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {


        @Override
        @Override
        void onMultiPress(long downTime, int count, int displayId) {
        void onMultiPress(long downTime, int count, int displayId) {
            if (overridePowerKeyBehaviorInFocusedWindow()) {
                mDeferredKeyActionExecutor.cancelQueuedAction(KEYCODE_POWER);
                mDeferredKeyActionExecutor.queueKeyAction(
                        KEYCODE_POWER,
                        downTime,
                        () -> {
                            powerPress(downTime, count, displayId);
                        });
            } else {
            powerPress(downTime, count, displayId);
            powerPress(downTime, count, displayId);
        }
        }
        }


        @Override
        @Override
        void onKeyUp(long eventTime, int count, int displayId, int deviceId, int metaState) {
        void onKeyUp(long eventTime, int count, int displayId, int deviceId, int metaState) {
@@ -3542,12 +3477,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            }
            }
        }
        }


        if (overridePowerKeyBehaviorInFocusedWindow() && event.getKeyCode() == KEYCODE_POWER
                && event.getAction() == KeyEvent.ACTION_UP
                && mDoubleTapPowerDetected) {
            mDoubleTapPowerDetected = false;
        }

        return needToConsumeKey ? keyConsumed : keyNotConsumed;
        return needToConsumeKey ? keyConsumed : keyNotConsumed;
    }
    }


@@ -4063,8 +3992,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    sendSystemKeyToStatusBarAsync(event);
                    sendSystemKeyToStatusBarAsync(event);
                    return true;
                    return true;
                }
                }
            case KeyEvent.KEYCODE_POWER:
                return interceptPowerKeyBeforeDispatching(focusedToken, event);
            case KeyEvent.KEYCODE_SCREENSHOT:
            case KeyEvent.KEYCODE_SCREENSHOT:
                if (firstDown) {
                if (firstDown) {
                    interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
                    interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
@@ -4120,8 +4047,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    sendSystemKeyToStatusBarAsync(event);
                    sendSystemKeyToStatusBarAsync(event);
                    return true;
                    return true;
                }
                }
            case KeyEvent.KEYCODE_POWER:
                return interceptPowerKeyBeforeDispatching(focusedToken, event);
        }
        }
        if (isValidGlobalKey(keyCode)
        if (isValidGlobalKey(keyCode)
                && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
                && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
@@ -4132,90 +4057,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        return (metaState & KeyEvent.META_META_ON) != 0;
        return (metaState & KeyEvent.META_META_ON) != 0;
    }
    }


    /**
     * Called by interceptKeyBeforeDispatching to handle interception logic for KEYCODE_POWER
     * KeyEvents.
     *
     * @return true if intercepting the key, false if sending to app.
     */
    private boolean interceptPowerKeyBeforeDispatching(IBinder focusedToken, KeyEvent event) {
        if (!overridePowerKeyBehaviorInFocusedWindow()) {
            //Flag disabled: intercept the power key and do not send to app.
            return true;
        }
        if (event.getKeyCode() != KEYCODE_POWER) {
            Log.wtf(TAG, "interceptPowerKeyBeforeDispatching received a non-power KeyEvent "
                    + "with key code: " + event.getKeyCode());
            return false;
        }

        // Intercept keys (don't send to app) for 3x, 4x, 5x gestures)
        if (mPowerButtonConsecutiveTaps > CAMERA_POWER_TAP_COUNT_THRESHOLD) {
            setDeferredKeyActionsExecutableAsync(KEYCODE_POWER, event.getDownTime());
            return true;
        }

        // UP key; just reuse the original decision.
        if (event.getAction() == KeyEvent.ACTION_UP) {
            final Set<Integer> consumedKeys = mConsumedKeysForDevice.get(event.getDeviceId());
            return consumedKeys != null
                    && consumedKeys.contains(event.getKeyCode());
        }

        KeyInterceptionInfo info =
                mWindowManagerInternal.getKeyInterceptionInfoFromToken(focusedToken);

        if (info == null || !mButtonOverridePermissionChecker.canWindowOverridePowerKey(mContext,
                info.windowOwnerUid, info.inputFeaturesFlags)) {
            // The focused window does not have the permission to override power key behavior.
            if (DEBUG_INPUT) {
                String interceptReason = "";
                if (info == null) {
                    interceptReason = "Window is null";
                } else if (!mButtonOverridePermissionChecker.canAppOverrideSystemKey(mContext,
                        info.windowOwnerUid)) {
                    interceptReason = "Application does not have "
                            + "OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW permission";
                } else {
                    interceptReason = "Window does not have inputFeatureFlag set";
                }

                Log.d(TAG, String.format("Intercepting KEYCODE_POWER event. action=%d, "
                                + "eventTime=%d to window=%s. interceptReason=%s. "
                                + "mDoubleTapPowerDetected=%b",
                        event.getAction(), event.getEventTime(), (info != null)
                                ? info.windowTitle : "null", interceptReason,
                        mDoubleTapPowerDetected));
            }
            // Intercept the key (i.e. do not send to app)
            setDeferredKeyActionsExecutableAsync(KEYCODE_POWER, event.getDownTime());
            return true;
        }

        if (DEBUG_INPUT) {
            Log.d(TAG, String.format("Sending KEYCODE_POWER to app. action=%d, "
                            + "eventTime=%d to window=%s. mDoubleTapPowerDetected=%b",
                    event.getAction(), event.getEventTime(), info.windowTitle,
                    mDoubleTapPowerDetected));
        }

        if (!mDoubleTapPowerDetected) {
            //Single press: post a delayed runnable for the single press power action that will be
            // called if it's not cancelled by a double press.
            final var downTime = event.getDownTime();
            mPowerKeyDelayedRunnable = () ->
                    setDeferredKeyActionsExecutableAsync(KEYCODE_POWER, downTime);
            mHandler.postDelayed(mPowerKeyDelayedRunnable, POWER_MULTI_PRESS_TIMEOUT_MILLIS);
        } else if (mPowerKeyDelayedRunnable != null) {
            //Double press detected: cancel the single press runnable.
            mHandler.removeCallbacks(mPowerKeyDelayedRunnable);
            mPowerKeyDelayedRunnable = null;
        }

        // Focused window has permission. Send to app.
        return false;
    }

    @SuppressLint("MissingPermission")
    @SuppressLint("MissingPermission")
    private void initKeyGestures() {
    private void initKeyGestures() {
        if (!useKeyGestureEventHandler()) {
        if (!useKeyGestureEventHandler()) {
@@ -4792,11 +4633,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            return true;
            return true;
        }
        }


        if (overridePowerKeyBehaviorInFocusedWindow() && keyCode == KEYCODE_POWER) {
            handleUnhandledSystemKey(event);
            return true;
        }

        if (useKeyGestureEventHandler()) {
        if (useKeyGestureEventHandler()) {
            return false;
            return false;
        }
        }
@@ -5631,13 +5467,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                        KeyEvent.actionToString(event.getAction()),
                        KeyEvent.actionToString(event.getAction()),
                        mPowerKeyHandled ? 1 : 0,
                        mPowerKeyHandled ? 1 : 0,
                        mSingleKeyGestureDetector.getKeyPressCounter(KeyEvent.KEYCODE_POWER));
                        mSingleKeyGestureDetector.getKeyPressCounter(KeyEvent.KEYCODE_POWER));
                if (overridePowerKeyBehaviorInFocusedWindow()) {
                    result |= ACTION_PASS_TO_USER;
                } else {
                // Any activity on the power button stops the accessibility shortcut
                // Any activity on the power button stops the accessibility shortcut
                result &= ~ACTION_PASS_TO_USER;
                result &= ~ACTION_PASS_TO_USER;
                }

                isWakeKey = false; // wake-up will be handled separately
                isWakeKey = false; // wake-up will be handled separately
                if (down) {
                if (down) {
                    interceptPowerKeyDown(event, interactiveAndAwake, isKeyGestureTriggered);
                    interceptPowerKeyDown(event, interactiveAndAwake, isKeyGestureTriggered);
@@ -5899,32 +5730,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }
        }


        if (event.getKeyCode() == KEYCODE_POWER && event.getAction() == KeyEvent.ACTION_DOWN) {
        if (event.getKeyCode() == KEYCODE_POWER && event.getAction() == KeyEvent.ACTION_DOWN) {
            if (overridePowerKeyBehaviorInFocusedWindow()) {
                if (mGestureLauncherService != null) {
                    mGestureLauncherService.processPowerKeyDown(event);
                }

                if (detectDoubleTapPower(event)) {
                    mDoubleTapPowerDetected = true;

                    // Copy of the event for handler in case the original event gets recycled.
                    KeyEvent eventCopy = KeyEvent.obtain(event);
                    mDeferredKeyActionExecutor.queueKeyAction(
                            KeyEvent.KEYCODE_POWER,
                            eventCopy.getEventTime(),
                            () -> {
                                if (!handleCameraGesture(eventCopy, interactive)) {
                                    mSingleKeyGestureDetector.interceptKey(
                                            eventCopy, interactive, defaultDisplayOn);
                                } else {
                                    mSingleKeyGestureDetector.reset();
                                }
                                eventCopy.recycle();
                            });
                    return;
                }
            }

            mPowerKeyHandled = handleCameraGesture(event, interactive);
            mPowerKeyHandled = handleCameraGesture(event, interactive);
            if (mPowerKeyHandled) {
            if (mPowerKeyHandled) {
                // handled by camera gesture.
                // handled by camera gesture.
@@ -5936,27 +5741,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mSingleKeyGestureDetector.interceptKey(event, interactive, defaultDisplayOn);
        mSingleKeyGestureDetector.interceptKey(event, interactive, defaultDisplayOn);
    }
    }


    private boolean detectDoubleTapPower(KeyEvent event) {
        if (event.getKeyCode() != KEYCODE_POWER || event.getAction() != KeyEvent.ACTION_DOWN) {
            return false;
        }
        if (event.isLongPress()) {
            return false;
        }

        final long powerTapInterval = event.getEventTime() - mLastPowerDown;
        mLastPowerDown = event.getEventTime();
        if (powerTapInterval >= POWER_MULTI_PRESS_TIMEOUT_MILLIS) {
            // Tap too slow for double press
            mPowerButtonConsecutiveTaps = 1;
        } else {
            mPowerButtonConsecutiveTaps++;
        }

        return powerTapInterval < POWER_MULTI_PRESS_TIMEOUT_MILLIS
                && mPowerButtonConsecutiveTaps == CAMERA_POWER_TAP_COUNT_THRESHOLD;
    }

    // The camera gesture will be detected by GestureLauncherService.
    // The camera gesture will be detected by GestureLauncherService.
    private boolean handleCameraGesture(KeyEvent event, boolean interactive) {
    private boolean handleCameraGesture(KeyEvent event, boolean interactive) {
        // camera gesture.
        // camera gesture.
@@ -7813,12 +7597,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    null)
                    null)
                    == PERMISSION_GRANTED;
                    == PERMISSION_GRANTED;
        }
        }

        boolean canWindowOverridePowerKey(Context context, int uid, int inputFeaturesFlags) {
            return canAppOverrideSystemKey(context, uid)
                    && (inputFeaturesFlags & WindowManager.LayoutParams
                    .INPUT_FEATURE_RECEIVE_POWER_KEY_DOUBLE_PRESS) != 0;
        }
    }
    }


    private int getTargetDisplayIdForKeyEvent(KeyEvent event) {
    private int getTargetDisplayIdForKeyEvent(KeyEvent event) {
+2 −3
Original line number Original line Diff line number Diff line
@@ -5750,10 +5750,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                || mKeyInterceptionInfo.layoutParamsPrivateFlags != getAttrs().privateFlags
                || mKeyInterceptionInfo.layoutParamsPrivateFlags != getAttrs().privateFlags
                || mKeyInterceptionInfo.layoutParamsType != getAttrs().type
                || mKeyInterceptionInfo.layoutParamsType != getAttrs().type
                || mKeyInterceptionInfo.windowTitle != getWindowTag()
                || mKeyInterceptionInfo.windowTitle != getWindowTag()
                || mKeyInterceptionInfo.windowOwnerUid != getOwningUid()
                || mKeyInterceptionInfo.windowOwnerUid != getOwningUid()) {
                || mKeyInterceptionInfo.inputFeaturesFlags != getAttrs().inputFeatures) {
            mKeyInterceptionInfo = new KeyInterceptionInfo(getAttrs().type, getAttrs().privateFlags,
            mKeyInterceptionInfo = new KeyInterceptionInfo(getAttrs().type, getAttrs().privateFlags,
                    getWindowTag().toString(), getOwningUid(), getAttrs().inputFeatures);
                    getWindowTag().toString(), getOwningUid());
        }
        }
        return mKeyInterceptionInfo;
        return mKeyInterceptionInfo;
    }
    }
+0 −69
Original line number Original line Diff line number Diff line
@@ -1408,47 +1408,6 @@ public class GestureLauncherServiceTest {
        assertEquals(1, tapCounts.get(1).intValue());
        assertEquals(1, tapCounts.get(1).intValue());
    }
    }


    /**
     * If processPowerKeyDown is called instead of interceptPowerKeyDown (meaning the double tap
     * gesture isn't performed), the emergency gesture is still launched.
     */
    @Test
    public void
            testProcessPowerKeyDown_fiveInboundPresses_cameraDoesNotLaunch_emergencyGestureLaunches() {
        enableCameraGesture();
        enableEmergencyGesture();

        // First event
        long eventTime = INITIAL_EVENT_TIME_MILLIS;
        sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false);

        //Second event; call processPowerKeyDown without calling interceptPowerKeyDown
        final long interval = CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
        eventTime += interval;
        KeyEvent keyEvent =
                new KeyEvent(
                        IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, IGNORED_REPEAT);
        mGestureLauncherService.processPowerKeyDown(keyEvent);

        verify(mMetricsLogger, never())
                .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
        verify(mUiEventLogger, never()).log(any());

        // Presses 3 and 4 should not trigger any gesture
        for (int i = 0; i < 2; i++) {
            eventTime += interval;
            sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, false);
        }

        // Fifth button press should still trigger the emergency flow
        eventTime += interval;
        sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, true);

        verify(mUiEventLogger, times(1))
                .log(GestureLauncherService.GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER);
        verify(mStatusBarManagerInternal).onEmergencyActionLaunchGestureDetected();
    }

    /**
    /**
     * Helper method to trigger emergency gesture by pressing button for 5 times.
     * Helper method to trigger emergency gesture by pressing button for 5 times.
     *
     *
@@ -1551,32 +1510,4 @@ public class GestureLauncherServiceTest {
                userSetupCompleteValue,
                userSetupCompleteValue,
                UserHandle.USER_CURRENT);
                UserHandle.USER_CURRENT);
    }
    }


    private void enableEmergencyGesture() {
        withEmergencyGestureEnabledConfigValue(true);
        withEmergencyGestureEnabledSettingValue(true);
        mGestureLauncherService.updateEmergencyGestureEnabled();
        withUserSetupCompleteValue(true);
    }

    private void enableCameraGesture() {
        withCameraDoubleTapPowerEnableConfigValue(true);
        withCameraDoubleTapPowerDisableSettingValue(0);
        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
        withUserSetupCompleteValue(true);
    }

    private void sendPowerKeyDownToGestureLauncherServiceAndAssertValues(
            long eventTime, boolean expectedIntercept, boolean expectedOutLaunchedValue) {
        KeyEvent keyEvent =
                new KeyEvent(
                        IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, IGNORED_REPEAT);
        boolean interactive = true;
        MutableBoolean outLaunched = new MutableBoolean(true);
        boolean intercepted =
                mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, outLaunched);
        assertEquals(intercepted, expectedIntercept);
        assertEquals(outLaunched.value, expectedOutLaunchedValue);
    }
}
}
Loading