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

Commit ad272b7a authored by Yeabkal Wubshit's avatar Yeabkal Wubshit
Browse files

Create WindowWakeUpPolicy

This change is a pure refactor, that takes the wake up calls and policy
from PhoneWindowManager to a new class.

Bug: 317432315
Test: manual test on device against PowerManager wake logs
Change-Id: I18f97c3983d858c1636f3ee81a65d32fb50367ef
parent 850a3f00
Loading
Loading
Loading
Loading
+24 −68
Original line number Diff line number Diff line
@@ -473,6 +473,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    private TalkbackShortcutController mTalkbackShortcutController;

    private WindowWakeUpPolicy mWindowWakeUpPolicy;

    boolean mSafeMode;

    // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
@@ -640,15 +642,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    // Whether to lock the device after the next dreaming transition has finished.
    private boolean mLockAfterDreamingTransitionFinished;

    // Allowed theater mode wake actions
    private boolean mAllowTheaterModeWakeFromKey;
    private boolean mAllowTheaterModeWakeFromPowerKey;
    private boolean mAllowTheaterModeWakeFromMotion;
    private boolean mAllowTheaterModeWakeFromMotionWhenNotDreaming;
    private boolean mAllowTheaterModeWakeFromCameraLens;
    private boolean mAllowTheaterModeWakeFromLidSwitch;
    private boolean mAllowTheaterModeWakeFromWakeGesture;

    // If true, the power button long press behavior will be invoked even if the default display is
    // non-interactive. If false, the power button long press behavior will be skipped if the
    // default display is non-interactive.
@@ -930,8 +923,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                if (shouldEnableWakeGestureLp()) {
                    performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, false,
                            "Wake Up");
                    wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromWakeGesture,
                            PowerManager.WAKE_REASON_GESTURE, "android.policy:GESTURE");
                    mWindowWakeUpPolicy.wakeUpFromWakeGesture();
                }
            }
        }
@@ -1067,7 +1059,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                || handledByPowerManager || mKeyCombinationManager.isPowerKeyIntercepted();
        if (!mPowerKeyHandled) {
            if (!interactive) {
                wakeUpFromPowerKey(event.getDownTime());
                wakeUpFromWakeKey(event);
            }
        } else {
            // handled by another power key policy.
@@ -1309,7 +1301,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    Settings.Global.putInt(mContext.getContentResolver(),
                            Settings.Global.THEATER_MODE_ON, 0);
                    if (!interactive) {
                        wakeUpFromPowerKey(eventTime);
                        wakeUpFromWakeKey(eventTime, KEYCODE_POWER);
                    }
                } else {
                    Slog.i(TAG, "Toggling theater mode on.");
@@ -1325,7 +1317,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            case MULTI_PRESS_POWER_BRIGHTNESS_BOOST:
                Slog.i(TAG, "Starting brightness boost.");
                if (!interactive) {
                    wakeUpFromPowerKey(eventTime);
                    wakeUpFromWakeKey(eventTime, KEYCODE_POWER);
                }
                mPowerManager.boostScreenBrightness(eventTime);
                break;
@@ -2312,22 +2304,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mLidNavigationAccessibility = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_lidNavigationAccessibility);

        mAllowTheaterModeWakeFromKey = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromKey);
        mAllowTheaterModeWakeFromPowerKey = mAllowTheaterModeWakeFromKey
                || mContext.getResources().getBoolean(
                    com.android.internal.R.bool.config_allowTheaterModeWakeFromPowerKey);
        mAllowTheaterModeWakeFromMotion = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromMotion);
        mAllowTheaterModeWakeFromMotionWhenNotDreaming = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromMotionWhenNotDreaming);
        mAllowTheaterModeWakeFromCameraLens = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromCameraLens);
        mAllowTheaterModeWakeFromLidSwitch = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromLidSwitch);
        mAllowTheaterModeWakeFromWakeGesture = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromGesture);

        mGoToSleepOnButtonPressTheaterMode = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_goToSleepOnButtonPressTheaterMode);

