diff options
| author | 2019-09-03 14:41:12 -0700 | |
|---|---|---|
| committer | 2019-09-03 14:41:12 -0700 | |
| commit | f024c2ed38be764d7c9c92dac7b2ec2e85a84d57 (patch) | |
| tree | da180e27bfeca29d3220cdc77cbeb96c1997da85 | |
| parent | 406c55da1c113887f233f29909d10d59d773cc30 (diff) | |
| parent | 1f4f57eab4ed383639813fdc5d9642ba038cf93e (diff) | |
Merge "DMD: Support 90hz only in the refresh rate zone" into qt-r1-dev am: d44f2edc08
am: 1f4f57eab4
Change-Id: I7324013fadecc41a956a0b6f109b8aee9dd3a374
| -rw-r--r-- | core/java/android/hardware/display/DisplayManager.java | 23 | ||||
| -rw-r--r-- | core/res/res/values/config.xml | 4 | ||||
| -rw-r--r-- | core/res/res/values/symbols.xml | 1 | ||||
| -rw-r--r-- | services/core/java/com/android/server/display/DisplayModeDirector.java | 128 | 
4 files changed, 121 insertions, 35 deletions
| diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 21c49add6cba..bf794731c6b4 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -829,23 +829,36 @@ public final class DisplayManager {      public interface DeviceConfig {          /** -         * Key for accessing the 60 hz only regions. +         * Key for refresh rate in the zone defined by thresholds. +         * +         * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER +         * @see android.R.integer#config_defaultZoneBehavior +         */ +        String KEY_REFRESH_RATE_IN_ZONE = "refresh_rate_in_zone"; + +        /** +         * Key for accessing the display brightness thresholds for the configured refresh rate zone. +         * The value will be a pair of comma separated integers representing the minimum and maximum +         * thresholds of the zone, respectively, in display backlight units (i.e. [0, 255]).           *           * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER           * @see android.R.array#config_brightnessThresholdsOfPeakRefreshRate           * @hide           */ -        String KEY_PEAK_REFRESH_RATE_BRIGHTNESS_THRESHOLDS = +        String KEY_PEAK_REFRESH_RATE_DISPLAY_BRIGHTNESS_THRESHOLDS =                  "peak_refresh_rate_brightness_thresholds";          /** -         * Key for accessing the 60 hz only regions. +         * Key for accessing the ambient brightness thresholds for the configured refresh rate zone. +         * The value will be a pair of comma separated integers representing the minimum and maximum +         * thresholds of the zone, respectively, in lux.           *           * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER -         * @see android.R.array#config_brightnessThresholdsOfPeakRefreshRate +         * @see android.R.array#config_ambientThresholdsOfPeakRefreshRate           * @hide           */ -        String KEY_PEAK_REFRESH_RATE_AMBIENT_THRESHOLDS = "peak_refresh_rate_ambient_thresholds"; +        String KEY_PEAK_REFRESH_RATE_AMBIENT_BRIGHTNESS_THRESHOLDS = +                "peak_refresh_rate_ambient_thresholds";          /**           * Key for default peak refresh rate diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index e4a5074ddbbf..efc943e3d44a 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4196,6 +4196,10 @@          -->      </integer-array> +    <!-- Default refresh rate in the zone defined by brightness and ambient thresholds. +         If non-positive, then the refresh rate is unchanged even if thresholds are configured. --> +    <integer name="config_defaultRefreshRateInZone">0</integer> +      <!-- The type of the light sensor to be used by the display framework for things like           auto-brightness. If unset, then it just gets the default sensor of type TYPE_LIGHT. -->      <string name="config_displayLightSensorType" translatable="false" /> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 261e76e35a4a..e5805fd91fbb 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3798,6 +3798,7 @@    <!-- For high refresh rate displays -->    <java-symbol type="integer" name="config_defaultPeakRefreshRate" /> +  <java-symbol type="integer" name="config_defaultRefreshRateInZone" />    <java-symbol type="array" name="config_brightnessThresholdsOfPeakRefreshRate" />    <java-symbol type="array" name="config_ambientThresholdsOfPeakRefreshRate" /> diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index 58aadd1cbef4..1fc0db3ff7cb 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -69,6 +69,7 @@ public class DisplayModeDirector {      private static final int MSG_ALLOWED_MODES_CHANGED = 1;      private static final int MSG_BRIGHTNESS_THRESHOLDS_CHANGED = 2;      private static final int MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED = 3; +    private static final int MSG_REFRESH_RATE_IN_ZONE_CHANGED = 4;      // Special ID used to indicate that given vote is to be applied globally, rather than to a      // specific display. @@ -440,23 +441,48 @@ public class DisplayModeDirector {                      mSettingsObserver.onDeviceConfigDefaultPeakRefreshRateChanged(                              defaultPeakRefreshRate);                      break; + +                case MSG_REFRESH_RATE_IN_ZONE_CHANGED: +                    int refreshRateInZone = msg.arg1; +                    mBrightnessObserver.onDeviceConfigRefreshRateInZoneChanged( +                            refreshRateInZone); +                    break;              }          }      }      private static final class Vote { -        // We split the app request into two priorities in case we can satisfy one desire without -        // the other. -        public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 0; -        public static final int PRIORITY_APP_REQUEST_SIZE = 1; -        public static final int PRIORITY_USER_SETTING_REFRESH_RATE = 2; -        public static final int PRIORITY_LOW_BRIGHTNESS = 3; -        public static final int PRIORITY_LOW_POWER_MODE = 4; +        // LOW_BRIGHTNESS votes for a single refresh rate like [60,60], [90,90] or null. +        // If the higher voters result is a range, it will fix the rate to a single choice. +        // It's used to avoid rate switch in certain conditions. +        public static final int PRIORITY_LOW_BRIGHTNESS = 0; + +        // SETTING_MIN_REFRESH_RATE is used to propose a lower bound of display refresh rate. +        // It votes [MIN_REFRESH_RATE, Float.POSITIVE_INFINITY] +        public static final int PRIORITY_USER_SETTING_MIN_REFRESH_RATE = 1; + +        // We split the app request into different priorities in case we can satisfy one desire +        // without the other. + +        // Application can specify preferred refresh rate with below attrs. +        // @see android.view.WindowManager.LayoutParams#preferredRefreshRate +        // @see android.view.WindowManager.LayoutParams#preferredDisplayModeId +        // System also forces some apps like blacklisted app to run at a lower refresh rate. +        // @see android.R.array#config_highRefreshRateBlacklist +        public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 2; +        public static final int PRIORITY_APP_REQUEST_SIZE = 3; + +        // SETTING_PEAK_REFRESH_RATE has a high priority and will restrict the bounds of the rest +        // of low priority voters. It votes [0, max(PEAK, MIN)] +        public static final int PRIORITY_USER_SETTING_PEAK_REFRESH_RATE = 4; + +        // LOW_POWER_MODE force display to [0, 60HZ] if Settings.Global.LOW_POWER_MODE is on. +        public static final int PRIORITY_LOW_POWER_MODE = 5;          // Whenever a new priority is added, remember to update MIN_PRIORITY and/or MAX_PRIORITY as          // appropriate, as well as priorityToString. -        public static final int MIN_PRIORITY = PRIORITY_APP_REQUEST_REFRESH_RATE; +        public static final int MIN_PRIORITY = PRIORITY_LOW_BRIGHTNESS;          public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE;          /** @@ -500,12 +526,16 @@ public class DisplayModeDirector {          public static String priorityToString(int priority) {              switch (priority) { +                case PRIORITY_LOW_BRIGHTNESS: +                    return "PRIORITY_LOW_BRIGHTNESS"; +                case PRIORITY_USER_SETTING_MIN_REFRESH_RATE: +                    return "PRIORITY_USER_SETTING_MIN_REFRESH_RATE";                  case PRIORITY_APP_REQUEST_REFRESH_RATE:                      return "PRIORITY_APP_REQUEST_REFRESH_RATE";                  case PRIORITY_APP_REQUEST_SIZE:                      return "PRIORITY_APP_REQUEST_SIZE"; -                case PRIORITY_USER_SETTING_REFRESH_RATE: -                    return "PRIORITY_USER_SETTING_REFRESH_RATE"; +                case PRIORITY_USER_SETTING_PEAK_REFRESH_RATE: +                    return "PRIORITY_USER_SETTING_PEAK_REFRESH_RATE";                  case PRIORITY_LOW_POWER_MODE:                      return "PRIORITY_LOW_POWER_MODE";                  default: @@ -608,12 +638,11 @@ public class DisplayModeDirector {              float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),                      Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate); -            if (peakRefreshRate < minRefreshRate) { -                peakRefreshRate = minRefreshRate; -            } +            updateVoteLocked(Vote.PRIORITY_USER_SETTING_PEAK_REFRESH_RATE, +                    Vote.forRefreshRates(0f, Math.max(minRefreshRate, peakRefreshRate))); +            updateVoteLocked(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE, +                    Vote.forRefreshRates(minRefreshRate, Float.POSITIVE_INFINITY)); -            Vote vote = Vote.forRefreshRates(minRefreshRate, peakRefreshRate); -            updateVoteLocked(Vote.PRIORITY_USER_SETTING_REFRESH_RATE, vote);              mBrightnessObserver.onRefreshRateSettingChangedLocked(minRefreshRate, peakRefreshRate);          } @@ -655,6 +684,7 @@ public class DisplayModeDirector {                  refreshRateVote = null;                  sizeVote = null;              } +              updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, refreshRateVote);              updateVoteLocked(displayId, Vote.PRIORITY_APP_REQUEST_SIZE, sizeVote);              return; @@ -799,6 +829,8 @@ public class DisplayModeDirector {          private boolean mRefreshRateChangeable = false;          private boolean mLowPowerModeEnabled = false; +        private int mRefreshRateInZone; +          BrightnessObserver(Context context, Handler handler) {              super(handler);              mContext = context; @@ -815,6 +847,7 @@ public class DisplayModeDirector {          public void observe(SensorManager sensorManager) {              mSensorManager = sensorManager; +              // DeviceConfig is accessible after system ready.              int[] brightnessThresholds = mDeviceConfigDisplaySettings.getBrightnessThresholds();              int[] ambientThresholds = mDeviceConfigDisplaySettings.getAmbientThresholds(); @@ -824,6 +857,8 @@ public class DisplayModeDirector {                  mDisplayBrightnessThresholds = brightnessThresholds;                  mAmbientBrightnessThresholds = ambientThresholds;              } + +            mRefreshRateInZone = mDeviceConfigDisplaySettings.getRefreshRateInZone();              restartObserver();              mDeviceConfigDisplaySettings.startListening();          } @@ -863,8 +898,16 @@ public class DisplayModeDirector {              restartObserver();          } +        public void onDeviceConfigRefreshRateInZoneChanged(int refreshRate) { +            if (refreshRate != mRefreshRateInZone) { +                mRefreshRateInZone = refreshRate; +                restartObserver(); +            } +        } +          public void dumpLocked(PrintWriter pw) {              pw.println("  BrightnessObserver"); +            pw.println("    mRefreshRateInZone: " + mRefreshRateInZone);              for (int d: mDisplayBrightnessThresholds) {                  pw.println("    mDisplayBrightnessThreshold: " + d); @@ -950,6 +993,10 @@ public class DisplayModeDirector {           * to value changes.           */          private boolean checkShouldObserve(int[] a) { +            if (mRefreshRateInZone <= 0) { +                return false; +            } +              for (int d: a) {                  if (d >= 0) {                      return true; @@ -959,37 +1006,42 @@ public class DisplayModeDirector {              return false;          } -        private void onBrightnessChangedLocked() { -            int brightness = Settings.System.getInt(mContext.getContentResolver(), -                    Settings.System.SCREEN_BRIGHTNESS, -1); - -            Vote vote = null; +        private boolean isInsideZone(int brightness, float lux) {              for (int i = 0; i < mDisplayBrightnessThresholds.length; i++) {                  int disp = mDisplayBrightnessThresholds[i];                  int ambi = mAmbientBrightnessThresholds[i];                  if (disp >= 0 && ambi >= 0) {                      if (brightness <= disp && mAmbientLux <= ambi) { -                        vote = Vote.forRefreshRates(0f, 60f); +                        return true;                      }                  } else if (disp >= 0) {                      if (brightness <= disp) { -                        vote = Vote.forRefreshRates(0f, 60f); +                        return true;                      }                  } else if (ambi >= 0) {                      if (mAmbientLux <= ambi) { -                        vote = Vote.forRefreshRates(0f, 60f); +                        return true;                      }                  } +            } -                if (vote != null) { -                    break; -                } +            return false; +        } + +        private void onBrightnessChangedLocked() { +            int brightness = Settings.System.getInt(mContext.getContentResolver(), +                    Settings.System.SCREEN_BRIGHTNESS, -1); + +            Vote vote = null; +            boolean insideZone = isInsideZone(brightness, mAmbientLux); +            if (insideZone) { +                vote = Vote.forRefreshRates(mRefreshRateInZone, mRefreshRateInZone);              }              if (DEBUG) {                  Slog.d(TAG, "Display brightness " + brightness + ", ambient lux " +  mAmbientLux + -                        (vote != null ? " 60hz only" : " no refresh rate limit")); +                        ", Vote " + vote);              }              updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, vote);          } @@ -1104,7 +1156,6 @@ public class DisplayModeDirector {      }      private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener { -          public DeviceConfigDisplaySettings() {          } @@ -1118,7 +1169,8 @@ public class DisplayModeDirector {           */          public int[] getBrightnessThresholds() {              return getIntArrayProperty( -                    DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_BRIGHTNESS_THRESHOLDS); +                    DisplayManager.DeviceConfig. +                            KEY_PEAK_REFRESH_RATE_DISPLAY_BRIGHTNESS_THRESHOLDS);          }          /* @@ -1126,7 +1178,8 @@ public class DisplayModeDirector {           */          public int[] getAmbientThresholds() {              return getIntArrayProperty( -                    DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_AMBIENT_THRESHOLDS); +                    DisplayManager.DeviceConfig. +                            KEY_PEAK_REFRESH_RATE_AMBIENT_BRIGHTNESS_THRESHOLDS);          }          /* @@ -1143,17 +1196,32 @@ public class DisplayModeDirector {              return defaultPeakRefreshRate;          } +        public int getRefreshRateInZone() { +            int defaultRefreshRateInZone = mContext.getResources().getInteger( +                    R.integer.config_defaultRefreshRateInZone); + +            int refreshRate = DeviceConfig.getInt( +                    DeviceConfig.NAMESPACE_DISPLAY_MANAGER, +                    DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_ZONE, +                    defaultRefreshRateInZone); + +            return refreshRate; +        } +          @Override          public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {              int[] brightnessThresholds = getBrightnessThresholds();              int[] ambientThresholds = getAmbientThresholds();              Float defaultPeakRefreshRate = getDefaultPeakRefreshRate(); +            int refreshRateInZone = getRefreshRateInZone();              mHandler.obtainMessage(MSG_BRIGHTNESS_THRESHOLDS_CHANGED,                      new Pair<int[], int[]>(brightnessThresholds, ambientThresholds))                      .sendToTarget();              mHandler.obtainMessage(MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED,                      defaultPeakRefreshRate).sendToTarget(); +            mHandler.obtainMessage(MSG_REFRESH_RATE_IN_ZONE_CHANGED, refreshRateInZone, +                    0).sendToTarget();          }          private int[] getIntArrayProperty(String prop) { |