summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2019-10-15 00:24:25 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-10-15 00:24:25 +0000
commitee4eb8c39d38b3ed704e534b5a1d9dabe361e80b (patch)
tree7bf220d6a13791a89ff2b79a07b928846136e24d
parent8e0b67272db3ee5c691287f4ec7a40313c15b98f (diff)
parent5c4d37fc1713e483801ead4d21f1ca107beab374 (diff)
Merge "DO NOT MERGE - Merge QD1A.190821.011 into stage-aosp-master" into stage-aosp-master
-rw-r--r--core/java/android/hardware/display/DisplayManager.java47
-rw-r--r--core/java/android/provider/DeviceConfig.java17
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java1
-rw-r--r--packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml14
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIFactory.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java15
-rw-r--r--services/core/java/com/android/server/VibratorService.java1
-rw-r--r--services/core/java/com/android/server/biometrics/face/FaceService.java3
-rw-r--r--services/core/java/com/android/server/display/DisplayModeDirector.java330
-rw-r--r--services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java12
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();
});