@@ -2457,6 +2433,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                com.android.internal.R.integer.config_keyguardDrawnTimeout);
        mKeyguardDelegate = injector.getKeyguardServiceDelegate();
        mTalkbackShortcutController = injector.getTalkbackShortcutController();
        mWindowWakeUpPolicy = new WindowWakeUpPolicy(mContext);
        initKeyCombinationRules();
        initSingleKeyGestureRules(injector.getLooper());
        mButtonOverridePermissionChecker = injector.getButtonOverridePermissionChecker();
@@ -4483,8 +4460,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        updateRotation(true);

        if (lidOpen) {
            wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromLidSwitch,
                    PowerManager.WAKE_REASON_LID, "android.policy:LID");
            mWindowWakeUpPolicy.wakeUpFromLid();
        } else if (getLidBehavior() != LID_BEHAVIOR_SLEEP) {
            mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
        }
@@ -4510,8 +4486,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            } else {
                intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
            }
            wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromCameraLens,
                    PowerManager.WAKE_REASON_CAMERA_LAUNCH, "android.policy:CAMERA_COVER");
            mWindowWakeUpPolicy.wakeUpFromCameraCover(whenNanos / 1000000);
            startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
        }
        mCameraLensCoverState = lensCoverState;
@@ -4589,7 +4564,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            boolean shouldTurnOnTv = false;
            if (down && (keyCode == KeyEvent.KEYCODE_POWER
                    || keyCode == KeyEvent.KEYCODE_TV_POWER)) {
                wakeUpFromPowerKey(event.getDownTime());
                wakeUpFromWakeKey(event);
                shouldTurnOnTv = true;
            } else if (down && (isWakeKey || keyCode == KeyEvent.KEYCODE_WAKEUP)
                    && isWakeKeyWhenScreenOff(keyCode)) {
@@ -5104,9 +5079,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        if (mRequestedOrSleepingDefaultDisplay) {
            mCameraGestureTriggeredDuringGoingToSleep = true;
            // Wake device up early to prevent display doing redundant turning off/on stuff.
            wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromPowerKey,
                    PowerManager.WAKE_REASON_CAMERA_LAUNCH,
                    "android.policy:CAMERA_GESTURE_PREVENT_LOCK");
            mWindowWakeUpPolicy.wakeUpFromPowerKeyCameraGesture();
        }
        return true;
    }
