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

Commit afcae178 authored by bquezada's avatar bquezada Committed by Michael Wright
Browse files

Add sensor for flip to screen off. See go/flip-to-screen-off-design-doc for design details.

Test: atest FaceDownDetectorTest & Tested with local device.
Bug: 164517126
Bug: 169780171

Change-Id: I7bc634a0ce4b4ae56e017e8cde127cd9c722e0eb
(cherry picked from commit 2be8baec)
parent fc39b029
Loading
Loading
Loading
Loading
+456 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.power;

import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;

import android.annotation.NonNull;
import android.app.ActivityThread;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.provider.DeviceConfig;
import android.util.Slog;

import com.android.internal.util.FrameworkStatsLog;

import java.io.PrintWriter;
import java.time.Duration;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;

/**
 * Class used to detect when the phone is placed face down. This is used for Flip to Screen Off. A
 * client can use this detector to trigger state changes like screen off when the phone is face
 * down.
 */
public class FaceDownDetector implements SensorEventListener {

    private static final String TAG = "FaceDownDetector";
    private static final boolean DEBUG = false;

    private static final int SCREEN_OFF_RESULT =
            FrameworkStatsLog.FACE_DOWN_REPORTED__FACE_DOWN_RESPONSE__SCREEN_OFF;
    private static final int USER_INTERACTION =
            FrameworkStatsLog.FACE_DOWN_REPORTED__FACE_DOWN_RESPONSE__USER_INTERACTION;
    private static final int UNFLIP =
            FrameworkStatsLog.FACE_DOWN_REPORTED__FACE_DOWN_RESPONSE__UNFLIP;

    /**
     * Used by the ExponentialMovingAverage accelerations, this determines how quickly the
     * average can change. A number closer to 1 will mean it will take longer to change.
     */
    private static final float MOVING_AVERAGE_WEIGHT = 0.5f;

    /** DeviceConfig flag name, if {@code true}, enables Face Down features. */
    private static final String KEY_FEATURE_ENABLED = "enable_flip_to_screen_off";

    /** Default value in absence of {@link DeviceConfig} override. */
    private static final boolean DEFAULT_FEATURE_ENABLED = true;

    private boolean mIsEnabled;

    /**
     * DeviceConfig flag name, determines how long to disable sensor when user interacts while
     * device is flipped.
     */
    private static final String KEY_INTERACTION_BACKOFF = "face_down_interaction_backoff_millis";

    /** Default value in absence of {@link DeviceConfig} override. */
    private static final long DEFAULT_INTERACTION_BACKOFF = 60_000;

    private long mUserInteractionBackoffMillis;

    /**
     * DeviceConfig flag name, defines the max change in acceleration which will prevent face down
     * due to movement.
     */
    static final String KEY_ACCELERATION_THRESHOLD = "acceleration_threshold";

    /** Default value in absence of {@link DeviceConfig} override. */
    static final float DEFAULT_ACCELERATION_THRESHOLD = 0.2f;

    private float mAccelerationThreshold;

    /**
     * DeviceConfig flag name, defines the maximum z-axis acceleration that will indicate the phone
     * is face down.
     */
    static final String KEY_Z_ACCELERATION_THRESHOLD = "z_acceleration_threshold";

    /** Default value in absence of {@link DeviceConfig} override. */
    static final float DEFAULT_Z_ACCELERATION_THRESHOLD = -9.5f;

    private float mZAccelerationThreshold;

    /**
     * After going face down, we relax the threshold to make it more difficult to exit face down
     * than to enter it.
     */
    private float mZAccelerationThresholdLenient;

    /**
     * DeviceConfig flag name, defines the minimum amount of time that has to pass while the phone
     * is face down and not moving in order to trigger face down behavior, in milliseconds.
     */
    static final String KEY_TIME_THRESHOLD_MILLIS = "time_threshold_millis";

