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

Commit 196200de authored by Vishnu Nair's avatar Vishnu Nair Committed by Android (Google) Code Review
Browse files

Merge "Don't hold wm lock when intercepting keys"

parents 77825a15 539334aa
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.internal.policy;


/**
 * Stores a snapshot of window information used to decide whether to intercept a key event.
 */
public class KeyInterceptionInfo {
    // Window layout params attributes.
    public final int layoutParamsType;
    public final int layoutParamsPrivateFlags;
    // Debug friendly name to help identify the window
    public final String windowTitle;

    public KeyInterceptionInfo(int type, int flags, String title) {
        layoutParamsType = type;
        layoutParamsPrivateFlags = flags;
        windowTitle = title;
    }
}
+26 −18
Original line number Diff line number Diff line
@@ -204,6 +204,7 @@ import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.os.RoSystemProperties;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
import com.android.internal.policy.KeyInterceptionInfo;
import com.android.internal.policy.PhoneWindow;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ArrayUtils;
@@ -1603,7 +1604,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            mDisplayId = displayId;
        }

        int handleHomeButton(WindowState win, KeyEvent event) {
        int handleHomeButton(IBinder focusedToken, KeyEvent event) {
            final boolean keyguardOn = keyguardOn();
            final int repeatCount = event.getRepeatCount();
            final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
@@ -1646,18 +1647,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                return -1;
            }

            final KeyInterceptionInfo info =
                    mWindowManagerInternal.getKeyInterceptionInfoFromToken(focusedToken);
            if (info != null) {
                // If a system window has focus, then it doesn't make sense
                // right now to interact with applications.
            WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
            if (attrs != null) {
                final int type = attrs.type;
                if (type == TYPE_KEYGUARD_DIALOG
                        || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                if (info.layoutParamsType == TYPE_KEYGUARD_DIALOG
                        || (info.layoutParamsPrivateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                    // the "app" is keyguard, so give it the key
                    return 0;
                }
                for (int t : WINDOW_TYPES_WHERE_HOME_DOESNT_WORK) {
                    if (type == t) {
                    if (info.layoutParamsType == t) {
                        // don't do anything, but also don't pass it to the app
                        return -1;
                    }
@@ -2598,8 +2599,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    // TODO(b/117479243): handle it in InputPolicy
    /** {@inheritDoc} */
    @Override
    public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
        final long result = interceptKeyBeforeDispatchingInner(win, event, policyFlags);
    public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,
            int policyFlags) {
        final long result = interceptKeyBeforeDispatchingInner(focusedToken, event, policyFlags);
        final int eventDisplayId = event.getDisplayId();
        if (result == 0 && !mPerDisplayFocusEnabled
                && eventDisplayId != INVALID_DISPLAY && eventDisplayId != mTopFocusedDisplayId) {
@@ -2627,7 +2629,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        return result;
    }

    private long interceptKeyBeforeDispatchingInner(WindowState win, KeyEvent event,
    private long interceptKeyBeforeDispatchingInner(IBinder focusedToken, KeyEvent event,
            int policyFlags) {
        final boolean keyguardOn = keyguardOn();
        final int keyCode = event.getKeyCode();
@@ -2730,7 +2732,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                handler = new DisplayHomeButtonHandler(displayId);
                mDisplayHomeButtonHandlers.put(displayId, handler);
            }
            return handler.handleHomeButton(win, event);
            return handler.handleHomeButton(focusedToken, event);
        } else if (keyCode == KeyEvent.KEYCODE_MENU) {
            // Hijack modified menu keys for debugging features
            final int chordBug = KeyEvent.META_SHIFT_ON;
@@ -3131,10 +3133,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    // TODO(b/117479243): handle it in InputPolicy
    /** {@inheritDoc} */
    @Override
    public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
    public KeyEvent dispatchUnhandledKey(IBinder focusedToken, KeyEvent event, int policyFlags) {
        // Note: This method is only called if the initial down was unhandled.
        if (DEBUG_INPUT) {
            Slog.d(TAG, "Unhandled key: win=" + win + ", action=" + event.getAction()
            final KeyInterceptionInfo info =
                    mWindowManagerInternal.getKeyInterceptionInfoFromToken(focusedToken);
            final String title = info == null ? "<unknown>" : info.windowTitle;
            Slog.d(TAG, "Unhandled key: inputToken=" + focusedToken
                    + ", title=" + title
                    + ", action=" + event.getAction()
                    + ", flags=" + event.getFlags()
                    + ", keyCode=" + event.getKeyCode()
                    + ", scanCode=" + event.getScanCode()
@@ -3173,7 +3180,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                        event.getDeviceId(), event.getScanCode(),
                        flags, event.getSource(), event.getDisplayId(), null);

                if (!interceptFallback(win, fallbackEvent, policyFlags)) {
                if (!interceptFallback(focusedToken, fallbackEvent, policyFlags)) {
                    fallbackEvent.recycle();
                    fallbackEvent = null;
                }
@@ -3197,11 +3204,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        return fallbackEvent;
    }

    private boolean interceptFallback(WindowState win, KeyEvent fallbackEvent, int policyFlags) {
    private boolean interceptFallback(IBinder focusedToken, KeyEvent fallbackEvent,
            int policyFlags) {
        int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags);
        if ((actions & ACTION_PASS_TO_USER) != 0) {
            long delayMillis = interceptKeyBeforeDispatching(
                    win, fallbackEvent, policyFlags);
                    focusedToken, fallbackEvent, policyFlags);
            if (delayMillis == 0) {
                return true;
            }
+5 −5
Original line number Diff line number Diff line
@@ -1025,7 +1025,7 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
     * behavior for keys that can not be overridden by applications.
     * This method is called from the input thread, with no locks held.
     *
     * @param win The window that currently has focus.  This is where the key
     * @param focusedToken Client window token that currently has focus. This is where the key
     *            event will normally go.
     * @param event The key event.
     * @param policyFlags The policy flags associated with the key.
@@ -1034,7 +1034,7 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
     * milliseconds by which the key dispatch should be delayed before trying
     * again.
     */
    public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags);
    long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event, int policyFlags);

    /**
     * Called from the input dispatcher thread when an application did not handle
@@ -1043,14 +1043,14 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
     * <p>Allows you to define default global behavior for keys that were not handled
     * by applications.  This method is called from the input thread, with no locks held.
     *
     * @param win The window that currently has focus.  This is where the key
     * @param focusedToken Client window token that currently has focus. This is where the key
     *            event will normally go.
     * @param event The key event.
     * @param policyFlags The policy flags associated with the key.
     * @return Returns an alternate key event to redispatch as a fallback, or null to give up.
     * The caller is responsible for recycling the key event.
     */
    public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags);
    KeyEvent dispatchUnhandledKey(IBinder focusedToken, KeyEvent event, int policyFlags);

    /**
     * Called when the top focused display is changed.
+4 −6
Original line number Diff line number Diff line
@@ -181,9 +181,8 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
     */
    @Override
    public long interceptKeyBeforeDispatching(
            IBinder focus, KeyEvent event, int policyFlags) {
        WindowState windowState = mService.windowForClientLocked(null, focus, false);
        return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
            IBinder focusedToken, KeyEvent event, int policyFlags) {
        return mService.mPolicy.interceptKeyBeforeDispatching(focusedToken, event, policyFlags);
    }

    /**
@@ -192,9 +191,8 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
     */
    @Override
    public KeyEvent dispatchUnhandledKey(
            IBinder focus, KeyEvent event, int policyFlags) {
        WindowState windowState = mService.windowForClientLocked(null, focus, false);
        return mService.mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
            IBinder focusedToken, KeyEvent event, int policyFlags) {
        return mService.mPolicy.dispatchUnhandledKey(focusedToken, event, policyFlags);
    }

    /** Callback to get pointer layer. */
+4 −0
Original line number Diff line number Diff line
@@ -528,6 +528,10 @@ final class InputMonitor {
            populateInputWindowHandle(
                    inputWindowHandle, w, flags, type, isVisible, hasFocus, hasWallpaper);

            // register key interception info
            mService.mKeyInterceptionInfoForToken.put(inputWindowHandle.token,
                    w.getKeyInterceptionInfo());

            if (w.mWinAnimator.hasSurface()) {
                mInputTransaction.setInputWindowInfo(
                        w.mWinAnimator.mSurfaceController.mSurfaceControl, inputWindowHandle);
Loading