From 2155bc2be3d38b876335eb06f08e81fc2d563831 Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Tue, 1 May 2018 00:38:32 +0100 Subject: [PATCH] Generally improve brightness dumpsys. For the recent spate of autobrightness bugs, being able to determine both current state of the display brightness and the overall situational context of the device (e.g. ALS readings) is critical to quick diagnosis. This tidies up the logs and adds some more state information so we have more context about the situation the device is in. Bug: 78909876 Test: adb shell dumpsys display Change-Id: I0e3cd5d00268b5b44f3d486fae8940d7d7d2ed2e --- core/res/res/values/config.xml | 3 - core/res/res/values/symbols.xml | 1 - .../AutomaticBrightnessController.java | 38 +++++++++--- .../server/display/BrightnessTracker.java | 30 ++++++--- .../display/DisplayPowerController.java | 62 ++++++++++++++++--- .../server/display/HysteresisLevels.java | 10 +++ 6 files changed, 113 insertions(+), 31 deletions(-) diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index bc43d91d9d190..a3530705ca655 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1285,9 +1285,6 @@ adapt to the environment. This mode may be better suited for watches. --> true - - 10000 - diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index db2aa8ecb16b7..fb275ba863cd2 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1905,7 +1905,6 @@ - diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index 0425844bd9e3a..03784d0db9bf0 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -20,12 +20,14 @@ import com.android.server.EventLogTags; import com.android.server.LocalServices; import android.annotation.Nullable; +import android.app.ActivityManager; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.display.BrightnessConfiguration; import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -91,6 +93,8 @@ class AutomaticBrightnessController { // The minimum and maximum screen brightnesses. private final int mScreenBrightnessRangeMinimum; private final int mScreenBrightnessRangeMaximum; + + // How much to scale doze brightness by (should be (0, 1.0]). private final float mDozeScaleFactor; // Initial light sensor event rate in milliseconds. @@ -122,8 +126,8 @@ class AutomaticBrightnessController { // weighting values positive. private final int mWeightingIntercept; - // accessor object for determining thresholds to change brightness dynamically - private final HysteresisLevels mDynamicHysteresis; + // Configuration object for determining thresholds to change brightness dynamically + private final HysteresisLevels mHysteresisLevels; // Amount of time to delay auto-brightness after screen on while waiting for // the light sensor to warm-up in milliseconds. @@ -192,7 +196,7 @@ class AutomaticBrightnessController { int lightSensorWarmUpTime, int brightnessMin, int brightnessMax, float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig, - int ambientLightHorizon, HysteresisLevels dynamicHysteresis) { + HysteresisLevels hysteresisLevels) { mCallbacks = callbacks; mSensorManager = sensorManager; mBrightnessMapper = mapper; @@ -206,9 +210,9 @@ class AutomaticBrightnessController { mBrighteningLightDebounceConfig = brighteningLightDebounceConfig; mDarkeningLightDebounceConfig = darkeningLightDebounceConfig; mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig; - mAmbientLightHorizon = ambientLightHorizon; - mWeightingIntercept = ambientLightHorizon; - mDynamicHysteresis = dynamicHysteresis; + mAmbientLightHorizon = AMBIENT_LIGHT_LONG_HORIZON_MILLIS; + mWeightingIntercept = AMBIENT_LIGHT_LONG_HORIZON_MILLIS; + mHysteresisLevels = hysteresisLevels; mShortTermModelValid = true; mShortTermModelAnchor = -1; @@ -338,19 +342,24 @@ class AutomaticBrightnessController { pw.println("Automatic Brightness Controller Configuration:"); pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum); pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum); + pw.println(" mDozeScaleFactor=" + mDozeScaleFactor); + pw.println(" mInitialLightSensorRate=" + mInitialLightSensorRate); + pw.println(" mNormalLightSensorRate=" + mNormalLightSensorRate); pw.println(" mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig); pw.println(" mBrighteningLightDebounceConfig=" + mBrighteningLightDebounceConfig); pw.println(" mDarkeningLightDebounceConfig=" + mDarkeningLightDebounceConfig); pw.println(" mResetAmbientLuxAfterWarmUpConfig=" + mResetAmbientLuxAfterWarmUpConfig); + pw.println(" mAmbientLightHorizon=" + mAmbientLightHorizon); + pw.println(" mWeightingIntercept=" + mWeightingIntercept); pw.println(); pw.println("Automatic Brightness Controller State:"); pw.println(" mLightSensor=" + mLightSensor); pw.println(" mLightSensorEnabled=" + mLightSensorEnabled); pw.println(" mLightSensorEnableTime=" + TimeUtils.formatUptime(mLightSensorEnableTime)); + pw.println(" mCurrentLightSensorRate=" + mCurrentLightSensorRate); pw.println(" mAmbientLux=" + mAmbientLux); pw.println(" mAmbientLuxValid=" + mAmbientLuxValid); - pw.println(" mAmbientLightHorizon=" + mAmbientLightHorizon); pw.println(" mBrighteningLuxThreshold=" + mBrighteningLuxThreshold); pw.println(" mDarkeningLuxThreshold=" + mDarkeningLuxThreshold); pw.println(" mLastObservedLux=" + mLastObservedLux); @@ -358,11 +367,20 @@ class AutomaticBrightnessController { pw.println(" mRecentLightSamples=" + mRecentLightSamples); pw.println(" mAmbientLightRingBuffer=" + mAmbientLightRingBuffer); pw.println(" mScreenAutoBrightness=" + mScreenAutoBrightness); - pw.println(" mDisplayPolicy=" + mDisplayPolicy); + pw.println(" mDisplayPolicy=" + DisplayPowerRequest.policyToString(mDisplayPolicy)); pw.println(" mShortTermModelAnchor=" + mShortTermModelAnchor); + pw.println(" mShortTermModelValid=" + mShortTermModelValid); + pw.println(" mBrightnessAdjustmentSamplePending=" + mBrightnessAdjustmentSamplePending); + pw.println(" mBrightnessAdjustmentSampleOldLux=" + mBrightnessAdjustmentSampleOldLux); + pw.println(" mBrightnessAdjustmentSampleOldBrightness=" + + mBrightnessAdjustmentSampleOldBrightness); + pw.println(" mShortTermModelValid=" + mShortTermModelValid); pw.println(); mBrightnessMapper.dump(pw); + + pw.println(); + mHysteresisLevels.dump(pw); } private boolean setLightSensorEnabled(boolean enable) { @@ -437,8 +455,8 @@ class AutomaticBrightnessController { lux = 0; } mAmbientLux = lux; - mBrighteningLuxThreshold = mDynamicHysteresis.getBrighteningThreshold(lux); - mDarkeningLuxThreshold = mDynamicHysteresis.getDarkeningThreshold(lux); + mBrighteningLuxThreshold = mHysteresisLevels.getBrighteningThreshold(lux); + mDarkeningLuxThreshold = mHysteresisLevels.getDarkeningThreshold(lux); // If the short term model was invalidated and the change is drastic enough, reset it. if (!mShortTermModelValid && mShortTermModelAnchor != -1) { diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java index 407fad0c9fe88..a568fe336f377 100644 --- a/services/core/java/com/android/server/display/BrightnessTracker.java +++ b/services/core/java/com/android/server/display/BrightnessTracker.java @@ -68,10 +68,11 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; import java.util.ArrayDeque; import java.util.ArrayList; - import java.util.Collections; +import java.util.Date; import java.util.Deque; import java.util.HashMap; import java.util.Map; @@ -115,6 +116,8 @@ public class BrightnessTracker { private static final int MSG_STOP_SENSOR_LISTENER = 2; private static final int MSG_START_SENSOR_LISTENER = 3; + private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); + // Lock held while accessing mEvents, is held while writing events to flash. private final Object mEventsLock = new Object(); @GuardedBy("mEventsLock") @@ -127,10 +130,10 @@ public class BrightnessTracker { private AmbientBrightnessStatsTracker mAmbientBrightnessStatsTracker; - private UserManager mUserManager; + private final UserManager mUserManager; private final Context mContext; private final ContentResolver mContentResolver; - private Handler mBgHandler; + private final Handler mBgHandler; // mBroadcastReceiver, mSensorListener, mSettingsObserver and mSensorRegistered // should only be used on the mBgHandler thread. @@ -164,6 +167,8 @@ public class BrightnessTracker { } else { mInjector = new Injector(); } + mBgHandler = new TrackerHandler(mInjector.getBackgroundHandler().getLooper()); + mUserManager = mContext.getSystemService(UserManager.class); } /** @@ -175,8 +180,6 @@ public class BrightnessTracker { if (DEBUG) { Slog.d(TAG, "Start"); } - mBgHandler = new TrackerHandler(mInjector.getBackgroundHandler().getLooper()); - mUserManager = mContext.getSystemService(UserManager.class); mCurrentUserId = ActivityManager.getCurrentUser(); mBgHandler.obtainMessage(MSG_BACKGROUND_START, (Float) initialBrightness).sendToTarget(); } @@ -649,10 +652,12 @@ public class BrightnessTracker { } } - public void dump(PrintWriter pw) { + public void dump(final PrintWriter pw) { pw.println("BrightnessTracker state:"); synchronized (mDataCollectionLock) { pw.println(" mStarted=" + mStarted); + pw.println(" mLastBatteryLevel=" + mLastBatteryLevel); + pw.println(" mLastBrightness=" + mLastBrightness); pw.println(" mLastSensorReadings.size=" + mLastSensorReadings.size()); if (!mLastSensorReadings.isEmpty()) { pw.println(" mLastSensorReadings time span " @@ -665,7 +670,8 @@ public class BrightnessTracker { pw.println(" mEvents.size=" + mEvents.size()); BrightnessChangeEvent[] events = mEvents.toArray(); for (int i = 0; i < events.length; ++i) { - pw.print(" " + events[i].timeStamp + ", " + events[i].userId); + pw.print(" " + FORMAT.format(new Date(events[i].timeStamp))); + pw.print(", userId=" + events[i].userId); pw.print(", " + events[i].lastBrightness + "->" + events[i].brightness); pw.print(", isUserSetBrightness=" + events[i].isUserSetBrightness); pw.print(", powerBrightnessFactor=" + events[i].powerBrightnessFactor); @@ -680,17 +686,23 @@ public class BrightnessTracker { pw.println("}"); } } + pw.println(" mWriteBrightnessTrackerStateScheduled=" + + mWriteBrightnessTrackerStateScheduled); + mBgHandler.runWithScissors(() -> dumpLocal(pw), 1000); if (mAmbientBrightnessStatsTracker != null) { pw.println(); mAmbientBrightnessStatsTracker.dump(pw); } } + private void dumpLocal(PrintWriter pw) { + pw.println(" mSensorRegistered=" + mSensorRegistered); + } + public ParceledListSlice getAmbientBrightnessStats(int userId) { if (mAmbientBrightnessStatsTracker != null) { ArrayList stats = - mAmbientBrightnessStatsTracker.getUserStats( - userId); + mAmbientBrightnessStatsTracker.getUserStats(userId); if (stats != null) { return new ParceledListSlice<>(stats); } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 3b35d025f595e..1be507e4b9c03 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -295,6 +295,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private boolean mAppliedAutoBrightness; private boolean mAppliedDimming; private boolean mAppliedLowPower; + private boolean mAppliedScreenBrightnessOverride; + private boolean mAppliedTemporaryBrightness; + private boolean mAppliedTemporaryAutoBrightnessAdjustment; + private boolean mAppliedBrightnessBoost; // Brightness animation ramp rates in brightness units per second private final int mBrightnessRampRateFast; @@ -424,7 +428,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call com.android.internal.R.array.config_dynamicHysteresisDarkLevels); int[] luxHysteresisLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisLuxLevels); - HysteresisLevels dynamicHysteresis = new HysteresisLevels( + HysteresisLevels hysteresisLevels = new HysteresisLevels( brightLevels, darkLevels, luxHysteresisLevels); long brighteningLightDebounce = resources.getInteger( @@ -433,8 +437,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce); boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean( com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp); - int ambientLightHorizon = resources.getInteger( - com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon); int lightSensorWarmUpTimeConfig = resources.getInteger( com.android.internal.R.integer.config_lightSensorWarmupTime); @@ -457,8 +459,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call lightSensorWarmUpTimeConfig, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate, initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce, - autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon, - dynamicHysteresis); + autoBrightnessResetAmbientLuxAfterWarmUp, hysteresisLevels); } else { mUseSoftwareAutoBrightnessConfig = false; } @@ -776,6 +777,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (brightness < 0 && mPowerRequest.screenBrightnessOverride > 0) { brightness = mPowerRequest.screenBrightnessOverride; + mAppliedScreenBrightnessOverride = true; + } else { + mAppliedScreenBrightnessOverride = false; } final boolean autoBrightnessEnabledInDoze = @@ -784,7 +788,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call && (state == Display.STATE_ON || autoBrightnessEnabledInDoze) && brightness < 0 && mAutomaticBrightnessController != null; - boolean brightnessIsTemporary = false; final boolean userSetBrightnessChanged = updateUserSetScreenBrightness(); if (userSetBrightnessChanged) { @@ -795,7 +798,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // WindowManager or based on the display state. if (mTemporaryScreenBrightness > 0) { brightness = mTemporaryScreenBrightness; - brightnessIsTemporary = true; + mAppliedTemporaryBrightness = true; + } else { + mAppliedTemporaryBrightness = false; } final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment(); @@ -807,9 +812,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call final float autoBrightnessAdjustment; if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) { autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment; - brightnessIsTemporary = true; + mAppliedTemporaryAutoBrightnessAdjustment = true; } else { autoBrightnessAdjustment = mAutoBrightnessAdjustment; + mAppliedTemporaryAutoBrightnessAdjustment = true; } // Apply brightness boost. @@ -819,6 +825,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (mPowerRequest.boostScreenBrightness && brightness != PowerManager.BRIGHTNESS_OFF) { brightness = PowerManager.BRIGHTNESS_ON; + mAppliedBrightnessBoost = true; + } else { + mAppliedBrightnessBoost = false; } // If the brightness is already set then it's been overridden by something other than the @@ -948,6 +957,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // level without it being a noticeable jump since any actual content isn't yet visible. final boolean isDisplayContentVisible = mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f; + final boolean brightnessIsTemporary = + mAppliedTemporaryBrightness || mAppliedTemporaryAutoBrightnessAdjustment; if (initialRampSkip || hasBrightnessBuckets || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) { animateScreenBrightness(brightness, 0); @@ -1586,10 +1597,20 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println(" mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig); pw.println(" mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum); pw.println(" mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum); + pw.println(" mScreenBrightnessDefault=" + mScreenBrightnessDefault); + pw.println(" mScreenBrightnessForVrRangeMinimum=" + mScreenBrightnessForVrRangeMinimum); + pw.println(" mScreenBrightnessForVrRangeMaximum=" + mScreenBrightnessForVrRangeMaximum); + pw.println(" mScreenBrightnessForVrDefault=" + mScreenBrightnessForVrDefault); pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig); pw.println(" mAllowAutoBrightnessWhileDozingConfig=" + mAllowAutoBrightnessWhileDozingConfig); + pw.println(" mBrightnessRampRateFast=" + mBrightnessRampRateFast); + pw.println(" mBrightnessRampRateSlow=" + mBrightnessRampRateSlow); + pw.println(" mSkipScreenOnBrightnessRamp=" + mSkipScreenOnBrightnessRamp); pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig); + pw.println(" mColorFadeEnabled=" + mColorFadeEnabled); + pw.println(" mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig); + pw.println(" mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig); mHandler.runWithScissors(new Runnable() { @Override @@ -1603,6 +1624,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println(); pw.println("Display Power Controller Thread State:"); pw.println(" mPowerRequest=" + mPowerRequest); + pw.println(" mUnfinishedBusiness=" + mUnfinishedBusiness); pw.println(" mWaitingForNegativeProximity=" + mWaitingForNegativeProximity); pw.println(" mProximitySensor=" + mProximitySensor); pw.println(" mProximitySensorEnabled=" + mProximitySensorEnabled); @@ -1615,12 +1637,23 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println(" mLastUserSetScreenBrightness=" + mLastUserSetScreenBrightness); pw.println(" mCurrentScreenBrightnessSetting=" + mCurrentScreenBrightnessSetting); pw.println(" mPendingScreenBrightnessSetting=" + mPendingScreenBrightnessSetting); + pw.println(" mTemporaryScreenBrightness=" + mTemporaryScreenBrightness); pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment); + pw.println(" mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment); pw.println(" mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment); + pw.println(" mScreenBrightnessForVr=" + mScreenBrightnessForVr); pw.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness); pw.println(" mAppliedDimming=" + mAppliedDimming); pw.println(" mAppliedLowPower=" + mAppliedLowPower); + pw.println(" mAppliedScreenBrightnessOverride=" + mAppliedScreenBrightnessOverride); + pw.println(" mAppliedTemporaryBrightness=" + mAppliedTemporaryBrightness); + pw.println(" mDozing=" + mDozing); + pw.println(" mSkipRampState=" + skipRampStateToString(mSkipRampState)); + pw.println(" mInitialAutoBrightness=" + mInitialAutoBrightness); + pw.println(" mScreenOnBlockStartRealTime=" + mScreenOnBlockStartRealTime); + pw.println(" mScreenOffBlockStartRealTime=" + mScreenOffBlockStartRealTime); pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker); + pw.println(" mPendingScreenOffUnblocker=" + mPendingScreenOffUnblocker); pw.println(" mPendingScreenOff=" + mPendingScreenOff); pw.println(" mReportedToPolicy=" + reportedToPolicyToString(mReportedScreenStateToPolicy)); @@ -1677,6 +1710,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } + private static String skipRampStateToString(int state) { + switch (state) { + case RAMP_STATE_SKIP_NONE: + return "RAMP_STATE_SKIP_NONE"; + case RAMP_STATE_SKIP_INITIAL: + return "RAMP_STATE_SKIP_INITIAL"; + case RAMP_STATE_SKIP_AUTOBRIGHT: + return "RAMP_STATE_SKIP_AUTOBRIGHT"; + default: + return Integer.toString(state); + } + } + private static int clampAbsoluteBrightness(int value) { return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON); } diff --git a/services/core/java/com/android/server/display/HysteresisLevels.java b/services/core/java/com/android/server/display/HysteresisLevels.java index b062225638118..1c02dd1fcdf4c 100644 --- a/services/core/java/com/android/server/display/HysteresisLevels.java +++ b/services/core/java/com/android/server/display/HysteresisLevels.java @@ -18,6 +18,9 @@ package com.android.server.display; import android.util.Slog; +import java.io.PrintWriter; +import java.util.Arrays; + /** * A helper class for handling access to illuminance hysteresis level values. */ @@ -101,4 +104,11 @@ final class HysteresisLevels { } return levelArray; } + + public void dump(PrintWriter pw) { + pw.println("HysteresisLevels"); + pw.println(" mBrightLevels=" + Arrays.toString(mBrightLevels)); + pw.println(" mDarkLevels=" + Arrays.toString(mDarkLevels)); + pw.println(" mLuxLevels=" + Arrays.toString(mLuxLevels)); + } }