    /** Default value in absence of {@link DeviceConfig} override. */
    static final long DEFAULT_TIME_THRESHOLD_MILLIS = 1_000L;

    private Duration mTimeThreshold;

    private Sensor mAccelerometer;
    private SensorManager mSensorManager;
    private final Consumer<Boolean> mOnFlip;

    /** Values we store for logging purposes. */
    private long mLastFlipTime = 0L;
    public int mPreviousResultType = 0;
    public long mPreviousResultTime = 0L;
    private long mMillisSaved = 0L;

    private final ExponentialMovingAverage mCurrentXYAcceleration =
            new ExponentialMovingAverage(MOVING_AVERAGE_WEIGHT);
    private final ExponentialMovingAverage mCurrentZAcceleration =
            new ExponentialMovingAverage(MOVING_AVERAGE_WEIGHT);

    private boolean mFaceDown = false;
    private boolean mActive = false;

    private float mPrevAcceleration = 0;
    private long mPrevAccelerationTime = 0;

    private boolean mZAccelerationIsFaceDown = false;
    private long mZAccelerationFaceDownTime = 0L;

    private final Handler mHandler;
    private final Runnable mUserActivityRunnable;

    public FaceDownDetector(@NonNull Consumer<Boolean> onFlip) {
        mOnFlip = Objects.requireNonNull(onFlip);
        mHandler = new Handler(Looper.getMainLooper());
        mUserActivityRunnable = () -> {
            if (mFaceDown) {
                exitFaceDown(USER_INTERACTION, SystemClock.uptimeMillis() - mLastFlipTime);
                checkAndUpdateActiveState(false);
            }
        };
    }

