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

Commit 3143b284 authored by Manish Kushwaha's avatar Manish Kushwaha Committed by Android (Google) Code Review
Browse files

Merge "Introduce new wake lock level for screen timeout" into main

parents 4d96906b ce7e8a7f
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -183,6 +183,22 @@ public final class PowerManager {
     */
    public static final int DRAW_WAKE_LOCK = OsProtoEnums.DRAW_WAKE_LOCK; // 0x00000080

    /**
     * Wake lock level: Override the current screen timeout.
     * <p>
     *  This is used by the system to allow {@code PowerManagerService} to override the current
     *  screen timeout by config value.
     *
     *  config_screenTimeoutOverride in config.xml determines the screen timeout override value.
     * </p><p>
     * Requires the {@link android.Manifest.permission#SCREEN_TIMEOUT_OVERRIDE} permission.
     * </p>
     *
     * @hide
     */
    public static final int SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK =
            OsProtoEnums.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK; // 0x00000100

    /**
     * Mask for the wake lock level component of a combined wake lock level and flags integer.
     *
@@ -1369,6 +1385,7 @@ public final class PowerManager {
            case PROXIMITY_SCREEN_OFF_WAKE_LOCK:
            case DOZE_WAKE_LOCK:
            case DRAW_WAKE_LOCK:
            case SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK:
                break;
            default:
                throw new IllegalArgumentException("Must specify a valid wake lock level.");
+9 −0
Original line number Diff line number Diff line
@@ -8168,6 +8168,15 @@
    <permission android:name="android.permission.RESTRICT_DISPLAY_MODES"
        android:protectionLevel="signature" />

    <!-- Allows internal applications to override screen timeout temporarily
        <p>Protection level: signature
        <p>Not for use by third-party applications.
        @FlaggedApi("com.android.server.power.feature.flags.enable_early_screen_timeout_detector")
        @hide
    -->
    <permission android:name="android.permission.SCREEN_TIMEOUT_OVERRIDE"
                android:protectionLevel="signature" />

    <!-- Attribution for Geofencing service. -->
    <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
    <!-- Attribution for Country Detector. -->
+7 −0
Original line number Diff line number Diff line
@@ -2883,6 +2883,13 @@
    -->
    <integer name="config_minimumScreenOffTimeout">10000</integer>

    <!-- User activity timeout: Screen timeout override in milliseconds.

         This value must be greater than 0, otherwise the invalid value will not apply to
         the screen timeout override policy.
    -->
    <integer name="config_screenTimeoutOverride">-1</integer>

    <!-- User activity timeout: Maximum screen dim duration in milliseconds.

         Sets an upper bound for how long the screen will dim before the device goes
+1 −0
Original line number Diff line number Diff line
@@ -2285,6 +2285,7 @@
  <java-symbol type="bool" name="config_powerDecoupleAutoSuspendModeFromDisplay" />
  <java-symbol type="bool" name="config_powerDecoupleInteractiveModeFromDisplay" />
  <java-symbol type="integer" name="config_minimumScreenOffTimeout" />
  <java-symbol type="integer" name="config_screenTimeoutOverride" />
  <java-symbol type="integer" name="config_maximumScreenDimDuration" />
  <java-symbol type="fraction" name="config_maximumScreenDimRatio" />
  <java-symbol type="integer" name="config_attentiveTimeout" />
+117 −22
Original line number Diff line number Diff line
@@ -179,6 +179,9 @@ public final class PowerManagerService extends SystemService
    // Message: Sent when an attentive timeout occurs to update the power state.
    private static final int MSG_ATTENTIVE_TIMEOUT = 5;

    // Message: Sent when the policy want to release all timeout override wake locks.
    private static final int MSG_RELEASE_ALL_OVERRIDE_WAKE_LOCKS = 6;

    // Dirty bit: mWakeLocks changed
    private static final int DIRTY_WAKE_LOCKS = 1 << 0;
    // Dirty bit: mWakefulness changed
@@ -219,6 +222,7 @@ public final class PowerManagerService extends SystemService
    static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
    static final int WAKE_LOCK_DOZE = 1 << 6;
    static final int WAKE_LOCK_DRAW = 1 << 7;
    static final int WAKE_LOCK_SCREEN_TIMEOUT_OVERRIDE = 1 << 8;

    // Summarizes the user activity state.
    static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
@@ -616,7 +620,8 @@ public final class PowerManagerService extends SystemService
    public final float mScreenBrightnessDim;

    // Value we store for tracking face down behavior.
    private boolean mIsFaceDown = false;
    @VisibleForTesting
    boolean mIsFaceDown = false;
    private long mLastFlipTime = 0L;

    // The screen brightness setting override from the window manager
@@ -707,6 +712,9 @@ public final class PowerManagerService extends SystemService
    // Whether to keep dreaming when the device is unplugging.
    private boolean mKeepDreamingWhenUnplugging;

    @GuardedBy("mLock")
    private ScreenTimeoutOverridePolicy mScreenTimeoutOverridePolicy;

    private final class DreamManagerStateListener implements
            DreamManagerInternal.DreamManagerStateListener {
        @Override
@@ -734,6 +742,12 @@ public final class PowerManagerService extends SystemService
                userActivityNoUpdateLocked(mPowerGroups.get(groupId), eventTime,
                        PowerManager.USER_ACTIVITY_EVENT_OTHER, flags, uid);
            }

            // Release wake lock when default display is not interactive.
            if (mScreenTimeoutOverridePolicy != null && groupId == Display.DEFAULT_DISPLAY_GROUP) {
                mScreenTimeoutOverridePolicy.onWakefulnessChange(mWakeLockSummary, wakefulness);
            }

            mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS;
            mNotifier.onGroupWakefulnessChangeStarted(groupId, wakefulness, reason, eventTime);
            updateGlobalWakefulnessLocked(eventTime, reason, uid, opUid, opPackageName, details);
@@ -1401,6 +1415,13 @@ public final class PowerManagerService extends SystemService
            // Go.
            readConfigurationLocked();
            updateSettingsLocked();
            if (mFeatureFlags.isEarlyScreenTimeoutDetectorEnabled()) {
                mScreenTimeoutOverridePolicy = new ScreenTimeoutOverridePolicy(mContext,
                        mMinimumScreenOffTimeoutConfig, () -> {
                    Message msg = mHandler.obtainMessage(MSG_RELEASE_ALL_OVERRIDE_WAKE_LOCKS);
                    mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
                });
            }
            mDirty |= DIRTY_BATTERY_STATE;
            updatePowerStateLocked();
        }
@@ -1805,7 +1826,7 @@ public final class PowerManagerService extends SystemService
    }

    @GuardedBy("mLock")
    private void removeWakeLockLocked(WakeLock wakeLock, int index) {
    private void removeWakeLockNoUpdateLocked(WakeLock wakeLock, int index) {
        mWakeLocks.remove(index);
        UidState state = wakeLock.mUidState;
        state.mNumWakeLocks--;
@@ -1813,10 +1834,15 @@ public final class PowerManagerService extends SystemService
                state.mProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
            mUidState.remove(state.mUid);
        }
        notifyWakeLockReleasedLocked(wakeLock);

        notifyWakeLockReleasedLocked(wakeLock);
        applyWakeLockFlagsOnReleaseLocked(wakeLock);
        mDirty |= DIRTY_WAKE_LOCKS;
    }

    @GuardedBy("mLock")
    private void removeWakeLockLocked(WakeLock wakeLock, int index) {
        removeWakeLockNoUpdateLocked(wakeLock, index);
        updatePowerStateLocked();
    }

@@ -1999,7 +2025,9 @@ public final class PowerManagerService extends SystemService

                case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
                    return mSystemReady && mDisplayManagerInternal.isProximitySensorAvailable();

                case PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK:
                    return mSystemReady && mFeatureFlags.isEarlyScreenTimeoutDetectorEnabled()
                            && mScreenTimeoutOverridePolicy != null;
                default:
                    return false;
            }
@@ -2096,6 +2124,10 @@ public final class PowerManagerService extends SystemService
            mNotifier.onUserActivity(powerGroup.getGroupId(), event, uid);
            mAttentionDetector.onUserActivity(eventTime, event);

            if (mScreenTimeoutOverridePolicy != null) {
                mScreenTimeoutOverridePolicy.onUserActivity(mWakeLockSummary, event);
            }

            if (mUserInactiveOverrideFromWindowManager) {
                mUserInactiveOverrideFromWindowManager = false;
                mOverriddenTimeout = -1;
@@ -2751,6 +2783,11 @@ public final class PowerManagerService extends SystemService
                }
            }

            // Screen wake lock or non-interactive will release all override wake locks.
            if (mScreenTimeoutOverridePolicy != null) {
                mScreenTimeoutOverridePolicy.checkScreenWakeLock(mWakeLockSummary);
            }

            for (int idx = 0; idx < mPowerGroups.size(); idx++) {
                final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
                final int wakeLockSummary = adjustWakeLockSummary(powerGroup.getWakefulnessLocked(),
@@ -2826,6 +2863,8 @@ public final class PowerManagerService extends SystemService
                return WAKE_LOCK_DOZE;
            case PowerManager.DRAW_WAKE_LOCK:
                return WAKE_LOCK_DRAW;
            case PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK:
                return WAKE_LOCK_SCREEN_TIMEOUT_OVERRIDE;
        }
        return 0;
    }
@@ -2906,11 +2945,10 @@ public final class PowerManagerService extends SystemService

        final long attentiveTimeout = getAttentiveTimeoutLocked();
        final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);
        long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
        final long defaultScreenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
                attentiveTimeout);
        final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
        screenOffTimeout =
                getScreenOffTimeoutWithFaceDownLocked(screenOffTimeout, screenDimDuration);
        final long defaultScreenDimDuration = getScreenDimDurationLocked(defaultScreenOffTimeout);

        final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
        long nextTimeout = -1;
        boolean hasUserActivitySummary = false;
@@ -2919,6 +2957,16 @@ public final class PowerManagerService extends SystemService
            long groupNextTimeout = 0;
            final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
            final int wakefulness = powerGroup.getWakefulnessLocked();

            // The default display screen timeout could be overridden by policy.
            long screenOffTimeout = defaultScreenOffTimeout;
            long screenDimDuration = defaultScreenDimDuration;
            if (powerGroup.getGroupId() == Display.DEFAULT_DISPLAY_GROUP) {
                screenOffTimeout =
                        getScreenOffTimeoutOverrideLocked(screenOffTimeout, screenDimDuration);
                screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
            }

            if (wakefulness != WAKEFULNESS_ASLEEP) {
                final long lastUserActivityTime = powerGroup.getLastUserActivityTimeLocked();
                final long lastUserActivityTimeNoChangeLights =
@@ -3196,15 +3244,20 @@ public final class PowerManagerService extends SystemService
                (long)(screenOffTimeout * mMaximumScreenDimRatioConfig));
    }

    @VisibleForTesting
    @GuardedBy("mLock")
    private long getScreenOffTimeoutWithFaceDownLocked(
            long screenOffTimeout, long screenDimDuration) {
        // If face down, we decrease the timeout to equal the dim duration so that the
        // device will go into a dim state.
    long getScreenOffTimeoutOverrideLocked(long screenOffTimeout, long screenDimDuration) {
        long shortestScreenOffTimeout = screenOffTimeout;
        if (mScreenTimeoutOverridePolicy != null) {
            shortestScreenOffTimeout =
                    mScreenTimeoutOverridePolicy.getScreenTimeoutOverrideLocked(
                            mWakeLockSummary, screenOffTimeout);
        }
        if (mIsFaceDown) {
            return Math.min(screenDimDuration, screenOffTimeout);
            shortestScreenOffTimeout = Math.min(screenDimDuration, shortestScreenOffTimeout);
        }
        return screenOffTimeout;

        return shortestScreenOffTimeout;
    }

    /**
@@ -4815,6 +4868,13 @@ public final class PowerManagerService extends SystemService
        mAmbientDisplaySuppressionController.dump(pw);

        mLowPowerStandbyController.dump(pw);

        synchronized (mLock) {
            if (mScreenTimeoutOverridePolicy != null) {
                mScreenTimeoutOverridePolicy.dump(pw);
            }
        }

        mFeatureFlags.dump(pw);
    }

@@ -5284,6 +5344,9 @@ public final class PowerManagerService extends SystemService
                case MSG_ATTENTIVE_TIMEOUT:
                    handleAttentiveTimeout();
                    break;
                case MSG_RELEASE_ALL_OVERRIDE_WAKE_LOCKS:
                    releaseAllOverrideWakeLocks();
                    break;
            }

            return true;
@@ -5488,6 +5551,8 @@ public final class PowerManagerService extends SystemService
                    return "DOZE_WAKE_LOCK                   ";
                case PowerManager.DRAW_WAKE_LOCK:
                    return "DRAW_WAKE_LOCK                   ";
                case PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK:
                    return "SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK";
                default:
                    return "???                              ";
            }
@@ -5732,6 +5797,17 @@ public final class PowerManagerService extends SystemService
                mContext.enforceCallingOrSelfPermission(
                        android.Manifest.permission.DEVICE_POWER, null);
            }

            if ((flags & PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK) != 0) {
                if (!mFeatureFlags.isEarlyScreenTimeoutDetectorEnabled()) {
                    throw new IllegalArgumentException("Acquiring an unsupported wake lock:"
                            + " flags=" + flags + ", tag=" + tag);
                }

                mContext.enforceCallingOrSelfPermission(
                        android.Manifest.permission.SCREEN_TIMEOUT_OVERRIDE, null);
            }

            if (ws != null && !ws.isEmpty()) {
                mContext.enforceCallingOrSelfPermission(
                        android.Manifest.permission.UPDATE_DEVICE_STATS, null);
@@ -7182,4 +7258,23 @@ public final class PowerManagerService extends SystemService
        }
        return false;
    }

    private void releaseAllOverrideWakeLocks() {
        synchronized (mLock) {
            final int size = mWakeLocks.size();
            boolean change = false;
            for (int i = size - 1; i >= 0; i--) {
                final WakeLock wakeLock = mWakeLocks.get(i);
                if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
                        == PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK) {
                    removeWakeLockNoUpdateLocked(wakeLock, i);
                    change = true;
                }
            }

            if (change) {
                updatePowerStateLocked();
            }
        }
    }
}
Loading