@@ -5204,8 +5177,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    public int interceptMotionBeforeQueueingNonInteractive(int displayId, int source, int action,
            long whenNanos, int policyFlags) {
        if ((policyFlags & FLAG_WAKE) != 0) {
            if (wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion,
                    PowerManager.WAKE_REASON_WAKE_MOTION, "android.policy:MOTION")) {
            if (mWindowWakeUpPolicy.wakeUpFromMotion(whenNanos / 1000000)) {
                // Woke up. Pass motion events to user.
                return ACTION_PASS_TO_USER;
            }
@@ -5219,8 +5191,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        // there will be no dream to intercept the touch and wake into ambient.  The device should
        // wake up in this case.
        if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) {
            if (wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotionWhenNotDreaming,
                    PowerManager.WAKE_REASON_WAKE_MOTION, "android.policy:MOTION")) {
            if (mWindowWakeUpPolicy.wakeUpFromMotion(whenNanos / 1000000)) {
                // Woke up. Pass motion events to user.
                return ACTION_PASS_TO_USER;
            }
@@ -5554,37 +5525,22 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        return sleepDurationRealtime > mWakeUpToLastStateTimeout;
    }

    private void wakeUpFromPowerKey(long eventTime) {
        if (wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey,
                PowerManager.WAKE_REASON_POWER_BUTTON, "android.policy:POWER")) {
            // Start HOME with "reason" extra if sleeping for more than mWakeUpToLastStateTimeout
            if (shouldWakeUpWithHomeIntent()) {
                startDockOrHome(DEFAULT_DISPLAY, /*fromHomeKey*/ false, /*wakenFromDreams*/ true,
                        PowerManager.wakeReasonToString(PowerManager.WAKE_REASON_POWER_BUTTON));
            }
        }
    private void wakeUpFromWakeKey(KeyEvent event) {
        wakeUpFromWakeKey(event.getEventTime(), event.getKeyCode());
    }

    private void wakeUpFromWakeKey(KeyEvent event) {
        if (wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey,
                PowerManager.WAKE_REASON_WAKE_KEY, "android.policy:KEY")) {
    private void wakeUpFromWakeKey(long eventTime, int keyCode) {
        if (mWindowWakeUpPolicy.wakeUpFromKey(eventTime, keyCode)) {
            final boolean keyCanLaunchHome = keyCode == KEYCODE_HOME || keyCode == KEYCODE_POWER;
            // Start HOME with "reason" extra if sleeping for more than mWakeUpToLastStateTimeout
            if (shouldWakeUpWithHomeIntent() && event.getKeyCode() == KEYCODE_HOME) {
                startDockOrHome(DEFAULT_DISPLAY, /*fromHomeKey*/ true, /*wakenFromDreams*/ true,
                        PowerManager.wakeReasonToString(PowerManager.WAKE_REASON_WAKE_KEY));
            }
        }
            if (shouldWakeUpWithHomeIntent() &&  keyCanLaunchHome) {
                startDockOrHome(
                        DEFAULT_DISPLAY,
                        /*fromHomeKey*/ keyCode == KEYCODE_HOME,
                        /*wakenFromDreams*/ true,
                        "Wake from " + KeyEvent. keyCodeToString(keyCode));
            }

    private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, @WakeReason int reason,
            String details) {
        final boolean theaterModeEnabled = isTheaterModeEnabled();
        if (!wakeInTheaterMode && theaterModeEnabled) {
            return false;
        }

        mPowerManager.wakeUp(wakeTime, reason, details);
        return true;
    }

    private void finishKeyguardDrawn() {
+176 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.os.PowerManager.WAKE_REASON_CAMERA_LAUNCH;
import static android.os.PowerManager.WAKE_REASON_GESTURE;
import static android.os.PowerManager.WAKE_REASON_LID;
import static android.os.PowerManager.WAKE_REASON_POWER_BUTTON;
import static android.os.PowerManager.WAKE_REASON_WAKE_KEY;
import static android.os.PowerManager.WAKE_REASON_WAKE_MOTION;
import static android.view.KeyEvent.KEYCODE_POWER;

import android.content.Context;
import android.content.res.Resources;
import android.os.PowerManager;
import android.os.PowerManager.WakeReason;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Slog;


/** Policy controlling the decision and execution of window-related wake ups. */
class WindowWakeUpPolicy {
    private static final String TAG = "WindowWakeUpPolicy";

    private static final boolean DEBUG = false;

    private final Context mContext;
    private final PowerManager mPowerManager;

    private final boolean mAllowTheaterModeWakeFromKey;
    private final boolean mAllowTheaterModeWakeFromPowerKey;
    private final boolean mAllowTheaterModeWakeFromMotion;
    private final boolean mAllowTheaterModeWakeFromMotionWhenNotDreaming;
    private final boolean mAllowTheaterModeWakeFromCameraLens;
    private final boolean mAllowTheaterModeWakeFromLidSwitch;
    private final boolean mAllowTheaterModeWakeFromWakeGesture;

    WindowWakeUpPolicy(Context context) {
        mContext = context;
        mPowerManager = context.getSystemService(PowerManager.class);

        final Resources res = context.getResources();
        mAllowTheaterModeWakeFromKey = res.getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromKey);
        mAllowTheaterModeWakeFromPowerKey = mAllowTheaterModeWakeFromKey
                || res.getBoolean(
                    com.android.internal.R.bool.config_allowTheaterModeWakeFromPowerKey);
        mAllowTheaterModeWakeFromMotion = res.getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromMotion);
        mAllowTheaterModeWakeFromMotionWhenNotDreaming = res.getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromMotionWhenNotDreaming);
        mAllowTheaterModeWakeFromCameraLens = res.getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromCameraLens);
        mAllowTheaterModeWakeFromLidSwitch = res.getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromLidSwitch);
        mAllowTheaterModeWakeFromWakeGesture = res.getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromGesture);
    }

    /**
     * Wakes up from a key event.
     *
     * @param eventTime the timestamp of the event in {@link SystemClock#uptimeMillis()}.
     * @param keyCode the {@link android.view.KeyEvent} key code of the key event.
     * @return {@code true} if the policy allows the requested wake up and the request has been
     *      executed; {@code false} otherwise.
     */
    boolean wakeUpFromKey(long eventTime, int keyCode) {
        final boolean wakeAllowedDuringTheaterMode =
                keyCode == KEYCODE_POWER
                        ? mAllowTheaterModeWakeFromPowerKey
                        : mAllowTheaterModeWakeFromKey;
        return wakeUp(
                eventTime,
                wakeAllowedDuringTheaterMode,
                keyCode == KEYCODE_POWER ? WAKE_REASON_POWER_BUTTON : WAKE_REASON_WAKE_KEY,
                keyCode == KEYCODE_POWER ? "POWER" : "KEY");
    }

    /**
     * Wakes up from a motion event.
     *
     * @param eventTime the timestamp of the event in {@link SystemClock#uptimeMillis()}.
     * @return {@code true} if the policy allows the requested wake up and the request has been
     *      executed; {@code false} otherwise.
     */
    boolean wakeUpFromMotion(long eventTime) {
        return wakeUp(
                eventTime, mAllowTheaterModeWakeFromMotion, WAKE_REASON_WAKE_MOTION, "MOTION");
    }

    /**
     * Wakes up due to an opened camera cover.
     *
     * @param eventTime the timestamp of the event in {@link SystemClock#uptimeMillis()}.
     * @return {@code true} if the policy allows the requested wake up and the request has been
     *      executed; {@code false} otherwise.
     */
    boolean wakeUpFromCameraCover(long eventTime) {
        return wakeUp(
                eventTime,
                mAllowTheaterModeWakeFromCameraLens,
                WAKE_REASON_CAMERA_LAUNCH,
                "CAMERA_COVER");
    }

    /**
     * Wakes up due to an opened lid.
     *
     * @return {@code true} if the policy allows the requested wake up and the request has been
     *      executed; {@code false} otherwise.
     */
    boolean wakeUpFromLid() {
        return wakeUp(
                SystemClock.uptimeMillis(),
                mAllowTheaterModeWakeFromLidSwitch,
                WAKE_REASON_LID,
                "LID");
    }

    /**
     * Wakes up to prevent sleeping when opening camera through power button.
     *
     * @return {@code true} if the policy allows the requested wake up and the request has been
     *      executed; {@code false} otherwise.
     */
    boolean wakeUpFromPowerKeyCameraGesture() {
        return wakeUp(
                SystemClock.uptimeMillis(),
                mAllowTheaterModeWakeFromPowerKey,
                WAKE_REASON_CAMERA_LAUNCH,
                "CAMERA_GESTURE_PREVENT_LOCK");
    }

    /**
     * Wake up from a wake gesture.
     *
     * @return {@code true} if the policy allows the requested wake up and the request has been
     *      executed; {@code false} otherwise.
     */
    boolean wakeUpFromWakeGesture() {
        return wakeUp(
                SystemClock.uptimeMillis(),
                mAllowTheaterModeWakeFromWakeGesture,
                WAKE_REASON_GESTURE,
                "GESTURE");
    }

    private boolean wakeUp(
            long wakeTime, boolean wakeInTheaterMode, @WakeReason int reason, String details) {
        final boolean isTheaterModeEnabled =
                Settings.Global.getInt(
                        mContext.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0) == 1;
        if (!wakeInTheaterMode && isTheaterModeEnabled) {
            if (DEBUG) Slog.d(TAG, "Unable to wake up from " + details);
            return false;
        }
        mPowerManager.wakeUp(wakeTime, reason, "android.policy:" + details);
        return true;
    }
}