    /** Initializes the FaceDownDetector and all necessary listeners. */
    public void systemReady(Context context) {
        mSensorManager = context.getSystemService(SensorManager.class);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        readValuesFromDeviceConfig();
        checkAndUpdateActiveState(true);
        DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_ATTENTION_MANAGER_SERVICE,
                ActivityThread.currentApplication().getMainExecutor(),
                (properties) -> onDeviceConfigChange(properties.getKeyset()));
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
        intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        context.registerReceiver(new ScreenStateReceiver(), intentFilter);
    }

    /**
     * Sets the active state of the detector. If false, we will not process accelerometer changes.
     */
    private void checkAndUpdateActiveState(boolean active) {
        if (mIsEnabled && mActive != active) {
            final long currentTime = SystemClock.uptimeMillis();
            // Don't make active if there was recently a user interaction while face down.
            if (active && mPreviousResultType == USER_INTERACTION
                    && currentTime - mPreviousResultTime  < mUserInteractionBackoffMillis) {
                return;
            }
            if (DEBUG) Slog.d(TAG, "Update active - " + active);
            mActive = active;
            if (!active) {
                if (mFaceDown && mPreviousResultTime != USER_INTERACTION) {
                    mPreviousResultType = SCREEN_OFF_RESULT;
                    mPreviousResultTime = currentTime;
                }
                mSensorManager.unregisterListener(this);
                mFaceDown = false;
                mOnFlip.accept(false);
            } else {
                if (mPreviousResultType == SCREEN_OFF_RESULT) {
                    logScreenOff();
                }
                mSensorManager.registerListener(
                        this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
            }
        }
    }

    /** Prints state information about FaceDownDetector */
    public void dump(PrintWriter pw) {
        pw.println("FaceDownDetector:");
        pw.println("  mFaceDown=" + mFaceDown);
        pw.println("  mActive=" + mActive);
        pw.println("  mLastFlipTime=" + mLastFlipTime);
        pw.println("  mUserInteractionBackoffMillis=" + mUserInteractionBackoffMillis);
        pw.println("  mPreviousResultTime=" + mPreviousResultTime);
        pw.println("  mPreviousResultType=" + mPreviousResultType);
        pw.println("  mMillisSaved=" + mMillisSaved);
        pw.println("  mZAccelerationThreshold=" + mZAccelerationThreshold);
        pw.println("  mAccelerationThreshold=" + mAccelerationThreshold);
        pw.println("  mTimeThreshold=" + mTimeThreshold);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) return;
        if (!mActive || !mIsEnabled) return;

        final float x = event.values[0];
        final float y = event.values[1];
        mCurrentXYAcceleration.updateMovingAverage(x * x + y * y);
        mCurrentZAcceleration.updateMovingAverage(event.values[2]);

        // Detect movement
        // If the x, y acceleration is within the acc threshold for at least a length of time longer
        // than the time threshold, we set moving to true.
        final long curTime = event.timestamp;
        if (Math.abs(mCurrentXYAcceleration.mMovingAverage - mPrevAcceleration)
                > mAccelerationThreshold) {
            mPrevAcceleration = mCurrentXYAcceleration.mMovingAverage;
            mPrevAccelerationTime = curTime;
        }
        final boolean moving = curTime - mPrevAccelerationTime <= mTimeThreshold.toNanos();

        // If the z acceleration is beyond the gravity/z-acceleration threshold for at least a
        // length of time longer than the time threshold, we set isFaceDownForPeriod to true.
        final float zAccelerationThreshold =
                mFaceDown ? mZAccelerationThresholdLenient : mZAccelerationThreshold;
        final boolean isCurrentlyFaceDown =
                mCurrentZAcceleration.mMovingAverage < zAccelerationThreshold;
        final boolean isFaceDownForPeriod = isCurrentlyFaceDown
                && mZAccelerationIsFaceDown
                && curTime - mZAccelerationFaceDownTime > mTimeThreshold.toNanos();
        if (isCurrentlyFaceDown && !mZAccelerationIsFaceDown) {
            mZAccelerationFaceDownTime = curTime;
            mZAccelerationIsFaceDown = true;
        } else if (!isCurrentlyFaceDown) {
            mZAccelerationIsFaceDown = false;
        }


        if (!moving && isFaceDownForPeriod && !mFaceDown) {
            faceDownDetected();
        } else if (!isFaceDownForPeriod && mFaceDown) {
            unFlipDetected();
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {}

    private void faceDownDetected() {
        if (DEBUG) Slog.d(TAG, "Triggered faceDownDetected.");
        mLastFlipTime = SystemClock.uptimeMillis();
        mFaceDown = true;
        mOnFlip.accept(true);
    }

    private void unFlipDetected() {
        if (DEBUG) Slog.d(TAG, "Triggered exitFaceDown");
        exitFaceDown(UNFLIP, SystemClock.uptimeMillis() - mLastFlipTime);
    }

    /**
     * The user interacted with the screen while face down, indicated the phone is in use.
     * We log this event and temporarily make this detector inactive.
     */
    public void userActivity() {
        mHandler.post(mUserActivityRunnable);
    }

    private void exitFaceDown(int resultType, long millisSinceFlip) {
        FrameworkStatsLog.write(FrameworkStatsLog.FACE_DOWN_REPORTED,
                resultType,
                millisSinceFlip,
                /* millis_until_normal_timeout= */ 0L,
                /* millis_until_next_screen_on= */ 0L);
        mFaceDown = false;
        mLastFlipTime = 0L;
        mPreviousResultType = resultType;
        mPreviousResultTime = SystemClock.uptimeMillis();
        mOnFlip.accept(false);
    }

    private void logScreenOff() {
        if (mPreviousResultType == SCREEN_OFF_RESULT) {
            final long currentTime = SystemClock.uptimeMillis();
            FrameworkStatsLog.write(FrameworkStatsLog.FACE_DOWN_REPORTED,
                    mPreviousResultType,
                    /* millis_since_flip= */ mPreviousResultTime  - mLastFlipTime,
                    mMillisSaved,
                    /* millis_until_next_screen_on= */ currentTime - mPreviousResultTime);
            mPreviousResultType = -1;
        }
    }

    private boolean isEnabled() {
        return DeviceConfig.getBoolean(NAMESPACE_ATTENTION_MANAGER_SERVICE, KEY_FEATURE_ENABLED,
                DEFAULT_FEATURE_ENABLED);
    }

    private float getAccelerationThreshold() {
        return getFloatFlagValue(KEY_ACCELERATION_THRESHOLD,
                DEFAULT_ACCELERATION_THRESHOLD,
                -2.0f,
                2.0f);
    }

    private float getZAccelerationThreshold() {
        return getFloatFlagValue(KEY_Z_ACCELERATION_THRESHOLD,
                DEFAULT_Z_ACCELERATION_THRESHOLD,
                -15.0f,
                0.0f);
    }

    private long getUserInteractionBackoffMillis() {
        return getLongFlagValue(KEY_INTERACTION_BACKOFF,
                DEFAULT_INTERACTION_BACKOFF,
                0,
                3600_000);
    }

    private float getFloatFlagValue(String key, float defaultValue, float min, float max) {
        final float value = DeviceConfig.getFloat(NAMESPACE_ATTENTION_MANAGER_SERVICE,
                key,
                defaultValue);

        if (value < min || value > max) {
            Slog.w(TAG, "Bad flag value supplied for: " + key);
            return defaultValue;
        }

        return value;
    }

    private long getLongFlagValue(String key, long defaultValue, long min, long max) {
        final long value = DeviceConfig.getLong(NAMESPACE_ATTENTION_MANAGER_SERVICE,
                key,
                defaultValue);

        if (value < min || value > max) {
            Slog.w(TAG, "Bad flag value supplied for: " + key);
            return defaultValue;
        }

        return value;
    }

    private Duration getTimeThreshold() {
        final long millis = DeviceConfig.getLong(NAMESPACE_ATTENTION_MANAGER_SERVICE,
                KEY_TIME_THRESHOLD_MILLIS,
                DEFAULT_TIME_THRESHOLD_MILLIS);

        if (millis < 0 || millis > 15_000) {
            Slog.w(TAG, "Bad flag value supplied for: " + KEY_TIME_THRESHOLD_MILLIS);
            return Duration.ofMillis(DEFAULT_TIME_THRESHOLD_MILLIS);
        }

        return Duration.ofMillis(millis);
    }

    private void onDeviceConfigChange(@NonNull Set<String> keys) {
        for (String key : keys) {
            switch (key) {
                case KEY_ACCELERATION_THRESHOLD:
                case KEY_Z_ACCELERATION_THRESHOLD:
                case KEY_TIME_THRESHOLD_MILLIS:
                case KEY_FEATURE_ENABLED:
                    readValuesFromDeviceConfig();
                    return;
                default:
                    Slog.i(TAG, "Ignoring change on " + key);
            }
        }
    }

    private void readValuesFromDeviceConfig() {
        mAccelerationThreshold = getAccelerationThreshold();
        mZAccelerationThreshold = getZAccelerationThreshold();
        mZAccelerationThresholdLenient = mZAccelerationThreshold + 1.0f;
        mTimeThreshold = getTimeThreshold();
        mIsEnabled = isEnabled();
        mUserInteractionBackoffMillis = getUserInteractionBackoffMillis();

        Slog.i(TAG, "readValuesFromDeviceConfig():"
                + "\nmAccelerationThreshold=" + mAccelerationThreshold
                + "\nmZAccelerationThreshold=" + mZAccelerationThreshold
                + "\nmTimeThreshold=" + mTimeThreshold
                + "\nmIsEnabled=" + mIsEnabled);
    }

    /**
     * Sets how much screen on time might be saved as a result of this detector. Currently used for
     * logging purposes.
     */
    public void setMillisSaved(long millisSaved) {
        mMillisSaved = millisSaved;
    }

    private final class ScreenStateReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
                checkAndUpdateActiveState(false);
            } else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
                checkAndUpdateActiveState(true);
            }
        }
    }

    private final class ExponentialMovingAverage {
        private final float mAlpha;
        private final float mInitialAverage;
        private float mMovingAverage;

        ExponentialMovingAverage(float alpha) {
            this(alpha, 0.0f);
        }

        ExponentialMovingAverage(float alpha, float initialAverage) {
            this.mAlpha = alpha;
            this.mInitialAverage = initialAverage;
            this.mMovingAverage = initialAverage;
        }

        void updateMovingAverage(float newValue) {
            mMovingAverage = newValue + mAlpha * (mMovingAverage - newValue);
        }

        void reset() {
            mMovingAverage = this.mInitialAverage;
        }
    }
}
+5 −1
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ public class Notifier {
    private final AppOpsManager mAppOps;
    private final SuspendBlocker mSuspendBlocker;
    private final WindowManagerPolicy mPolicy;
    private final FaceDownDetector mFaceDownDetector;
    private final ActivityManagerInternal mActivityManagerInternal;
    private final InputManagerInternal mInputManagerInternal;
    private final InputMethodManagerInternal mInputMethodManagerInternal;
@@ -165,12 +166,14 @@ public class Notifier {
    private boolean mUserActivityPending;

    public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
            SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
            SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
            FaceDownDetector faceDownDetector) {
        mContext = context;
        mBatteryStats = batteryStats;
        mAppOps = mContext.getSystemService(AppOpsManager.class);
        mSuspendBlocker = suspendBlocker;
        mPolicy = policy;
        mFaceDownDetector = faceDownDetector;
        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
        mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
        mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
@@ -654,6 +657,7 @@ public class Notifier {
        TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
        tm.notifyUserActivity();
        mPolicy.userActivity();
        mFaceDownDetector.userActivity();
    }

    void postEnhancedDischargePredictionBroadcast(long delayMs) {
+51 −4
Original line number Diff line number Diff line
@@ -176,6 +176,8 @@ public final class PowerManagerService extends SystemService
    private static final int DIRTY_VR_MODE_CHANGED = 1 << 13;
    // Dirty bit: attentive timer may have timed out
    private static final int DIRTY_ATTENTIVE = 1 << 14;
    // Dirty bit: phone flipped to face down
    private static final int DIRTY_FACE_DOWN = 1 << 15;

    // Summarizes the state of all active wakelocks.
    private static final int WAKE_LOCK_CPU = 1 << 0;
@@ -263,6 +265,7 @@ public final class PowerManagerService extends SystemService
    private final BatterySaverStateMachine mBatterySaverStateMachine;
    private final BatterySavingStats mBatterySavingStats;
    private final AttentionDetector mAttentionDetector;
    private final FaceDownDetector mFaceDownDetector;
    private final BinderService mBinderService;
    private final LocalService mLocalService;
    private final NativeWrapper mNativeWrapper;
@@ -547,6 +550,10 @@ public final class PowerManagerService extends SystemService
    public final float mScreenBrightnessMaximumVr;
    public final float mScreenBrightnessDefaultVr;

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

    // The screen brightness mode.
    // One of the Settings.System.SCREEN_BRIGHTNESS_MODE_* constants.
    private int mScreenBrightnessModeSetting;
@@ -791,8 +798,10 @@ public final class PowerManagerService extends SystemService
    @VisibleForTesting
    static class Injector {
        Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
                SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
            return new Notifier(looper, context, batteryStats, suspendBlocker, policy);
                SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
                FaceDownDetector faceDownDetector) {
            return new Notifier(
                    looper, context, batteryStats, suspendBlocker, policy, faceDownDetector);
        }

        SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) {
@@ -906,6 +915,7 @@ public final class PowerManagerService extends SystemService
        mAmbientDisplaySuppressionController =
                mInjector.createAmbientDisplaySuppressionController(context);
        mAttentionDetector = new AttentionDetector(this::onUserAttention, mLock);
        mFaceDownDetector = new FaceDownDetector(this::onFlip);

        mBatterySavingStats = new BatterySavingStats(mLock);
        mBatterySaverPolicy =
@@ -1011,6 +1021,26 @@ public final class PowerManagerService extends SystemService
        }
    }

    private void onFlip(boolean isFaceDown) {
        long millisUntilNormalTimeout = 0;
        synchronized (mLock) {
            mIsFaceDown = isFaceDown;
            if (isFaceDown) {
                final long currentTime = mClock.uptimeMillis();
                mLastFlipTime = currentTime;
                final long sleepTimeout = getSleepTimeoutLocked(-1L);
                final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout, -1L);
                millisUntilNormalTimeout =
                        mLastUserActivityTime + screenOffTimeout - mClock.uptimeMillis();
                mDirty |= DIRTY_FACE_DOWN;
                updatePowerStateLocked();
            }
        }
        if (isFaceDown) {
            mFaceDownDetector.setMillisSaved(millisUntilNormalTimeout);
        }
    }

    @Override
    public void onStart() {
        publishBinderService(Context.POWER_SERVICE, mBinderService, /* allowIsolated= */ false,
@@ -1065,7 +1095,7 @@ public final class PowerManagerService extends SystemService
            mBatteryStats = BatteryStatsService.getService();
            mNotifier = mInjector.createNotifier(Looper.getMainLooper(), mContext, mBatteryStats,
                    mInjector.createSuspendBlocker(this, "PowerManagerService.Broadcasts"),
                    mPolicy);
                    mPolicy, mFaceDownDetector);

            mWirelessChargerDetector = mInjector.createWirelessChargerDetector(sensorManager,
                    mInjector.createSuspendBlocker(
@@ -1099,6 +1129,7 @@ public final class PowerManagerService extends SystemService

        mBatterySaverController.systemReady();
        mBatterySaverPolicy.systemReady();
        mFaceDownDetector.systemReady(mContext);

        // Register for settings changes.
        resolver.registerContentObserver(Settings.Secure.getUriFor(
@@ -2283,9 +2314,11 @@ public final class PowerManagerService extends SystemService
                    || getWakefulnessLocked() == WAKEFULNESS_DOZING) {
                final long attentiveTimeout = getAttentiveTimeoutLocked();
                final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);
                final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
                long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
                        attentiveTimeout);
                final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
                screenOffTimeout =
                        getScreenOffTimeoutWithFaceDownLocked(screenOffTimeout, screenDimDuration);
                final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
                final long nextProfileTimeout = getNextProfileTimeoutLocked(now);

@@ -2541,6 +2574,16 @@ public final class PowerManagerService extends SystemService
                (long)(screenOffTimeout * mMaximumScreenDimRatioConfig));
    }

    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.
        if (mIsFaceDown) {
            return Math.min(screenDimDuration, screenOffTimeout);
        }
        return screenOffTimeout;
    }

    /**
     * Updates the wakefulness of the device.
     *
@@ -3859,6 +3902,8 @@ public final class PowerManagerService extends SystemService
            pw.println("  mDisplayReady=" + mDisplayReady);
            pw.println("  mHoldingWakeLockSuspendBlocker=" + mHoldingWakeLockSuspendBlocker);
            pw.println("  mHoldingDisplaySuspendBlocker=" + mHoldingDisplaySuspendBlocker);
            pw.println("  mLastFlipTime=" + mLastFlipTime);
            pw.println("  mIsFaceDown=" + mIsFaceDown);

            pw.println();
            pw.println("Settings and Configuration:");
@@ -4003,6 +4048,8 @@ public final class PowerManagerService extends SystemService
            mNotifier.dump(pw);
        }

        mFaceDownDetector.dump(pw);

        mAmbientDisplaySuppressionController.dump(pw);
    }

+165 −0

File added.

Preview size limit exceeded, changes collapsed.

+3 −1

File changed.

Preview size limit exceeded, changes collapsed.

Loading