Merge "Ask for user consent before resolving personal intent in work profile" into udc-dev
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 390fe52..12cd523 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -60,6 +60,7 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
@@ -180,6 +181,9 @@
private final ArrayMap<IBinder, IWallpaperEngineWrapper> mActiveEngines = new ArrayMap<>();
+ private Handler mBackgroundHandler;
+ private HandlerThread mBackgroundThread;
+
static final class WallpaperCommand {
String action;
int x;
@@ -198,14 +202,6 @@
*/
public class Engine {
IWallpaperEngineWrapper mIWallpaperEngine;
- final ArraySet<RectF> mLocalColorAreas = new ArraySet<>(4);
- final ArraySet<RectF> mLocalColorsToAdd = new ArraySet<>(4);
-
- // 2D matrix [x][y] to represent a page of a portion of a window
- EngineWindowPage[] mWindowPages = new EngineWindowPage[0];
- Bitmap mLastScreenshot;
- int mLastWindowPage = -1;
- private boolean mResetWindowPages;
// Copies from mIWallpaperEngine.
HandlerCaller mCaller;
@@ -266,11 +262,27 @@
final Object mLock = new Object();
boolean mOffsetMessageEnqueued;
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
float mPendingXOffset;
float mPendingYOffset;
float mPendingXOffsetStep;
float mPendingYOffsetStep;
+
+ /**
+ * local color extraction related fields
+ * to be used by the background thread only (except the atomic boolean)
+ */
+ final ArraySet<RectF> mLocalColorAreas = new ArraySet<>(4);
+ final ArraySet<RectF> mLocalColorsToAdd = new ArraySet<>(4);
+ private long mLastProcessLocalColorsTimestamp;
+ private AtomicBoolean mProcessLocalColorsPending = new AtomicBoolean(false);
+ private int mPixelCopyCount = 0;
+ // 2D matrix [x][y] to represent a page of a portion of a window
+ EngineWindowPage[] mWindowPages = new EngineWindowPage[0];
+ Bitmap mLastScreenshot;
+ private boolean mResetWindowPages;
+
boolean mPendingSync;
MotionEvent mPendingMove;
boolean mIsInAmbientMode;
@@ -279,12 +291,8 @@
private long mLastColorInvalidation;
private final Runnable mNotifyColorsChanged = this::notifyColorsChanged;
- // used to throttle processLocalColors
- private long mLastProcessLocalColorsTimestamp;
- private AtomicBoolean mProcessLocalColorsPending = new AtomicBoolean(false);
private final Supplier<Long> mClockFunction;
private final Handler mHandler;
-
private Display mDisplay;
private Context mDisplayContext;
private int mDisplayState;
@@ -854,7 +862,7 @@
+ "was not established.");
}
mResetWindowPages = true;
- processLocalColors(mPendingXOffset, mPendingXOffsetStep);
+ processLocalColors();
} catch (RemoteException e) {
Log.w(TAG, "Can't notify system because wallpaper connection was lost.", e);
}
@@ -1392,7 +1400,7 @@
resetWindowPages();
mSession.finishDrawing(mWindow, null /* postDrawTransaction */,
Integer.MAX_VALUE);
- processLocalColors(mPendingXOffset, mPendingXOffsetStep);
+ processLocalColors();
}
reposition();
reportEngineShown(shouldWaitForEngineShown());
@@ -1536,7 +1544,7 @@
if (!mDestroyed) {
mVisible = visible;
reportVisibility();
- if (mReportedVisible) processLocalColors(mPendingXOffset, mPendingXOffsetStep);
+ if (mReportedVisible) processLocalColors();
} else {
AnimationHandler.requestAnimatorsEnabled(visible, this);
}
@@ -1620,31 +1628,41 @@
}
// setup local color extraction data
- processLocalColors(xOffset, xOffsetStep);
+ processLocalColors();
}
/**
* Thread-safe util to call {@link #processLocalColorsInternal} with a minimum interval of
* {@link #PROCESS_LOCAL_COLORS_INTERVAL_MS} between two calls.
*/
- private void processLocalColors(float xOffset, float xOffsetStep) {
+ private void processLocalColors() {
if (mProcessLocalColorsPending.compareAndSet(false, true)) {
final long now = mClockFunction.get();
final long timeSinceLastColorProcess = now - mLastProcessLocalColorsTimestamp;
final long timeToWait = Math.max(0,
PROCESS_LOCAL_COLORS_INTERVAL_MS - timeSinceLastColorProcess);
- mHandler.postDelayed(() -> {
+ mBackgroundHandler.postDelayed(() -> {
mLastProcessLocalColorsTimestamp = now + timeToWait;
mProcessLocalColorsPending.set(false);
- processLocalColorsInternal(xOffset, xOffsetStep);
+ processLocalColorsInternal();
}, timeToWait);
}
}
- private void processLocalColorsInternal(float xOffset, float xOffsetStep) {
+ private void processLocalColorsInternal() {
// implemented by the wallpaper
if (supportsLocalColorExtraction()) return;
+ assertBackgroundThread();
+ float xOffset;
+ float xOffsetStep;
+ float wallpaperDimAmount;
+ synchronized (mLock) {
+ xOffset = mPendingXOffset;
+ xOffsetStep = mPendingXOffsetStep;
+ wallpaperDimAmount = mWallpaperDimAmount;
+ }
+
if (DEBUG) {
Log.d(TAG, "processLocalColors " + xOffset + " of step "
+ xOffsetStep);
@@ -1707,7 +1725,7 @@
xPage = mWindowPages.length - 1;
}
current = mWindowPages[xPage];
- updatePage(current, xPage, xPages, finalXOffsetStep);
+ updatePage(current, xPage, xPages, wallpaperDimAmount);
Trace.endSection();
}
@@ -1727,16 +1745,23 @@
}
}
+ /**
+ * Must be called with the surface lock held.
+ * Must not be called if the surface is not valid.
+ * Will unlock the surface when done using it.
+ */
void updatePage(EngineWindowPage currentPage, int pageIndx, int numPages,
- float xOffsetStep) {
+ float wallpaperDimAmount) {
+
+ assertBackgroundThread();
+
// in case the clock is zero, we start with negative time
long current = SystemClock.elapsedRealtime() - DEFAULT_UPDATE_SCREENSHOT_DURATION;
long lapsed = current - currentPage.getLastUpdateTime();
// Always update the page when the last update time is <= 0
// This is important especially when the device first boots
- if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) {
- return;
- }
+ if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) return;
+
Surface surface = mSurfaceHolder.getSurface();
if (!surface.isValid()) return;
boolean widthIsLarger = mSurfaceSize.x > mSurfaceSize.y;
@@ -1752,33 +1777,42 @@
Bitmap screenShot = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
final Bitmap finalScreenShot = screenShot;
- Trace.beginSection("WallpaperService#pixelCopy");
- PixelCopy.request(surface, screenShot, (res) -> {
- Trace.endSection();
- if (DEBUG) Log.d(TAG, "result of pixel copy is " + res);
- if (res != PixelCopy.SUCCESS) {
- Bitmap lastBitmap = currentPage.getBitmap();
- // assign the last bitmap taken for now
- currentPage.setBitmap(mLastScreenshot);
- Bitmap lastScreenshot = mLastScreenshot;
- if (lastScreenshot != null && !lastScreenshot.isRecycled()
- && !Objects.equals(lastBitmap, lastScreenshot)) {
- updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
+ final String pixelCopySectionName = "WallpaperService#pixelCopy";
+ final int pixelCopyCount = mPixelCopyCount++;
+ Trace.beginAsyncSection(pixelCopySectionName, pixelCopyCount);
+ try {
+ PixelCopy.request(surface, screenShot, (res) -> {
+ Trace.endAsyncSection(pixelCopySectionName, pixelCopyCount);
+ if (DEBUG) Log.d(TAG, "result of pixel copy is " + res);
+ if (res != PixelCopy.SUCCESS) {
+ Bitmap lastBitmap = currentPage.getBitmap();
+ // assign the last bitmap taken for now
+ currentPage.setBitmap(mLastScreenshot);
+ Bitmap lastScreenshot = mLastScreenshot;
+ if (lastScreenshot != null && !lastScreenshot.isRecycled()
+ && !Objects.equals(lastBitmap, lastScreenshot)) {
+ updatePageColors(currentPage, pageIndx, numPages, wallpaperDimAmount);
+ }
+ } else {
+ mLastScreenshot = finalScreenShot;
+ // going to hold this lock for a while
+ currentPage.setBitmap(finalScreenShot);
+ currentPage.setLastUpdateTime(current);
+ updatePageColors(currentPage, pageIndx, numPages, wallpaperDimAmount);
}
- } else {
- mLastScreenshot = finalScreenShot;
- // going to hold this lock for a while
- currentPage.setBitmap(finalScreenShot);
- currentPage.setLastUpdateTime(current);
- updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
- }
- }, mHandler);
-
+ }, mBackgroundHandler);
+ } catch (IllegalArgumentException e) {
+ // this can potentially happen if the surface is invalidated right between the
+ // surface.isValid() check and the PixelCopy operation.
+ // in this case, stop: we'll compute colors on the next processLocalColors call.
+ Log.i(TAG, "Cancelling processLocalColors: exception caught during PixelCopy");
+ }
}
// locked by the passed page
- private void updatePageColors(EngineWindowPage page, int pageIndx, int numPages,
- float xOffsetStep) {
+ private void updatePageColors(
+ EngineWindowPage page, int pageIndx, int numPages, float wallpaperDimAmount) {
if (page.getBitmap() == null) return;
+ assertBackgroundThread();
Trace.beginSection("WallpaperService#updatePageColors");
if (DEBUG) {
Log.d(TAG, "updatePageColorsLocked for page " + pageIndx + " with areas "
@@ -1800,7 +1834,7 @@
Log.e(TAG, "Error creating page local color bitmap", e);
continue;
}
- WallpaperColors color = WallpaperColors.fromBitmap(target, mWallpaperDimAmount);
+ WallpaperColors color = WallpaperColors.fromBitmap(target, wallpaperDimAmount);
target.recycle();
WallpaperColors currentColor = page.getColors(area);
@@ -1817,17 +1851,26 @@
+ " local color callback for area" + area + " for page " + pageIndx
+ " of " + numPages);
}
- try {
- mConnection.onLocalWallpaperColorsChanged(area, color,
- mDisplayContext.getDisplayId());
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e);
- }
+ mHandler.post(() -> {
+ try {
+ mConnection.onLocalWallpaperColorsChanged(area, color,
+ mDisplayContext.getDisplayId());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e);
+ }
+ });
}
}
Trace.endSection();
}
+ private void assertBackgroundThread() {
+ if (!mBackgroundHandler.getLooper().isCurrentThread()) {
+ throw new IllegalStateException(
+ "ProcessLocalColors should be called from the background thread");
+ }
+ }
+
private RectF generateSubRect(RectF in, int pageInx, int numPages) {
float minLeft = (float) (pageInx) / (float) (numPages);
float maxRight = (float) (pageInx + 1) / (float) (numPages);
@@ -1852,7 +1895,6 @@
if (supportsLocalColorExtraction()) return;
if (!mResetWindowPages) return;
mResetWindowPages = false;
- mLastWindowPage = -1;
for (int i = 0; i < mWindowPages.length; i++) {
mWindowPages[i].setLastUpdateTime(0L);
}
@@ -1878,12 +1920,10 @@
if (DEBUG) {
Log.d(TAG, "addLocalColorsAreas adding local color areas " + regions);
}
- mHandler.post(() -> {
+ mBackgroundHandler.post(() -> {
mLocalColorsToAdd.addAll(regions);
- processLocalColors(mPendingXOffset, mPendingYOffset);
+ processLocalColors();
});
-
-
}
/**
@@ -1893,7 +1933,7 @@
*/
public void removeLocalColorsAreas(@NonNull List<RectF> regions) {
if (supportsLocalColorExtraction()) return;
- mHandler.post(() -> {
+ mBackgroundHandler.post(() -> {
float step = mPendingXOffsetStep;
mLocalColorsToAdd.removeAll(regions);
mLocalColorAreas.removeAll(regions);
@@ -2554,6 +2594,9 @@
@Override
public void onCreate() {
Trace.beginSection("WPMS.onCreate");
+ mBackgroundThread = new HandlerThread("DefaultWallpaperLocalColorExtractor");
+ mBackgroundThread.start();
+ mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
super.onCreate();
Trace.endSection();
}
@@ -2566,6 +2609,7 @@
engineWrapper.destroy();
}
mActiveEngines.clear();
+ mBackgroundThread.quitSafely();
Trace.endSection();
}
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9640033..7e89fc8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4963,4 +4963,50 @@
<java-symbol type="bool" name="config_batteryStatsResetOnUnplugHighBatteryLevel" />
<java-symbol type="bool" name="config_batteryStatsResetOnUnplugAfterSignificantCharge" />
+
+
+ <java-symbol name="materialColorOnSecondaryFixedVariant" type="attr"/>
+ <java-symbol name="materialColorOnTertiaryFixedVariant" type="attr"/>
+ <java-symbol name="materialColorSurfaceContainerLowest" type="attr"/>
+ <java-symbol name="materialColorOnPrimaryFixedVariant" type="attr"/>
+ <java-symbol name="materialColorOnSecondaryContainer" type="attr"/>
+ <java-symbol name="materialColorOnTertiaryContainer" type="attr"/>
+ <java-symbol name="materialColorSurfaceContainerLow" type="attr"/>
+ <java-symbol name="materialColorOnPrimaryContainer" type="attr"/>
+ <java-symbol name="materialColorSecondaryFixedDim" type="attr"/>
+ <java-symbol name="materialColorOnErrorContainer" type="attr"/>
+ <java-symbol name="materialColorOnSecondaryFixed" type="attr"/>
+ <java-symbol name="materialColorOnSurfaceInverse" type="attr"/>
+ <java-symbol name="materialColorTertiaryFixedDim" type="attr"/>
+ <java-symbol name="materialColorOnTertiaryFixed" type="attr"/>
+ <java-symbol name="materialColorPrimaryFixedDim" type="attr"/>
+ <java-symbol name="materialColorSecondaryContainer" type="attr"/>
+ <java-symbol name="materialColorErrorContainer" type="attr"/>
+ <java-symbol name="materialColorOnPrimaryFixed" type="attr"/>
+ <java-symbol name="materialColorPrimaryInverse" type="attr"/>
+ <java-symbol name="materialColorSecondaryFixed" type="attr"/>
+ <java-symbol name="materialColorSurfaceInverse" type="attr"/>
+ <java-symbol name="materialColorSurfaceVariant" type="attr"/>
+ <java-symbol name="materialColorTertiaryContainer" type="attr"/>
+ <java-symbol name="materialColorTertiaryFixed" type="attr"/>
+ <java-symbol name="materialColorPrimaryContainer" type="attr"/>
+ <java-symbol name="materialColorOnBackground" type="attr"/>
+ <java-symbol name="materialColorPrimaryFixed" type="attr"/>
+ <java-symbol name="materialColorOnSecondary" type="attr"/>
+ <java-symbol name="materialColorOnTertiary" type="attr"/>
+ <java-symbol name="materialColorSurfaceDim" type="attr"/>
+ <java-symbol name="materialColorSurfaceBright" type="attr"/>
+ <java-symbol name="materialColorSecondary" type="attr"/>
+ <java-symbol name="materialColorOnError" type="attr"/>
+ <java-symbol name="materialColorSurface" type="attr"/>
+ <java-symbol name="materialColorSurfaceContainerHigh" type="attr"/>
+ <java-symbol name="materialColorTertiary" type="attr"/>
+ <java-symbol name="materialColorSurfaceContainerHighest" type="attr"/>
+ <java-symbol name="materialColorOnSurfaceVariant" type="attr"/>
+ <java-symbol name="materialColorOutline" type="attr"/>
+ <java-symbol name="materialColorOnPrimary" type="attr"/>
+ <java-symbol name="materialColorOnSurface" type="attr"/>
+ <java-symbol name="materialColorSurfaceContainer" type="attr"/>
+ <java-symbol name="materialColorSurfaceContainer" type="attr"/>
+
</resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 245cc8d..0779f1d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -213,6 +213,12 @@
final View handle = caption.findViewById(R.id.caption_handle);
handle.setOnTouchListener(mOnCaptionTouchListener);
handle.setOnClickListener(mOnCaptionButtonClickListener);
+ if (DesktopModeStatus.isProto1Enabled()) {
+ final View back = caption.findViewById(R.id.back_button);
+ back.setOnClickListener(mOnCaptionButtonClickListener);
+ final View close = caption.findViewById(R.id.close_window);
+ close.setOnClickListener(mOnCaptionButtonClickListener);
+ }
updateButtonVisibility();
}
@@ -319,6 +325,14 @@
final View handle = caption.findViewById(R.id.caption_handle);
final Drawable handleBackground = handle.getBackground();
handleBackground.setTintList(buttonTintColor);
+ if (DesktopModeStatus.isProto1Enabled()) {
+ final View back = caption.findViewById(R.id.back_button);
+ final Drawable backBackground = back.getBackground();
+ backBackground.setTintList(buttonTintColor);
+ final View close = caption.findViewById(R.id.close_window);
+ final Drawable closeBackground = close.getBackground();
+ closeBackground.setTintList(buttonTintColor);
+ }
}
private void closeDragResizeListener() {
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
index 774255b..b98b9221 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
@@ -35,8 +35,7 @@
*
* Note that calls to [View.setTransitionVisibility] shouldn't be blocked.
*
- * @param block whether we should block/postpone all calls to `setVisibility` and
- * `setTransitionVisibility`.
+ * @param block whether we should block/postpone all calls to `setVisibility`.
*/
fun setShouldBlockVisibilityChanges(block: Boolean)
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index addae72..17ce0b9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2781,7 +2781,8 @@
boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
&& shouldListenBouncerState && shouldListenUdfpsState
- && shouldListenSideFpsState;
+ && shouldListenSideFpsState
+ && !isFingerprintLockedOut();
logListenerModelData(
new KeyguardFingerprintListenModel(
System.currentTimeMillis(),
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 9fe7506..fec34c2 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -29,6 +29,7 @@
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
import static com.android.keyguard.FaceAuthApiRequestReason.NOTIFICATION_PANEL_CLICKED;
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
+import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_STATE_CANCELLING;
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_STATE_CANCELLING_RESTARTING;
import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT;
import static com.android.keyguard.KeyguardUpdateMonitor.HAL_POWER_PRESS_TIMEOUT;
@@ -1175,10 +1176,11 @@
assertThat(mKeyguardUpdateMonitor.isFingerprintLockedOut()).isEqualTo(fpLocked);
assertThat(mKeyguardUpdateMonitor.isFaceLockedOut()).isEqualTo(faceLocked);
- // Fingerprint should be restarted once its cancelled bc on lockout, the device
- // can still detectFingerprint (and if it's not locked out, fingerprint can listen)
+ // Fingerprint should be cancelled on lockout if going to lockout state, else
+ // restarted if it's not
assertThat(mKeyguardUpdateMonitor.mFingerprintRunningState)
- .isEqualTo(BIOMETRIC_STATE_CANCELLING_RESTARTING);
+ .isEqualTo(fpLocked
+ ? BIOMETRIC_STATE_CANCELLING : BIOMETRIC_STATE_CANCELLING_RESTARTING);
}
@Test
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index c2c59f2..88c0c7f 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4370,7 +4370,8 @@
}
}
- private void setLeAudioVolumeOnModeUpdate(int mode, int device) {
+ private void setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index,
+ int maxIndex) {
switch (mode) {
case AudioSystem.MODE_IN_COMMUNICATION:
case AudioSystem.MODE_IN_CALL:
@@ -4388,16 +4389,15 @@
// (like the outgoing call) the value of 'device' is not DEVICE_OUT_BLE_*
// even when BLE is connected.
if (!AudioSystem.isLeAudioDeviceType(device)) {
+ Log.w(TAG, "setLeAudioVolumeOnModeUpdate got unexpected device=" + device
+ + ", forcing to device=" + AudioSystem.DEVICE_OUT_BLE_HEADSET);
device = AudioSystem.DEVICE_OUT_BLE_HEADSET;
}
- final int streamType = getBluetoothContextualVolumeStream(mode);
- final int index = mStreamStates[streamType].getIndex(device);
- final int maxIndex = mStreamStates[streamType].getMaxIndex();
-
if (DEBUG_VOL) {
- Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex index="
- + index + " maxIndex=" + maxIndex + " streamType=" + streamType);
+ Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex device="
+ + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
+ + " streamType=" + streamType);
}
mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType);
mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate");
@@ -5865,10 +5865,18 @@
mModeLogger.enqueue(new PhoneStateEvent(requesterPackage, requesterPid,
requestedMode, pid, mode));
- int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
- int device = getDeviceForStream(streamType);
- int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device);
- setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true,
+ final int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
+ final int device = getDeviceForStream(streamType);
+ final int streamAlias = mStreamVolumeAlias[streamType];
+
+ if (DEBUG_MODE) {
+ Log.v(TAG, "onUpdateAudioMode: streamType=" + streamType
+ + ", streamAlias=" + streamAlias);
+ }
+
+ final int index = mStreamStates[streamAlias].getIndex(device);
+ final int maxIndex = mStreamStates[streamAlias].getMaxIndex();
+ setStreamVolumeInt(streamAlias, index, device, true,
requesterPackage, true /*hasModifyAudioSettings*/);
updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage);
@@ -5876,7 +5884,7 @@
// change of mode may require volume to be re-applied on some devices
updateAbsVolumeMultiModeDevices(previousMode, mode);
- setLeAudioVolumeOnModeUpdate(mode, device);
+ setLeAudioVolumeOnModeUpdate(mode, device, streamAlias, index, maxIndex);
// when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO
// connections not started by the application changing the mode when pid changes
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 229393d..1c57151 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -421,6 +421,13 @@
return -1;
}
+ if (!Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) {
+ // If this happens, something in KeyguardUpdateMonitor is wrong. This should only
+ // ever be invoked when the user is encrypted or lockdown.
+ Slog.e(TAG, "detectFingerprint invoked when user is not encrypted or lockdown");
+ return -1;
+ }
+
final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
if (provider == null) {
Slog.w(TAG, "Null provider for detectFingerprint");
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 40c879a..d4877eb 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1193,17 +1193,15 @@
}
loadScreenOffBrightnessSensor();
int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux();
- // TODO (b/265793751): Don't instantiate ScreenOffBrightnessSensorController if this is
- // a complementary display
if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) {
- mScreenOffBrightnessSensorController = new ScreenOffBrightnessSensorController(
- mSensorManager,
- mScreenOffBrightnessSensor,
- mHandler,
- SystemClock::uptimeMillis,
- sensorValueToLux,
- mInteractiveModeBrightnessMapper
- );
+ mScreenOffBrightnessSensorController =
+ mInjector.getScreenOffBrightnessSensorController(
+ mSensorManager,
+ mScreenOffBrightnessSensor,
+ mHandler,
+ SystemClock::uptimeMillis,
+ sensorValueToLux,
+ mInteractiveModeBrightnessMapper);
}
} else {
mUseSoftwareAutoBrightnessConfig = false;
@@ -1395,8 +1393,9 @@
if (mScreenOffBrightnessSensorController != null) {
mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
- && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
- && !mAllowAutoBrightnessWhileDozingConfig)));
+ && mIsEnabled && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
+ && !mAllowAutoBrightnessWhileDozingConfig))
+ && mLeadDisplayId == Layout.NO_LEAD_DISPLAY);
}
boolean skipRampBecauseOfProximityChangeToNegative = false;
@@ -2544,11 +2543,11 @@
mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
- mHandler.post(() -> {
+ mHandler.postAtTime(() -> {
mUseAutoBrightness = screenBrightnessModeSetting
== Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
updatePowerState();
- });
+ }, mClock.uptimeMillis());
}
private float getAutoBrightnessAdjustmentSetting() {
@@ -3446,6 +3445,23 @@
darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold,
potentialOldBrightnessRange);
}
+
+ ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
+ SensorManager sensorManager,
+ Sensor lightSensor,
+ Handler handler,
+ ScreenOffBrightnessSensorController.Clock clock,
+ int[] sensorValueToLux,
+ BrightnessMappingStrategy brightnessMapper) {
+ return new ScreenOffBrightnessSensorController(
+ sensorManager,
+ lightSensor,
+ handler,
+ clock,
+ sensorValueToLux,
+ brightnessMapper
+ );
+ }
}
static class CachedBrightnessInfo {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index 5ea8aaa..a928777 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -1030,17 +1030,15 @@
loadScreenOffBrightnessSensor();
int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux();
- // TODO (b/265793751): Don't instantiate ScreenOffBrightnessSensorController if this is
- // a complementary display
if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) {
- mScreenOffBrightnessSensorController = new ScreenOffBrightnessSensorController(
- mSensorManager,
- mScreenOffBrightnessSensor,
- mHandler,
- SystemClock::uptimeMillis,
- sensorValueToLux,
- mInteractiveModeBrightnessMapper
- );
+ mScreenOffBrightnessSensorController =
+ mInjector.getScreenOffBrightnessSensorController(
+ mSensorManager,
+ mScreenOffBrightnessSensor,
+ mHandler,
+ SystemClock::uptimeMillis,
+ sensorValueToLux,
+ mInteractiveModeBrightnessMapper);
}
} else {
mUseSoftwareAutoBrightnessConfig = false;
@@ -1189,8 +1187,9 @@
if (mScreenOffBrightnessSensorController != null) {
mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
- && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
- && !mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig())));
+ && mIsEnabled && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
+ && !mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig()))
+ && mLeadDisplayId == Layout.NO_LEAD_DISPLAY);
}
// Initialize things the first time the power state is changed.
@@ -2150,11 +2149,11 @@
mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
- mHandler.post(() -> {
+ mHandler.postAtTime(() -> {
mUseAutoBrightness = screenBrightnessModeSetting
== Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
updatePowerState();
- });
+ }, mClock.uptimeMillis());
}
private float getAutoBrightnessAdjustmentSetting() {
@@ -2924,6 +2923,23 @@
darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold,
potentialOldBrightnessRange);
}
+
+ ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
+ SensorManager sensorManager,
+ Sensor lightSensor,
+ Handler handler,
+ ScreenOffBrightnessSensorController.Clock clock,
+ int[] sensorValueToLux,
+ BrightnessMappingStrategy brightnessMapper) {
+ return new ScreenOffBrightnessSensorController(
+ sensorManager,
+ lightSensor,
+ handler,
+ clock,
+ sensorValueToLux,
+ brightnessMapper
+ );
+ }
}
static class CachedBrightnessInfo {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
index 7923bb2..799d1494 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
@@ -29,6 +29,7 @@
import android.annotation.Nullable;
import android.app.WallpaperColors;
+import android.app.WallpaperManager.SetWallpaperFlags;
import android.app.backup.WallpaperBackupHelper;
import android.content.ComponentName;
import android.content.Context;
@@ -124,6 +125,8 @@
}
/**
+ * TODO(b/197814683) adapt comment once flag is removed
+ *
* Load the system wallpaper (and the lock wallpaper, if it exists) from disk
* @param userId the id of the user for which the wallpaper should be loaded
* @param keepDimensionHints if false, parse and set the
@@ -132,17 +135,21 @@
* If null, a new object will be created.
* @param lockWallpaper the lock wallpaper object to reuse to do the modifications.
* If null, a new object will be created.
+ * @param which The wallpaper(s) to load. If {@link #mEnableSeparateLockScreenEngine} is false,
+ * this flag has no effect and both wallpapers will always be loaded.
* @return a {@link WallpaperLoadingResult} object containing the wallpaper data.
* This object will contain the {@code wallpaper} and
* {@code lockWallpaper} provided as parameters, if they are not null.
*/
public WallpaperLoadingResult loadSettingsLocked(int userId, boolean keepDimensionHints,
- WallpaperData wallpaper, WallpaperData lockWallpaper) {
+ WallpaperData wallpaper, WallpaperData lockWallpaper, @SetWallpaperFlags int which) {
JournaledFile journal = makeJournaledFile(userId);
FileInputStream stream = null;
File file = journal.chooseForRead();
boolean migrateFromOld = wallpaper == null;
+ boolean loadSystem = !mEnableSeparateLockScreenEngine || (which & FLAG_SYSTEM) != 0;
+ boolean loadLock = !mEnableSeparateLockScreenEngine || (which & FLAG_LOCK) != 0;
// don't reuse the wallpaper objects in the new version
if (mEnableSeparateLockScreenEngine) {
@@ -150,7 +157,7 @@
lockWallpaper = null;
}
- if (wallpaper == null) {
+ if (wallpaper == null && loadSystem) {
// Do this once per boot
if (migrateFromOld) migrateFromOld();
wallpaper = new WallpaperData(userId, FLAG_SYSTEM);
@@ -176,8 +183,8 @@
type = parser.next();
if (type == XmlPullParser.START_TAG) {
String tag = parser.getName();
- if ("wp".equals(tag)
- || ("kwp".equals(tag) && mEnableSeparateLockScreenEngine)) {
+ if (("wp".equals(tag) && loadSystem)
+ || ("kwp".equals(tag) && mEnableSeparateLockScreenEngine && loadLock)) {
if ("kwp".equals(tag) && lockWallpaper == null) {
lockWallpaper = new WallpaperData(userId, FLAG_LOCK);
@@ -206,9 +213,8 @@
Slog.v(TAG, "mNextWallpaperComponent:"
+ wallpaper.nextWallpaperComponent);
}
- } else if ("kwp".equals(tag)) {
- // keyguard-specific wallpaper for this user
-
+ } else if ("kwp".equals(tag) && !mEnableSeparateLockScreenEngine) {
+ // keyguard-specific wallpaper for this user (legacy code)
if (lockWallpaper == null) {
lockWallpaper = new WallpaperData(userId, FLAG_LOCK);
}
@@ -232,29 +238,32 @@
}
IoUtils.closeQuietly(stream);
- if (!success) {
- wallpaper.cropHint.set(0, 0, 0, 0);
- wpdData.mPadding.set(0, 0, 0, 0);
- wallpaper.name = "";
- lockWallpaper = null;
- } else {
- if (wallpaper.wallpaperId <= 0) {
- wallpaper.wallpaperId = makeWallpaperIdLocked();
- if (DEBUG) {
- Slog.w(TAG, "Didn't set wallpaper id in loadSettingsLocked(" + userId
- + "); now " + wallpaper.wallpaperId);
+ mWallpaperDisplayHelper.ensureSaneWallpaperDisplaySize(wpdData, DEFAULT_DISPLAY);
+
+ if (loadSystem) {
+ if (!success) {
+ wallpaper.cropHint.set(0, 0, 0, 0);
+ wpdData.mPadding.set(0, 0, 0, 0);
+ wallpaper.name = "";
+ } else {
+ if (wallpaper.wallpaperId <= 0) {
+ wallpaper.wallpaperId = makeWallpaperIdLocked();
+ if (DEBUG) {
+ Slog.w(TAG, "Didn't set wallpaper id in loadSettingsLocked(" + userId
+ + "); now " + wallpaper.wallpaperId);
+ }
}
}
+ ensureSaneWallpaperData(wallpaper);
+ wallpaper.mWhich = lockWallpaper != null ? FLAG_SYSTEM : FLAG_SYSTEM | FLAG_LOCK;
}
- mWallpaperDisplayHelper.ensureSaneWallpaperDisplaySize(wpdData, DEFAULT_DISPLAY);
- ensureSaneWallpaperData(wallpaper);
- if (lockWallpaper != null) {
- ensureSaneWallpaperData(lockWallpaper);
- lockWallpaper.mWhich = FLAG_LOCK;
- wallpaper.mWhich = FLAG_SYSTEM;
- } else {
- wallpaper.mWhich = FLAG_SYSTEM | FLAG_LOCK;
+ if (loadLock) {
+ if (!success) lockWallpaper = null;
+ if (lockWallpaper != null) {
+ ensureSaneWallpaperData(lockWallpaper);
+ lockWallpaper.mWhich = FLAG_LOCK;
+ }
}
return new WallpaperLoadingResult(wallpaper, lockWallpaper, success);
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 357d3f5..ac03808 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -297,7 +297,7 @@
if (DEBUG) {
Slog.v(TAG, "Wallpaper restore; reloading metadata");
}
- loadSettingsLocked(wallpaper.userId, true);
+ loadSettingsLocked(wallpaper.userId, true, FLAG_SYSTEM | FLAG_LOCK);
}
if (DEBUG) {
Slog.v(TAG, "Wallpaper written; generating crop");
@@ -440,7 +440,7 @@
if (DEBUG) {
Slog.v(TAG, "moved-to, therefore restore; reloading metadata");
}
- loadSettingsLocked(wallpaper.userId, true);
+ loadSettingsLocked(wallpaper.userId, true, FLAG_SYSTEM | FLAG_LOCK);
}
mWallpaperCropper.generateCrop(wallpaper);
if (DEBUG) {
@@ -1621,7 +1621,7 @@
// Initialize state from the persistent store, then guarantee that the
// WallpaperData for the system imagery is instantiated & active, creating
// it from defaults if necessary.
- loadSettingsLocked(UserHandle.USER_SYSTEM, false);
+ loadSettingsLocked(UserHandle.USER_SYSTEM, false, FLAG_SYSTEM | FLAG_LOCK);
getWallpaperSafeLocked(UserHandle.USER_SYSTEM, FLAG_SYSTEM);
}
@@ -1936,7 +1936,7 @@
wallpaper = mWallpaperMap.get(userId);
if (wallpaper == null) {
// Might need to bring it in the first time to establish our rewrite
- loadSettingsLocked(userId, false);
+ loadSettingsLocked(userId, false, FLAG_SYSTEM);
wallpaper = mWallpaperMap.get(userId);
}
}
@@ -2034,7 +2034,7 @@
WallpaperData wd = mWallpaperMap.get(user.id);
if (wd == null) {
// User hasn't started yet, so load their settings to peek at the wallpaper
- loadSettingsLocked(user.id, false);
+ loadSettingsLocked(user.id, false, FLAG_SYSTEM | FLAG_LOCK);
wd = mWallpaperMap.get(user.id);
}
if (wd != null && name.equals(wd.name)) {
@@ -2910,8 +2910,16 @@
liveSync.complete();
}
};
+
+ /*
+ * If we have a shared system+lock wallpaper, and we reapply the same wallpaper
+ * to system only, force rebind: the current wallpaper will be migrated to lock
+ * and a new engine with the same wallpaper will be applied to system.
+ */
+ boolean forceRebind = same && systemIsBoth && which == FLAG_SYSTEM;
+
boolean bindSuccess = bindWallpaperComponentLocked(name, /* force */
- false, /* fromUser */ true, newWallpaper, callback);
+ forceRebind, /* fromUser */ true, newWallpaper, callback);
if (bindSuccess) {
if (!same) {
newWallpaper.primaryColors = null;
@@ -3434,7 +3442,8 @@
if (wallpaper == null) {
// common case, this is the first lookup post-boot of the system or
// unified lock, so we bring up the saved state lazily now and recheck.
- loadSettingsLocked(userId, false);
+ int whichLoad = (which == FLAG_LOCK) ? FLAG_LOCK : FLAG_SYSTEM;
+ loadSettingsLocked(userId, false, whichLoad);
wallpaper = whichSet.get(userId);
if (wallpaper == null) {
// if it's still null here, this is likely a lock-only operation and there is not
@@ -3455,18 +3464,23 @@
return wallpaper;
}
- private void loadSettingsLocked(int userId, boolean keepDimensionHints) {
+ private void loadSettingsLocked(int userId, boolean keepDimensionHints, int which) {
initializeFallbackWallpaper();
WallpaperData wallpaperData = mWallpaperMap.get(userId);
WallpaperData lockWallpaperData = mLockWallpaperMap.get(userId);
WallpaperDataParser.WallpaperLoadingResult result = mWallpaperDataParser.loadSettingsLocked(
- userId, keepDimensionHints, wallpaperData, lockWallpaperData);
+ userId, keepDimensionHints, wallpaperData, lockWallpaperData, which);
- mWallpaperMap.put(userId, result.getSystemWallpaperData());
- if (result.success()) {
- mLockWallpaperMap.put(userId, result.getLockWallpaperData());
- } else {
- mLockWallpaperMap.remove(userId);
+ boolean updateSystem = !mEnableSeparateLockScreenEngine || (which & FLAG_SYSTEM) != 0;
+ boolean updateLock = !mEnableSeparateLockScreenEngine || (which & FLAG_LOCK) != 0;
+
+ if (updateSystem) mWallpaperMap.put(userId, result.getSystemWallpaperData());
+ if (updateLock) {
+ if (result.success()) {
+ mLockWallpaperMap.put(userId, result.getLockWallpaperData());
+ } else {
+ mLockWallpaperMap.remove(userId);
+ }
}
}
@@ -3493,7 +3507,7 @@
WallpaperData wallpaper = null;
boolean success = false;
synchronized (mLock) {
- loadSettingsLocked(UserHandle.USER_SYSTEM, false);
+ loadSettingsLocked(UserHandle.USER_SYSTEM, false, FLAG_SYSTEM | FLAG_LOCK);
wallpaper = mWallpaperMap.get(UserHandle.USER_SYSTEM);
wallpaper.wallpaperId = makeWallpaperIdLocked(); // always bump id at restore
wallpaper.allowBackup = true; // by definition if it was restored
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 3c3cb2b..852e773 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11324,7 +11324,6 @@
setBackwardsCompatibleAppRestrictions(
packageName, restrictions, caller.getUserHandle());
} else {
- Objects.requireNonNull(who, "ComponentName is null");
Preconditions.checkCallAuthorization((caller.hasAdminComponent()
&& (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
|| (caller.hasPackage() && isCallerDelegate(caller,
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
index b9f2059..96b6345 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -26,12 +26,15 @@
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Resources;
@@ -44,7 +47,9 @@
import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.os.test.TestLooper;
+import android.provider.Settings;
import android.util.FloatProperty;
import android.view.Display;
import android.view.DisplayInfo;
@@ -57,6 +62,7 @@
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
import com.android.server.display.RampAnimator.DualRampAnimator;
+import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.color.ColorDisplayService;
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
import com.android.server.policy.WindowManagerPolicy;
@@ -122,6 +128,7 @@
.spyStatic(SystemProperties.class)
.spyStatic(LocalServices.class)
.spyStatic(BatteryStatsService.class)
+ .spyStatic(Settings.System.class)
.startMocking();
mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
mClock = new OffsettableClock.Stopped();
@@ -139,8 +146,7 @@
ColorDisplayService.ColorDisplayServiceInternal.class));
doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService);
- mProxSensor = setUpProxSensor();
-
+ setUpSensors();
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
}
@@ -169,7 +175,7 @@
advanceTime(1);
// two times, one for unfinished business and one for proximity
- verify(mHolder.wakelockController).acquireWakelock(
+ verify(mHolder.wakelockController, times(2)).acquireWakelock(
WakelockController.WAKE_LOCK_UNFINISHED_BUSINESS);
verify(mHolder.wakelockController).acquireWakelock(
WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE);
@@ -177,7 +183,7 @@
mHolder.dpc.stop();
advanceTime(1);
// two times, one for unfinished business and one for proximity
- verify(mHolder.wakelockController).acquireWakelock(
+ verify(mHolder.wakelockController, times(2)).acquireWakelock(
WakelockController.WAKE_LOCK_UNFINISHED_BUSINESS);
verify(mHolder.wakelockController).acquireWakelock(
WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE);
@@ -214,12 +220,13 @@
mTestLooper.dispatchAll();
}
- private Sensor setUpProxSensor() throws Exception {
- Sensor proxSensor = TestUtils.createSensor(
+ private void setUpSensors() throws Exception {
+ mProxSensor = TestUtils.createSensor(
Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY);
+ Sensor screenOffBrightnessSensor = TestUtils.createSensor(
+ Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
when(mSensorManagerMock.getSensorList(eq(Sensor.TYPE_ALL)))
- .thenReturn(List.of(proxSensor));
- return proxSensor;
+ .thenReturn(List.of(mProxSensor, screenOffBrightnessSensor));
}
private SensorEventListener getSensorEventListener(Sensor sensor) {
@@ -229,14 +236,15 @@
}
private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock,
- DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock) {
+ DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock,
+ boolean isEnabled) {
DisplayInfo info = new DisplayInfo();
DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock);
when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
- when(logicalDisplayMock.isEnabledLocked()).thenReturn(true);
+ when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled);
when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
@@ -253,7 +261,14 @@
when(displayDeviceConfigMock.getAmbientLightSensor()).thenReturn(
new DisplayDeviceConfig.SensorData());
when(displayDeviceConfigMock.getScreenOffBrightnessSensor()).thenReturn(
- new DisplayDeviceConfig.SensorData());
+ new DisplayDeviceConfig.SensorData() {
+ {
+ type = Sensor.STRING_TYPE_LIGHT;
+ name = null;
+ }
+ });
+ when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
+ .thenReturn(new int[0]);
}
@Test
@@ -466,7 +481,7 @@
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1);
- verify(mHolder.displayPowerState).setScreenState(anyInt());
+ verify(mHolder.displayPowerState, times(2)).setScreenState(anyInt());
mHolder = createDisplayPowerController(42, UNIQUE_ID);
@@ -479,8 +494,145 @@
verify(mHolder.displayPowerState).setScreenState(anyInt());
}
+ @Test
+ public void testSetScreenOffBrightnessSensorEnabled_DisplayIsOff() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(true);
+
+ // The display turns on and we use the brightness value recommended by
+ // ScreenOffBrightnessSensorController
+ clearInvocations(mHolder.screenOffBrightnessSensorController);
+ float brightness = 0.14f;
+ when(mHolder.screenOffBrightnessSensorController.getAutomaticScreenBrightness())
+ .thenReturn(brightness);
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .getAutomaticScreenBrightness();
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorEnabled_DisplayIsInDoze() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_DOZE;
+ when(mResourcesMock.getBoolean(
+ com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing))
+ .thenReturn(true);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(true);
+
+ // The display turns on and we use the brightness value recommended by
+ // ScreenOffBrightnessSensorController
+ clearInvocations(mHolder.screenOffBrightnessSensorController);
+ float brightness = 0.14f;
+ when(mHolder.screenOffBrightnessSensorController.getAutomaticScreenBrightness())
+ .thenReturn(brightness);
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .getAutomaticScreenBrightness();
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_AutoBrightnessIsDisabled() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_DisplayIsDisabled() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+ mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ false);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_DisplayIsOn() {
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_DisplayIsAFollower() {
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+
+ mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, /* leadDisplayId= */ 42);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
String uniqueId) {
+ return createDisplayPowerController(displayId, uniqueId, /* isEnabled= */ true);
+ }
+
+ private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
+ String uniqueId, boolean isEnabled) {
final DisplayPowerState displayPowerState = mock(DisplayPowerState.class);
final DualRampAnimator<DisplayPowerState> animator = mock(DualRampAnimator.class);
final AutomaticBrightnessController automaticBrightnessController =
@@ -489,10 +641,12 @@
final BrightnessMappingStrategy brightnessMappingStrategy =
mock(BrightnessMappingStrategy.class);
final HysteresisLevels hysteresisLevels = mock(HysteresisLevels.class);
+ final ScreenOffBrightnessSensorController screenOffBrightnessSensorController =
+ mock(ScreenOffBrightnessSensorController.class);
TestInjector injector = new TestInjector(displayPowerState, animator,
automaticBrightnessController, wakelockController, brightnessMappingStrategy,
- hysteresisLevels);
+ hysteresisLevels, screenOffBrightnessSensorController);
final LogicalDisplay display = mock(LogicalDisplay.class);
final DisplayDevice device = mock(DisplayDevice.class);
@@ -500,7 +654,7 @@
final BrightnessSetting brightnessSetting = mock(BrightnessSetting.class);
final DisplayDeviceConfig config = mock(DisplayDeviceConfig.class);
- setUpDisplay(displayId, uniqueId, display, device, config);
+ setUpDisplay(displayId, uniqueId, display, device, config, isEnabled);
final DisplayPowerController2 dpc = new DisplayPowerController2(
mContextSpy, injector, mDisplayPowerCallbacksMock, mHandler,
@@ -509,7 +663,8 @@
hbmMetadata, /* bootCompleted= */ false);
return new DisplayPowerControllerHolder(dpc, displayPowerState, brightnessSetting, animator,
- automaticBrightnessController, wakelockController);
+ automaticBrightnessController, wakelockController,
+ screenOffBrightnessSensorController, hbmMetadata);
}
/**
@@ -523,18 +678,24 @@
public final DualRampAnimator<DisplayPowerState> animator;
public final AutomaticBrightnessController automaticBrightnessController;
public final WakelockController wakelockController;
+ public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController;
+ public final HighBrightnessModeMetadata hbmMetadata;
DisplayPowerControllerHolder(DisplayPowerController2 dpc,
DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting,
DualRampAnimator<DisplayPowerState> animator,
AutomaticBrightnessController automaticBrightnessController,
- WakelockController wakelockController) {
+ WakelockController wakelockController,
+ ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
+ HighBrightnessModeMetadata hbmMetadata) {
this.dpc = dpc;
this.displayPowerState = displayPowerState;
this.brightnessSetting = brightnessSetting;
this.animator = animator;
this.automaticBrightnessController = automaticBrightnessController;
this.wakelockController = wakelockController;
+ this.screenOffBrightnessSensorController = screenOffBrightnessSensorController;
+ this.hbmMetadata = hbmMetadata;
}
}
@@ -545,18 +706,21 @@
private final WakelockController mWakelockController;
private final BrightnessMappingStrategy mBrightnessMappingStrategy;
private final HysteresisLevels mHysteresisLevels;
+ private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator,
AutomaticBrightnessController automaticBrightnessController,
WakelockController wakelockController,
BrightnessMappingStrategy brightnessMappingStrategy,
- HysteresisLevels hysteresisLevels) {
+ HysteresisLevels hysteresisLevels,
+ ScreenOffBrightnessSensorController screenOffBrightnessSensorController) {
mDisplayPowerState = dps;
mAnimator = animator;
mAutomaticBrightnessController = automaticBrightnessController;
mWakelockController = wakelockController;
mBrightnessMappingStrategy = brightnessMappingStrategy;
mHysteresisLevels = hysteresisLevels;
+ mScreenOffBrightnessSensorController = screenOffBrightnessSensorController;
}
@Override
@@ -636,5 +800,13 @@
float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
return mHysteresisLevels;
}
+
+ @Override
+ ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
+ SensorManager sensorManager, Sensor lightSensor, Handler handler,
+ ScreenOffBrightnessSensorController.Clock clock, int[] sensorValueToLux,
+ BrightnessMappingStrategy brightnessMapper) {
+ return mScreenOffBrightnessSensorController;
+ }
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
index 1e9041c..28319ac 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -26,12 +26,15 @@
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Resources;
@@ -44,7 +47,9 @@
import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.os.test.TestLooper;
+import android.provider.Settings;
import android.util.FloatProperty;
import android.view.Display;
import android.view.DisplayInfo;
@@ -57,6 +62,7 @@
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
import com.android.server.display.RampAnimator.DualRampAnimator;
+import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.color.ColorDisplayService;
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
import com.android.server.policy.WindowManagerPolicy;
@@ -122,6 +128,7 @@
.spyStatic(SystemProperties.class)
.spyStatic(LocalServices.class)
.spyStatic(BatteryStatsService.class)
+ .spyStatic(Settings.System.class)
.startMocking();
mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
mClock = new OffsettableClock.Stopped();
@@ -140,8 +147,7 @@
ColorDisplayService.ColorDisplayServiceInternal.class));
doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService);
- mProxSensor = setUpProxSensor();
-
+ setUpSensors();
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
}
@@ -217,12 +223,13 @@
mTestLooper.dispatchAll();
}
- private Sensor setUpProxSensor() throws Exception {
- Sensor proxSensor = TestUtils.createSensor(
+ private void setUpSensors() throws Exception {
+ mProxSensor = TestUtils.createSensor(
Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY);
+ Sensor screenOffBrightnessSensor = TestUtils.createSensor(
+ Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
when(mSensorManagerMock.getSensorList(eq(Sensor.TYPE_ALL)))
- .thenReturn(List.of(proxSensor));
- return proxSensor;
+ .thenReturn(List.of(mProxSensor, screenOffBrightnessSensor));
}
private SensorEventListener getSensorEventListener(Sensor sensor) {
@@ -232,14 +239,15 @@
}
private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock,
- DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock) {
+ DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock,
+ boolean isEnabled) {
DisplayInfo info = new DisplayInfo();
DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock);
when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
- when(logicalDisplayMock.isEnabledLocked()).thenReturn(true);
+ when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled);
when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
@@ -256,7 +264,14 @@
when(displayDeviceConfigMock.getAmbientLightSensor()).thenReturn(
new DisplayDeviceConfig.SensorData());
when(displayDeviceConfigMock.getScreenOffBrightnessSensor()).thenReturn(
- new DisplayDeviceConfig.SensorData());
+ new DisplayDeviceConfig.SensorData() {
+ {
+ type = Sensor.STRING_TYPE_LIGHT;
+ name = null;
+ }
+ });
+ when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
+ .thenReturn(new int[0]);
}
@Test
@@ -470,7 +485,7 @@
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1);
- verify(mHolder.displayPowerState).setScreenState(anyInt());
+ verify(mHolder.displayPowerState, times(2)).setScreenState(anyInt());
mHolder = createDisplayPowerController(42, UNIQUE_ID);
@@ -483,8 +498,145 @@
verify(mHolder.displayPowerState).setScreenState(anyInt());
}
+ @Test
+ public void testSetScreenOffBrightnessSensorEnabled_DisplayIsOff() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(true);
+
+ // The display turns on and we use the brightness value recommended by
+ // ScreenOffBrightnessSensorController
+ clearInvocations(mHolder.screenOffBrightnessSensorController);
+ float brightness = 0.14f;
+ when(mHolder.screenOffBrightnessSensorController.getAutomaticScreenBrightness())
+ .thenReturn(brightness);
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .getAutomaticScreenBrightness();
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorEnabled_DisplayIsInDoze() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_DOZE;
+ when(mResourcesMock.getBoolean(
+ com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing))
+ .thenReturn(true);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(true);
+
+ // The display turns on and we use the brightness value recommended by
+ // ScreenOffBrightnessSensorController
+ clearInvocations(mHolder.screenOffBrightnessSensorController);
+ float brightness = 0.14f;
+ when(mHolder.screenOffBrightnessSensorController.getAutomaticScreenBrightness())
+ .thenReturn(brightness);
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .getAutomaticScreenBrightness();
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_AutoBrightnessIsDisabled() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_DisplayIsDisabled() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+ mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ false);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_DisplayIsOn() {
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_DisplayIsAFollower() {
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+
+ mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, /* leadDisplayId= */ 42);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
String uniqueId) {
+ return createDisplayPowerController(displayId, uniqueId, /* isEnabled= */ true);
+ }
+
+ private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
+ String uniqueId, boolean isEnabled) {
final DisplayPowerState displayPowerState = mock(DisplayPowerState.class);
final DualRampAnimator<DisplayPowerState> animator = mock(DualRampAnimator.class);
final AutomaticBrightnessController automaticBrightnessController =
@@ -492,9 +644,12 @@
final BrightnessMappingStrategy brightnessMappingStrategy =
mock(BrightnessMappingStrategy.class);
final HysteresisLevels hysteresisLevels = mock(HysteresisLevels.class);
+ final ScreenOffBrightnessSensorController screenOffBrightnessSensorController =
+ mock(ScreenOffBrightnessSensorController.class);
DisplayPowerController.Injector injector = new TestInjector(displayPowerState, animator,
- automaticBrightnessController, brightnessMappingStrategy, hysteresisLevels);
+ automaticBrightnessController, brightnessMappingStrategy, hysteresisLevels,
+ screenOffBrightnessSensorController);
final LogicalDisplay display = mock(LogicalDisplay.class);
final DisplayDevice device = mock(DisplayDevice.class);
@@ -502,7 +657,7 @@
final BrightnessSetting brightnessSetting = mock(BrightnessSetting.class);
final DisplayDeviceConfig config = mock(DisplayDeviceConfig.class);
- setUpDisplay(displayId, uniqueId, display, device, config);
+ setUpDisplay(displayId, uniqueId, display, device, config, isEnabled);
final DisplayPowerController dpc = new DisplayPowerController(
mContextSpy, injector, mDisplayPowerCallbacksMock, mHandler,
@@ -511,7 +666,7 @@
hbmMetadata, /* bootCompleted= */ false);
return new DisplayPowerControllerHolder(dpc, displayPowerState, brightnessSetting, animator,
- automaticBrightnessController);
+ automaticBrightnessController, screenOffBrightnessSensorController, hbmMetadata);
}
/**
@@ -524,16 +679,22 @@
public final BrightnessSetting brightnessSetting;
public final DualRampAnimator<DisplayPowerState> animator;
public final AutomaticBrightnessController automaticBrightnessController;
+ public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController;
+ public final HighBrightnessModeMetadata hbmMetadata;
DisplayPowerControllerHolder(DisplayPowerController dpc,
DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting,
DualRampAnimator<DisplayPowerState> animator,
- AutomaticBrightnessController automaticBrightnessController) {
+ AutomaticBrightnessController automaticBrightnessController,
+ ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
+ HighBrightnessModeMetadata hbmMetadata) {
this.dpc = dpc;
this.displayPowerState = displayPowerState;
this.brightnessSetting = brightnessSetting;
this.animator = animator;
this.automaticBrightnessController = automaticBrightnessController;
+ this.screenOffBrightnessSensorController = screenOffBrightnessSensorController;
+ this.hbmMetadata = hbmMetadata;
}
}
@@ -543,16 +704,19 @@
private final AutomaticBrightnessController mAutomaticBrightnessController;
private final BrightnessMappingStrategy mBrightnessMappingStrategy;
private final HysteresisLevels mHysteresisLevels;
+ private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator,
AutomaticBrightnessController automaticBrightnessController,
BrightnessMappingStrategy brightnessMappingStrategy,
- HysteresisLevels hysteresisLevels) {
+ HysteresisLevels hysteresisLevels,
+ ScreenOffBrightnessSensorController screenOffBrightnessSensorController) {
mDisplayPowerState = dps;
mAnimator = animator;
mAutomaticBrightnessController = automaticBrightnessController;
mBrightnessMappingStrategy = brightnessMappingStrategy;
mHysteresisLevels = hysteresisLevels;
+ mScreenOffBrightnessSensorController = screenOffBrightnessSensorController;
}
@Override
@@ -616,5 +780,13 @@
float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
return mHysteresisLevels;
}
+
+ @Override
+ ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
+ SensorManager sensorManager, Sensor lightSensor, Handler handler,
+ ScreenOffBrightnessSensorController.Clock clock, int[] sensorValueToLux,
+ BrightnessMappingStrategy brightnessMapper) {
+ return mScreenOffBrightnessSensorController;
+ }
}
}