diff options
| author | 2019-10-15 00:24:25 +0000 | |
|---|---|---|
| committer | 2019-10-15 00:24:25 +0000 | |
| commit | ee4eb8c39d38b3ed704e534b5a1d9dabe361e80b (patch) | |
| tree | 7bf220d6a13791a89ff2b79a07b928846136e24d | |
| parent | 8e0b67272db3ee5c691287f4ec7a40313c15b98f (diff) | |
| parent | 5c4d37fc1713e483801ead4d21f1ca107beab374 (diff) | |
Merge "DO NOT MERGE - Merge QD1A.190821.011 into stage-aosp-master" into stage-aosp-master
14 files changed, 373 insertions, 97 deletions
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 8a0a9c7c9d9d..5d8fa92263c4 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -820,4 +820,51 @@ public final class DisplayManager { */ void onDisplayChanged(int displayId); } + + /** + * Interface for accessing keys belonging to {@link + * android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER}. + * @hide + */ + public interface DeviceConfig { + + /** + * Key for accessing the 60 hz only regions. + * + * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER + * @see android.R.array#config_brightnessThresholdsOfPeakRefreshRate + * @hide + */ + String KEY_PEAK_REFRESH_RATE_BRIGHTNESS_THRESHOLDS = + "peak_refresh_rate_brightness_thresholds"; + + /** + * Key for accessing the 60 hz only regions. + * + * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER + * @see android.R.array#config_brightnessThresholdsOfPeakRefreshRate + * @hide + */ + String KEY_PEAK_REFRESH_RATE_AMBIENT_THRESHOLDS = "peak_refresh_rate_ambient_thresholds"; + + /** + * Key for default peak refresh rate + * + * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER + * @see android.R.integer#config_defaultPeakRefreshRate + * @hide + */ + String KEY_PEAK_REFRESH_RATE_DEFAULT = "peak_refresh_rate_default"; + + /** + * Key for controlling which packages are explicitly blocked from running at refresh rates + * higher than 60hz. An app may be added to this list if they exhibit performance issues at + * higher refresh rates. + * + * @see android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER + * @see android.R.array#config_highRefreshRateBlacklist + * @hide + */ + String KEY_HIGH_REFRESH_RATE_BLACKLIST = "high_refresh_rate_blacklist"; + } } diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index ea50ae810535..c837b9346173 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -136,6 +136,14 @@ public final class DeviceConfig { public static final String NAMESPACE_DEX_BOOT = "dex_boot"; /** + * Namespace for display manager related features. The names to access the properties in this + * namespace should be defined in {@link android.hardware.display.DisplayManager}. + * + * @hide + */ + public static final String NAMESPACE_DISPLAY_MANAGER = "display_manager"; + + /** * Namespace for all Game Driver features. * * @hide @@ -350,15 +358,6 @@ public final class DeviceConfig { */ String KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS = "system_gesture_exclusion_log_debounce_millis"; - - /** - * Key for controlling which packages are explicitly blocked from running at refresh rates - * higher than 60hz. - * - * @see android.provider.DeviceConfig#NAMESPACE_WINDOW_MANAGER - * @hide - */ - String KEY_HIGH_REFRESH_RATE_BLACKLIST = "high_refresh_rate_blacklist"; } private static final Object sLock = new Object(); diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index c8f2d760f974..2263f52dd361 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3477,6 +3477,14 @@ public final class Settings { }; /** + * The user selected min refresh rate in frames per second. + * + * If this isn't set, 0 will be used. + * @hide + */ + public static final String MIN_REFRESH_RATE = "min_refresh_rate"; + + /** * The user selected peak refresh rate in frames per second. * * If this isn't set, the system falls back to a device specific default. diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index aee178a9a01e..00607419b6d8 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -93,6 +93,7 @@ public class SettingsBackupTest { Settings.System.VOLUME_VOICE, // deprecated since API 2? Settings.System.WHEN_TO_MAKE_WIFI_CALLS, // bug? Settings.System.WINDOW_ORIENTATION_LISTENER_LOG, // used for debugging only + Settings.System.MIN_REFRESH_RATE, // depends on hardware capabilities Settings.System.PEAK_REFRESH_RATE // depends on hardware capabilities ); diff --git a/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml b/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml index fe1bb265880c..7c7c8c1e4729 100644 --- a/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml +++ b/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml @@ -16,16 +16,10 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" android:viewportWidth="22" android:viewportHeight="17" - android:width="22dp" - android:height="17dp"> + android:width="19.41dp" + android:height="15dp"> <path android:fillColor="#FFFFFFFF" - android:pathData="M1.22,8.49l0.43-4.96h4.33v1.17H2.67L2.44,7.41c0.41-0.29,0.85-0.43,1.33-0.43c0.77,0,1.38,0.3,1.83,0.9 s0.66,1.41,0.66,2.43c0,1.03-0.24,1.84-0.72,2.43s-1.14,0.88-1.98,0.88c-0.75,0-1.36-0.24-1.83-0.73s-0.74-1.16-0.81-2.02h1.13 c0.07,0.57,0.23,1,0.49,1.29c0.26,0.29,0.59,0.43,1.01,0.43c0.47,0,0.84-0.2,1.1-0.61c0.26-0.41,0.4-0.96,0.4-1.65 c0-0.65-0.14-1.18-0.43-1.59S3.96,8.11,3.47,8.11c-0.4,0-0.72,0.1-0.96,0.31L2.19,8.75L1.22,8.49z" /> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M14.14,12.24l-0.22,0.27c-0.63,0.73-1.55,1.1-2.76,1.1c-1.08,0-1.92-0.36-2.53-1.07c-0.61-0.71-0.93-1.72-0.94-3.02V7.56 c0-1.39,0.28-2.44,0.84-3.13c0.56-0.7,1.39-1.04,2.51-1.04c0.95,0,1.69,0.26,2.23,0.79c0.54,0.53,0.83,1.28,0.89,2.26h-1.25 c-0.05-0.62-0.22-1.1-0.52-1.45c-0.29-0.35-0.74-0.52-1.34-0.52c-0.72,0-1.24,0.23-1.57,0.7C9.14,5.63,8.96,6.37,8.95,7.4v2.03 c0,1,0.19,1.77,0.57,2.31c0.38,0.54,0.93,0.8,1.65,0.8c0.67,0,1.19-0.16,1.54-0.49l0.18-0.17V9.59h-1.82V8.52h3.07V12.24z" /> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M20.96,8.88h-3.52v3.53h4.1v1.07h-5.35V3.52h5.28V4.6h-4.03V7.8h3.52V8.88z" /> - + android:pathData="M 6.72 3.52 L 6.54 4.69 L 3.34 4.69 L 2.63 7.41 C 3.011 7.143 3.465 7 3.93 7 C 4.5 6.986 5.041 7.251 5.38 7.71 C 5.756 8.249 5.952 8.893 5.94 9.55 C 5.98 10.276 5.864 11.002 5.6 11.68 C 5.385 12.267 5.007 12.78 4.51 13.16 C 4.043 13.499 3.476 13.671 2.9 13.65 C 2.271 13.653 1.675 13.369 1.28 12.88 C 0.854 12.302 0.636 11.597 0.66 10.88 L 1.76 10.88 C 1.81 12 2.21 12.57 3 12.58 C 3.592 12.589 4.132 12.243 4.37 11.7 C 4.708 11.044 4.85 10.305 4.78 9.57 C 4.767 9.209 4.645 8.86 4.43 8.57 C 4.239 8.309 3.934 8.156 3.61 8.16 C 3.404 8.138 3.196 8.162 3 8.23 C 2.748 8.358 2.518 8.527 2.32 8.73 L 1.31 8.46 L 2.51 3.52 L 6.72 3.52 Z M 11.7 3.39 C 12.459 3.353 13.195 3.662 13.7 4.23 C 14.185 4.864 14.42 5.654 14.36 6.45 L 13.1 6.45 C 13.131 5.938 12.998 5.43 12.72 5 C 12.455 4.679 12.056 4.498 11.64 4.51 C 11.025 4.456 10.42 4.688 10 5.14 C 9.491 5.811 9.179 6.611 9.1 7.45 L 8.75 9.54 L 8.75 10.57 C 8.82 11.86 9.36 12.52 10.36 12.57 C 10.701 12.593 11.043 12.538 11.36 12.41 C 11.661 12.281 11.943 12.113 12.2 11.91 L 12.62 9.62 L 10.77 9.62 L 11 8.52 L 14 8.52 L 13.36 12.23 C 13.176 12.483 12.953 12.706 12.7 12.89 C 11.995 13.398 11.138 13.652 10.27 13.61 C 9.507 13.634 8.773 13.315 8.27 12.74 C 7.748 12.085 7.475 11.267 7.5 10.43 C 7.47 10.097 7.47 9.763 7.5 9.43 L 7.8 7.43 C 7.927 6.332 8.36 5.293 9.05 4.43 C 9.725 3.692 10.703 3.308 11.7 3.39 Z M 20.81 7.21 L 20.62 8.29 L 18.32 8.29 L 18.06 9.8 L 20.06 9.8 L 19.83 10.84 L 17.88 10.84 L 17.59 12.54 L 19.9 12.54 L 19.71 13.61 L 16.14 13.61 L 17.25 7.21 L 20.81 7.21 Z" /> + <path android:pathData="M 0 0 H 14 V 17 H 0 V 0 Z"/> </vector> diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index 264a1020ddc9..0d85a3f77270 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -134,11 +134,13 @@ public class SystemUIFactory { public KeyguardBouncer createKeyguardBouncer(Context context, ViewMediatorCallback callback, LockPatternUtils lockPatternUtils, ViewGroup container, DismissCallbackRegistry dismissCallbackRegistry, - KeyguardBouncer.BouncerExpansionCallback expansionCallback) { + KeyguardBouncer.BouncerExpansionCallback expansionCallback, + KeyguardBypassController bypassController) { return new KeyguardBouncer(context, callback, lockPatternUtils, container, dismissCallbackRegistry, FalsingManagerFactory.getInstance(context), expansionCallback, UnlockMethodCache.getInstance(context), - KeyguardUpdateMonitor.getInstance(context), new Handler(Looper.getMainLooper())); + KeyguardUpdateMonitor.getInstance(context), bypassController, + new Handler(Looper.getMainLooper())); } public ScrimController createScrimController(ScrimView scrimBehind, ScrimView scrimInFront, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index c4d346ccaefb..dc9b373de688 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -77,6 +77,7 @@ public class KeyguardBouncer { } }; private final Runnable mRemoveViewRunnable = this::removeView; + private final KeyguardBypassController mKeyguardBypassController; protected KeyguardHostView mKeyguardView; private final Runnable mResetRunnable = ()-> { if (mKeyguardView != null) { @@ -97,7 +98,8 @@ public class KeyguardBouncer { LockPatternUtils lockPatternUtils, ViewGroup container, DismissCallbackRegistry dismissCallbackRegistry, FalsingManager falsingManager, BouncerExpansionCallback expansionCallback, UnlockMethodCache unlockMethodCache, - KeyguardUpdateMonitor keyguardUpdateMonitor, Handler handler) { + KeyguardUpdateMonitor keyguardUpdateMonitor, + KeyguardBypassController keyguardBypassController, Handler handler) { mContext = context; mCallback = callback; mLockPatternUtils = lockPatternUtils; @@ -109,6 +111,7 @@ public class KeyguardBouncer { mHandler = handler; mUnlockMethodCache = unlockMethodCache; mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback); + mKeyguardBypassController = keyguardBypassController; } public void show(boolean resetSecuritySelection) { @@ -171,7 +174,8 @@ public class KeyguardBouncer { // Split up the work over multiple frames. DejankUtils.removeCallbacks(mResetRunnable); if (mUnlockMethodCache.isFaceAuthEnabled() && !needsFullscreenBouncer() - && !mKeyguardUpdateMonitor.userNeedsStrongAuth()) { + && !mKeyguardUpdateMonitor.userNeedsStrongAuth() + && !mKeyguardBypassController.getBypassEnabled()) { mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY); } else { DejankUtils.postAfterTraversal(mShowRunnable); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 4d85a422d9b9..7e86651ffef6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -220,7 +220,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mBiometricUnlockController = biometricUnlockController; mBouncer = SystemUIFactory.getInstance().createKeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils, container, dismissCallbackRegistry, - mExpansionCallback); + mExpansionCallback, bypassController); mNotificationPanelView = notificationPanelView; notificationPanelView.addExpansionListener(this); mBypassController = bypassController; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java index 907e695f2513..cd60e47eef50 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java @@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; @@ -84,6 +85,8 @@ public class KeyguardBouncerTest extends SysuiTestCase { @Mock private UnlockMethodCache mUnlockMethodCache; @Mock + private KeyguardBypassController mKeyguardBypassController; + @Mock private Handler mHandler; private KeyguardBouncer mBouncer; @@ -98,7 +101,8 @@ public class KeyguardBouncerTest extends SysuiTestCase { when(mKeyguardHostView.getHeight()).thenReturn(500); mBouncer = new KeyguardBouncer(getContext(), mViewMediatorCallback, mLockPatternUtils, container, mDismissCallbackRegistry, mFalsingManager, - mExpansionCallback, mUnlockMethodCache, mKeyguardUpdateMonitor, mHandler) { + mExpansionCallback, mUnlockMethodCache, mKeyguardUpdateMonitor, + mKeyguardBypassController, mHandler) { @Override protected void inflateView() { super.inflateView(); @@ -391,6 +395,15 @@ public class KeyguardBouncerTest extends SysuiTestCase { } @Test + public void testShow_delaysIfFaceAuthIsRunning_unlessBypass() { + when(mUnlockMethodCache.isFaceAuthEnabled()).thenReturn(true); + when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true); + mBouncer.show(true /* reset */); + + verify(mHandler, never()).postDelayed(any(), anyLong()); + } + + @Test public void testRegisterUpdateMonitorCallback() { verify(mKeyguardUpdateMonitor).registerCallback(any()); } diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index 07482796b027..9936d73fb800 100644 --- a/services/core/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java @@ -1188,6 +1188,7 @@ public class VibratorService extends IVibratorService.Stub private static boolean isNotification(int usageHint) { switch (usageHint) { case AudioAttributes.USAGE_NOTIFICATION: + case AudioAttributes.USAGE_NOTIFICATION_EVENT: case AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST: case AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT: case AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED: diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java index a7065216f6a3..ee49f5885e4a 100644 --- a/services/core/java/com/android/server/biometrics/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/face/FaceService.java @@ -223,7 +223,8 @@ public class FaceService extends BiometricServiceBase { @Override public boolean wasUserDetected() { - return mLastAcquire != FaceManager.FACE_ACQUIRED_NOT_DETECTED; + return mLastAcquire != FaceManager.FACE_ACQUIRED_NOT_DETECTED + && mLastAcquire != FaceManager.FACE_ACQUIRED_SENSOR_DIRTY; } @Override diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index c45a314e39cc..97fd02f53513 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -38,13 +38,16 @@ import android.os.Message; import android.os.UserHandle; import android.os.PowerManager; import android.os.SystemClock; +import android.provider.DeviceConfig; import android.provider.Settings; import android.text.TextUtils; +import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.DisplayInfo; +import com.android.internal.os.BackgroundThread; import com.android.internal.R; import com.android.server.display.whitebalance.DisplayWhiteBalanceFactory; import com.android.server.display.whitebalance.AmbientFilter; @@ -64,6 +67,8 @@ public class DisplayModeDirector { private static final boolean DEBUG = false; 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; // Special ID used to indicate that given vote is to be applied globally, rather than to a // specific display. @@ -91,6 +96,7 @@ public class DisplayModeDirector { private final DisplayObserver mDisplayObserver; private final BrightnessObserver mBrightnessObserver; + private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings; private Listener mListener; public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler) { @@ -103,7 +109,7 @@ public class DisplayModeDirector { mSettingsObserver = new SettingsObserver(context, handler); mDisplayObserver = new DisplayObserver(context, handler); mBrightnessObserver = new BrightnessObserver(context, handler); - + mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings(); } /** @@ -405,7 +411,7 @@ public class DisplayModeDirector { void onAllowedDisplayModesChanged(); } - private static final class DisplayModeDirectorHandler extends Handler { + private final class DisplayModeDirectorHandler extends Handler { DisplayModeDirectorHandler(Looper looper) { super(looper, null, true /*async*/); } @@ -417,6 +423,23 @@ public class DisplayModeDirector { Listener listener = (Listener) msg.obj; listener.onAllowedDisplayModesChanged(); break; + + case MSG_BRIGHTNESS_THRESHOLDS_CHANGED: + Pair<int[], int[]> thresholds = (Pair<int[], int[]>) msg.obj; + + if (thresholds != null) { + mBrightnessObserver.onDeviceConfigThresholdsChanged( + thresholds.first, thresholds.second); + } else { + mBrightnessObserver.onDeviceConfigThresholdsChanged(null, null); + } + break; + + case MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED: + Float defaultPeakRefreshRate = (Float) msg.obj; + mSettingsObserver.onDeviceConfigDefaultPeakRefreshRateChanged( + defaultPeakRefreshRate); + break; } } } @@ -502,13 +525,15 @@ public class DisplayModeDirector { } private final class SettingsObserver extends ContentObserver { - private final Uri mRefreshRateSetting = + private final Uri mPeakRefreshRateSetting = Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE); + private final Uri mMinRefreshRateSetting = + Settings.System.getUriFor(Settings.System.MIN_REFRESH_RATE); private final Uri mLowPowerModeSetting = Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE); private final Context mContext; - private final float mDefaultPeakRefreshRate; + private float mDefaultPeakRefreshRate; SettingsObserver(@NonNull Context context, @NonNull Handler handler) { super(handler); @@ -519,20 +544,44 @@ public class DisplayModeDirector { public void observe() { final ContentResolver cr = mContext.getContentResolver(); - cr.registerContentObserver(mRefreshRateSetting, false /*notifyDescendants*/, this, + cr.registerContentObserver(mPeakRefreshRateSetting, false /*notifyDescendants*/, this, + UserHandle.USER_SYSTEM); + cr.registerContentObserver(mMinRefreshRateSetting, false /*notifyDescendants*/, this, UserHandle.USER_SYSTEM); cr.registerContentObserver(mLowPowerModeSetting, false /*notifyDescendants*/, this, UserHandle.USER_SYSTEM); + + Float deviceConfigDefaultPeakRefresh = + mDeviceConfigDisplaySettings.getDefaultPeakRefreshRate(); + if (deviceConfigDefaultPeakRefresh != null) { + mDefaultPeakRefreshRate = deviceConfigDefaultPeakRefresh; + } + synchronized (mLock) { updateRefreshRateSettingLocked(); updateLowPowerModeSettingLocked(); } } + public void onDeviceConfigDefaultPeakRefreshRateChanged(Float defaultPeakRefreshRate) { + if (defaultPeakRefreshRate == null) { + defaultPeakRefreshRate = (float) mContext.getResources().getInteger( + R.integer.config_defaultPeakRefreshRate); + } + + if (mDefaultPeakRefreshRate != defaultPeakRefreshRate) { + synchronized (mLock) { + mDefaultPeakRefreshRate = defaultPeakRefreshRate; + updateRefreshRateSettingLocked(); + } + } + } + @Override public void onChange(boolean selfChange, Uri uri, int userId) { synchronized (mLock) { - if (mRefreshRateSetting.equals(uri)) { + if (mPeakRefreshRateSetting.equals(uri) + || mMinRefreshRateSetting.equals(uri)) { updateRefreshRateSettingLocked(); } else if (mLowPowerModeSetting.equals(uri)) { updateLowPowerModeSettingLocked(); @@ -550,15 +599,22 @@ public class DisplayModeDirector { vote = null; } updateVoteLocked(Vote.PRIORITY_LOW_POWER_MODE, vote); - mBrightnessObserver.onLowPowerModeEnabled(inLowPowerMode); + mBrightnessObserver.onLowPowerModeEnabledLocked(inLowPowerMode); } private void updateRefreshRateSettingLocked() { + float minRefreshRate = Settings.System.getFloat(mContext.getContentResolver(), + Settings.System.MIN_REFRESH_RATE, 0f); float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(), Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate); - Vote vote = Vote.forRefreshRates(0f, peakRefreshRate); + + if (peakRefreshRate < minRefreshRate) { + peakRefreshRate = minRefreshRate; + } + + Vote vote = Vote.forRefreshRates(minRefreshRate, peakRefreshRate); updateVoteLocked(Vote.PRIORITY_USER_SETTING_REFRESH_RATE, vote); - mBrightnessObserver.onPeakRefreshRateEnabled(peakRefreshRate > 60f); + mBrightnessObserver.onRefreshRateSettingChangedLocked(minRefreshRate, peakRefreshRate); } public void dumpLocked(PrintWriter pw) { @@ -720,8 +776,8 @@ public class DisplayModeDirector { Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); private final static int LIGHT_SENSOR_RATE_MS = 250; - private final int[] mDisplayBrightnessThresholds; - private final int[] mAmbientBrightnessThresholds; + private int[] mDisplayBrightnessThresholds; + private int[] mAmbientBrightnessThresholds; // valid threshold if any item from the array >= 0 private boolean mShouldObserveDisplayChange; private boolean mShouldObserveAmbientChange; @@ -734,35 +790,114 @@ public class DisplayModeDirector { private AmbientFilter mAmbientFilter; private final Context mContext; - private ScreenStateReceiver mScreenStateReceiver; + private final ScreenStateReceiver mScreenStateReceiver; - // Enable light sensor only when screen is on, peak refresh rate enabled and low power mode - // off. After initialization, these states will be updated from the same handler thread. + // Enable light sensor only when mShouldObserveAmbientChange is true, screen is on, peak + // refresh rate changeable and low power mode off. After initialization, these states will + // be updated from the same handler thread. private boolean mScreenOn = false; - private boolean mPeakRefreshRateEnabled = false; + private boolean mRefreshRateChangeable = false; private boolean mLowPowerModeEnabled = false; BrightnessObserver(Context context, Handler handler) { super(handler); mContext = context; + mScreenStateReceiver = new ScreenStateReceiver(mContext); mDisplayBrightnessThresholds = context.getResources().getIntArray( R.array.config_brightnessThresholdsOfPeakRefreshRate); mAmbientBrightnessThresholds = context.getResources().getIntArray( R.array.config_ambientThresholdsOfPeakRefreshRate); + if (mDisplayBrightnessThresholds.length != mAmbientBrightnessThresholds.length) { throw new RuntimeException("display brightness threshold array and ambient " + "brightness threshold array have different length"); } + } + + public void observe(SensorManager sensorManager) { + mSensorManager = sensorManager; + // DeviceConfig is accessible after system ready. + int[] brightnessThresholds = mDeviceConfigDisplaySettings.getBrightnessThresholds(); + int[] ambientThresholds = mDeviceConfigDisplaySettings.getAmbientThresholds(); + + if (brightnessThresholds != null && ambientThresholds != null + && brightnessThresholds.length == ambientThresholds.length) { + mDisplayBrightnessThresholds = brightnessThresholds; + mAmbientBrightnessThresholds = ambientThresholds; + } + restartObserver(); + mDeviceConfigDisplaySettings.startListening(); + } + + public void onRefreshRateSettingChangedLocked(float min, float max) { + boolean changeable = (max - min > 1f && max > 60f); + if (mRefreshRateChangeable != changeable) { + mRefreshRateChangeable = changeable; + updateSensorStatus(); + if (!changeable) { + // Revoke previous vote from BrightnessObserver + updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, null); + } + } + } + + public void onLowPowerModeEnabledLocked(boolean b) { + if (mLowPowerModeEnabled != b) { + mLowPowerModeEnabled = b; + updateSensorStatus(); + } + } + + public void onDeviceConfigThresholdsChanged(int[] brightnessThresholds, + int[] ambientThresholds) { + if (brightnessThresholds != null && ambientThresholds != null + && brightnessThresholds.length == ambientThresholds.length) { + mDisplayBrightnessThresholds = brightnessThresholds; + mAmbientBrightnessThresholds = ambientThresholds; + } else { + // Invalid or empty. Use device default. + mDisplayBrightnessThresholds = mContext.getResources().getIntArray( + R.array.config_brightnessThresholdsOfPeakRefreshRate); + mAmbientBrightnessThresholds = mContext.getResources().getIntArray( + R.array.config_ambientThresholdsOfPeakRefreshRate); + } + restartObserver(); + } + + public void dumpLocked(PrintWriter pw) { + pw.println(" BrightnessObserver"); + + for (int d: mDisplayBrightnessThresholds) { + pw.println(" mDisplayBrightnessThreshold: " + d); + } + + for (int d: mAmbientBrightnessThresholds) { + pw.println(" mAmbientBrightnessThreshold: " + d); + } + } + @Override + public void onChange(boolean selfChange, Uri uri, int userId) { + synchronized (mLock) { + if (mRefreshRateChangeable) { + onBrightnessChangedLocked(); + } + } + } + + private void restartObserver() { mShouldObserveDisplayChange = checkShouldObserve(mDisplayBrightnessThresholds); mShouldObserveAmbientChange = checkShouldObserve(mAmbientBrightnessThresholds); - } - public void observe(SensorManager sensorManager) { + final ContentResolver cr = mContext.getContentResolver(); if (mShouldObserveDisplayChange) { - final ContentResolver cr = mContext.getContentResolver(); + // Content Service does not check if an listener has already been registered. + // To ensure only one listener is registered, force an unregistration first. + cr.unregisterContentObserver(this); cr.registerContentObserver(mDisplayBrightnessSetting, false /*notifyDescendants*/, this, UserHandle.USER_SYSTEM); + } else { + cr.unregisterContentObserver(this); } if (mShouldObserveAmbientChange) { @@ -772,7 +907,7 @@ public class DisplayModeDirector { Sensor lightSensor = null; if (!TextUtils.isEmpty(lightSensorType)) { - List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL); + List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL); for (int i = 0; i < sensors.size(); i++) { Sensor sensor = sensors.get(i); if (lightSensorType.equals(sensor.getStringType())) { @@ -783,64 +918,35 @@ public class DisplayModeDirector { } if (lightSensor == null) { - lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); + lightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); } if (lightSensor != null) { final Resources res = mContext.getResources(); mAmbientFilter = DisplayWhiteBalanceFactory.createBrightnessFilter(res); - mSensorManager = sensorManager; mLightSensor = lightSensor; // Intent.ACTION_SCREEN_ON is not sticky. Check current screen status. if (mContext.getSystemService(PowerManager.class).isInteractive()) { onScreenOn(true); } - mScreenStateReceiver = new ScreenStateReceiver(mContext); + mScreenStateReceiver.register(); } + } else { + mAmbientFilter = null; + mLightSensor = null; + mScreenStateReceiver.unregister(); } - if (mShouldObserveDisplayChange || mShouldObserveAmbientChange) { + if (mRefreshRateChangeable) { + updateSensorStatus(); synchronized (mLock) { onBrightnessChangedLocked(); } } } - public void onPeakRefreshRateEnabled(boolean b) { - if (mShouldObserveAmbientChange && mPeakRefreshRateEnabled != b) { - mPeakRefreshRateEnabled = b; - updateSensorStatus(); - } - } - - public void onLowPowerModeEnabled(boolean b) { - if (mShouldObserveAmbientChange && mLowPowerModeEnabled != b) { - mLowPowerModeEnabled = b; - updateSensorStatus(); - } - } - - public void dumpLocked(PrintWriter pw) { - pw.println(" BrightnessObserver"); - - for (int d: mDisplayBrightnessThresholds) { - pw.println(" mDisplayBrightnessThreshold: " + d); - } - - for (int d: mAmbientBrightnessThresholds) { - pw.println(" mAmbientBrightnessThreshold: " + d); - } - } - - @Override - public void onChange(boolean selfChange, Uri uri, int userId) { - synchronized (mLock) { - onBrightnessChangedLocked(); - } - } - /** * Checks to see if at least one value is positive, in which case it is necessary to listen * to value changes. @@ -904,7 +1010,8 @@ public class DisplayModeDirector { return; } - if (mScreenOn && !mLowPowerModeEnabled && mPeakRefreshRateEnabled) { + if (mShouldObserveAmbientChange && mScreenOn && !mLowPowerModeEnabled + && mRefreshRateChangeable) { mSensorManager.registerListener(mLightSensorListener, mLightSensor, LIGHT_SENSOR_RATE_MS * 1000, mHandler); } else { @@ -993,18 +1100,117 @@ public class DisplayModeDirector { }; private final class ScreenStateReceiver extends BroadcastReceiver { + final Context mContext; + boolean mRegistered; + public ScreenStateReceiver(Context context) { - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_SCREEN_OFF); - filter.addAction(Intent.ACTION_SCREEN_ON); - filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); - context.registerReceiver(this, filter, null, mHandler); + mContext = context; } @Override public void onReceive(Context context, Intent intent) { onScreenOn(Intent.ACTION_SCREEN_ON.equals(intent.getAction())); } + + public void register() { + if (!mRegistered) { + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_SCREEN_OFF); + filter.addAction(Intent.ACTION_SCREEN_ON); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + mContext.registerReceiver(this, filter, null, mHandler); + mRegistered = true; + } + } + + public void unregister() { + if (mRegistered) { + mContext.unregisterReceiver(this); + mRegistered = false; + } + } } } + + private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener { + + public DeviceConfigDisplaySettings() { + } + + public void startListening() { + DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, + BackgroundThread.getExecutor(), this); + } + + /* + * Return null if no such property or wrong format (not comma separated integers). + */ + public int[] getBrightnessThresholds() { + return getIntArrayProperty( + DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_BRIGHTNESS_THRESHOLDS); + } + + /* + * Return null if no such property or wrong format (not comma separated integers). + */ + public int[] getAmbientThresholds() { + return getIntArrayProperty( + DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_AMBIENT_THRESHOLDS); + } + + /* + * Return null if no such property + */ + public Float getDefaultPeakRefreshRate() { + float defaultPeakRefreshRate = DeviceConfig.getFloat( + DeviceConfig.NAMESPACE_DISPLAY_MANAGER, + DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_DEFAULT, -1); + + if (defaultPeakRefreshRate == -1) { + return null; + } + return defaultPeakRefreshRate; + } + + @Override + public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { + int[] brightnessThresholds = getBrightnessThresholds(); + int[] ambientThresholds = getAmbientThresholds(); + Float defaultPeakRefreshRate = getDefaultPeakRefreshRate(); + + mHandler.obtainMessage(MSG_BRIGHTNESS_THRESHOLDS_CHANGED, + new Pair<int[], int[]>(brightnessThresholds, ambientThresholds)) + .sendToTarget(); + mHandler.obtainMessage(MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED, + defaultPeakRefreshRate).sendToTarget(); + } + + private int[] getIntArrayProperty(String prop) { + String strArray = DeviceConfig.getString(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, prop, + null); + + if (strArray != null) { + return parseIntArray(strArray); + } + + return null; + } + + private int[] parseIntArray(@NonNull String strArray) { + String[] items = strArray.split(","); + int[] array = new int[items.length]; + + try { + for (int i = 0; i < array.length; i++) { + array[i] = Integer.parseInt(items[i]); + } + } catch (NumberFormatException e) { + Slog.e(TAG, "Incorrect format for array: '" + strArray + "'", e); + array = null; + } + + return array; + } + } + } diff --git a/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java b/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java index 5726cb2d87d4..b33b68a7a5b2 100644 --- a/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java +++ b/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java @@ -16,7 +16,7 @@ package com.android.server.wm; -import static android.provider.DeviceConfig.WindowManager.KEY_HIGH_REFRESH_RATE_BLACKLIST; +import static android.hardware.display.DisplayManager.DeviceConfig.KEY_HIGH_REFRESH_RATE_BLACKLIST; import android.annotation.NonNull; import android.annotation.Nullable; @@ -58,9 +58,9 @@ class HighRefreshRateBlacklist { @VisibleForTesting HighRefreshRateBlacklist(Resources r, DeviceConfigInterface deviceConfig) { mDefaultBlacklist = r.getStringArray(R.array.config_highRefreshRateBlacklist); - deviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER, + deviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, BackgroundThread.getExecutor(), new OnPropertyChangedListener()); - final String property = deviceConfig.getProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER, + final String property = deviceConfig.getProperty(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, KEY_HIGH_REFRESH_RATE_BLACKLIST); updateBlacklist(property); } diff --git a/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java b/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java index e02b69c4b058..cd90462fffe4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java @@ -16,7 +16,7 @@ package com.android.server.wm; -import static android.provider.DeviceConfig.WindowManager.KEY_HIGH_REFRESH_RATE_BLACKLIST; +import static android.hardware.display.DisplayManager.DeviceConfig.KEY_HIGH_REFRESH_RATE_BLACKLIST; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -126,9 +126,9 @@ public class HighRefreshRateBlacklistTest { @Override public String getProperty(String namespace, String name) { - if (!DeviceConfig.NAMESPACE_WINDOW_MANAGER.equals(namespace) + if (!DeviceConfig.NAMESPACE_DISPLAY_MANAGER.equals(namespace) || !KEY_HIGH_REFRESH_RATE_BLACKLIST.equals(name)) { - throw new IllegalArgumentException("Only things in NAMESPACE_WINDOW_MANAGER " + throw new IllegalArgumentException("Only things in NAMESPACE_DISPLAY_MANAGER " + "supported."); } return mBlacklist; @@ -138,8 +138,8 @@ public class HighRefreshRateBlacklistTest { public void addOnPropertyChangedListener(String namespace, Executor executor, DeviceConfig.OnPropertyChangedListener listener) { - if (!DeviceConfig.NAMESPACE_WINDOW_MANAGER.equals(namespace)) { - throw new IllegalArgumentException("Only things in NAMESPACE_WINDOW_MANAGER " + if (!DeviceConfig.NAMESPACE_DISPLAY_MANAGER.equals(namespace)) { + throw new IllegalArgumentException("Only things in NAMESPACE_DISPLAY_MANAGER " + "supported."); } mListeners.add(new Pair<>(listener, executor)); @@ -153,7 +153,7 @@ public class HighRefreshRateBlacklistTest { final Executor executor = listenerInfo.second; final DeviceConfig.OnPropertyChangedListener listener = listenerInfo.first; executor.execute(() -> { - listener.onPropertyChanged(DeviceConfig.NAMESPACE_WINDOW_MANAGER, + listener.onPropertyChanged(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, KEY_HIGH_REFRESH_RATE_BLACKLIST, blacklist); latch.countDown(); }); |