summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt4
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java1
-rw-r--r--core/java/android/hardware/camera2/CameraCaptureSession.java2
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java3
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java1
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java1
-rw-r--r--core/java/android/hardware/camera2/params/OutputConfiguration.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt5
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java59
-rw-r--r--services/core/java/com/android/server/display/DisplayModeDirector.java6
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java14
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController2.java15
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerControllerInterface.java8
-rw-r--r--services/core/java/com/android/server/display/HbmEvent.java46
-rw-r--r--services/core/java/com/android/server/display/HighBrightnessModeController.java111
-rw-r--r--services/core/java/com/android/server/display/HighBrightnessModeMetadata.java58
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java5
-rw-r--r--services/core/java/com/android/server/wm/Transition.java6
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java209
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java73
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java4
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/display/HbmEventTest.java57
-rw-r--r--services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/display/HighBrightnessModeMetadataTest.java59
27 files changed, 464 insertions, 352 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 3d76b6688053..10578dbccb70 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -19035,15 +19035,15 @@ package android.hardware.camera2.params {
method public int getSurfaceGroupId();
method @NonNull public java.util.List<android.view.Surface> getSurfaces();
method public int getTimestampBase();
- method public boolean isReadoutTimestampUsed();
+ method public boolean isReadoutTimestampEnabled();
method public void removeSensorPixelModeUsed(int);
method public void removeSurface(@NonNull android.view.Surface);
method public void setDynamicRangeProfile(long);
method public void setMirrorMode(int);
method public void setPhysicalCameraId(@Nullable String);
+ method public void setReadoutTimestampEnabled(boolean);
method public void setStreamUseCase(long);
method public void setTimestampBase(int);
- method public void useReadoutTimestamp(boolean);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
field public static final int MIRROR_MODE_AUTO = 0; // 0x0
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 7e5523a26f47..9843c8f2624f 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -11049,6 +11049,7 @@ public class DevicePolicyManager {
* @throws SecurityException if the caller is not a profile owner on an organization-owned
* managed profile.
* @throws IllegalStateException if called after the device setup has been completed.
+ * @throws UnsupportedOperationException if the api is not enabled.
* @see ManagedSubscriptionsPolicy
*/
public void setManagedSubscriptionsPolicy(@Nullable ManagedSubscriptionsPolicy policy) {
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index ff6e8975f8da..c9fc7220c08f 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -1246,7 +1246,7 @@ public abstract class CameraCaptureSession implements AutoCloseable {
* between frames.</p>
*
* <p>The timestamps match the timestamps of the output surfaces with readout timestamp
- * enabled (via {@link OutputConfiguration#useReadoutTimestamp}) if:</p>
+ * enabled (via {@link OutputConfiguration#setReadoutTimestampEnabled}) if:</p>
* <ul>
* <li> Timestamp base is {@link OutputConfiguration#TIMESTAMP_BASE_DEFAULT} and the
* output
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 11b80cc98275..f20b25ff5434 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -4600,7 +4600,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* {@link CameraCaptureSession.CaptureCallback#onCaptureStarted }.</p>
* <p>In addition, the application can switch an output surface's timestamp from start of
* exposure to start of readout by calling
- * {@link android.hardware.camera2.params.OutputConfiguration#useReadoutTimestamp }.</p>
+ * {@link android.hardware.camera2.params.OutputConfiguration#setReadoutTimestampEnabled }.</p>
* <p>The readout timestamp is beneficial for video recording, because the encoder favors
* uniform timestamps, and the readout timestamps better reflect the cadence camera sensors
* output data.</p>
@@ -5688,4 +5688,5 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
+
}
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 3d8300933054..381c87d39cac 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -4198,4 +4198,5 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
+
}
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index dad7d3eb6842..635e79c01399 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -5699,4 +5699,5 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
+
}
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 8b7c5ec57516..857f62dfdd99 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -257,7 +257,7 @@ public final class OutputConfiguration implements Parcelable {
/**
* Timestamp is the start of readout in the same time domain as TIMESTAMP_BASE_SENSOR.
*
- * <p>NOTE: do not use! Use useReadoutTimestamp instead.</p>
+ * <p>NOTE: do not use! Use setReadoutTimestampEnabled instead.</p>
*
* @hide
*/
@@ -574,7 +574,7 @@ public final class OutputConfiguration implements Parcelable {
mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
mTimestampBase = TIMESTAMP_BASE_DEFAULT;
mMirrorMode = MIRROR_MODE_AUTO;
- mUseReadoutTimestamp = false;
+ mReadoutTimestampEnabled = false;
mIsReadoutSensorTimestampBase = false;
}
@@ -676,7 +676,7 @@ public final class OutputConfiguration implements Parcelable {
mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
mColorSpace = ColorSpaceProfiles.UNSPECIFIED;
mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
- mUseReadoutTimestamp = false;
+ mReadoutTimestampEnabled = false;
mIsReadoutSensorTimestampBase = false;
}
@@ -1050,7 +1050,7 @@ public final class OutputConfiguration implements Parcelable {
if (timestampBase == TIMESTAMP_BASE_READOUT_SENSOR) {
mTimestampBase = TIMESTAMP_BASE_SENSOR;
- mUseReadoutTimestamp = true;
+ mReadoutTimestampEnabled = true;
mIsReadoutSensorTimestampBase = true;
} else {
mTimestampBase = timestampBase;
@@ -1131,14 +1131,16 @@ public final class OutputConfiguration implements Parcelable {
* @param on The output image timestamp is the start of exposure time if false, and
* the start of readout time if true.
*/
- public void useReadoutTimestamp(boolean on) {
- mUseReadoutTimestamp = on;
+ public void setReadoutTimestampEnabled(boolean on) {
+ mReadoutTimestampEnabled = on;
}
/** Whether readout timestamp is used for this OutputConfiguration.
+ *
+ * @see #setReadoutTimestampEnabled
*/
- public boolean isReadoutTimestampUsed() {
- return mUseReadoutTimestamp;
+ public boolean isReadoutTimestampEnabled() {
+ return mReadoutTimestampEnabled;
}
/**
@@ -1172,7 +1174,7 @@ public final class OutputConfiguration implements Parcelable {
this.mStreamUseCase = other.mStreamUseCase;
this.mTimestampBase = other.mTimestampBase;
this.mMirrorMode = other.mMirrorMode;
- this.mUseReadoutTimestamp = other.mUseReadoutTimestamp;
+ this.mReadoutTimestampEnabled = other.mReadoutTimestampEnabled;
}
/**
@@ -1200,7 +1202,7 @@ public final class OutputConfiguration implements Parcelable {
int timestampBase = source.readInt();
int mirrorMode = source.readInt();
- boolean useReadoutTimestamp = source.readInt() == 1;
+ boolean readoutTimestampEnabled = source.readInt() == 1;
mSurfaceGroupId = surfaceSetId;
mRotation = rotation;
@@ -1229,7 +1231,7 @@ public final class OutputConfiguration implements Parcelable {
mStreamUseCase = streamUseCase;
mTimestampBase = timestampBase;
mMirrorMode = mirrorMode;
- mUseReadoutTimestamp = useReadoutTimestamp;
+ mReadoutTimestampEnabled = readoutTimestampEnabled;
}
/**
@@ -1350,7 +1352,7 @@ public final class OutputConfiguration implements Parcelable {
dest.writeLong(mStreamUseCase);
dest.writeInt(mTimestampBase);
dest.writeInt(mMirrorMode);
- dest.writeInt(mUseReadoutTimestamp ? 1 : 0);
+ dest.writeInt(mReadoutTimestampEnabled ? 1 : 0);
}
/**
@@ -1385,7 +1387,7 @@ public final class OutputConfiguration implements Parcelable {
mStreamUseCase != other.mStreamUseCase ||
mTimestampBase != other.mTimestampBase ||
mMirrorMode != other.mMirrorMode ||
- mUseReadoutTimestamp != other.mUseReadoutTimestamp)
+ mReadoutTimestampEnabled != other.mReadoutTimestampEnabled)
return false;
if (mSensorPixelModesUsed.size() != other.mSensorPixelModesUsed.size()) {
return false;
@@ -1428,7 +1430,7 @@ public final class OutputConfiguration implements Parcelable {
mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(),
mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(),
mDynamicRangeProfile, mColorSpace, mStreamUseCase,
- mTimestampBase, mMirrorMode, mUseReadoutTimestamp ? 1 : 0);
+ mTimestampBase, mMirrorMode, mReadoutTimestampEnabled ? 1 : 0);
}
return HashCodeHelpers.hashCode(
@@ -1438,7 +1440,7 @@ public final class OutputConfiguration implements Parcelable {
mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(),
mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(),
mDynamicRangeProfile, mColorSpace, mStreamUseCase, mTimestampBase,
- mMirrorMode, mUseReadoutTimestamp ? 1 : 0);
+ mMirrorMode, mReadoutTimestampEnabled ? 1 : 0);
}
private static final String TAG = "OutputConfiguration";
@@ -1480,8 +1482,8 @@ public final class OutputConfiguration implements Parcelable {
private int mTimestampBase;
// Mirroring mode
private int mMirrorMode;
- // Use readout timestamp
- private boolean mUseReadoutTimestamp;
+ // readout timestamp
+ private boolean mReadoutTimestampEnabled;
// Whether the timestamp base is set to READOUT_SENSOR
private boolean mIsReadoutSensorTimestampBase;
}
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
index 8d5e01c5b782..9050dad0134c 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
@@ -29,13 +29,14 @@ import android.os.Bundle
import android.os.Handler
import android.os.UserHandle
import android.util.Log
-import android.view.InputDevice
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.shared.hardware.hasInputDevice
+import com.android.systemui.shared.hardware.isAnyStylusSource
import com.android.systemui.util.NotificationChannels
import java.text.NumberFormat
import javax.inject.Inject
@@ -150,10 +151,7 @@ constructor(
}
private fun hasConnectedBluetoothStylus(): Boolean {
- // TODO(b/257936830): get bt address once input api available
- return inputManager.inputDeviceIds.any { deviceId ->
- inputManager.getInputDevice(deviceId).supportsSource(InputDevice.SOURCE_STYLUS)
- }
+ return inputManager.hasInputDevice { it.isAnyStylusSource && it.bluetoothAddress != null }
}
private fun getPendingBroadcast(action: String): PendingIntent? {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
index 1e81dc761b18..e1668e8bfa37 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
@@ -36,7 +36,6 @@ import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import junit.framework.Assert.assertEquals
import org.junit.Before
-import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
@@ -79,7 +78,7 @@ class StylusUsiPowerUiTest : SysuiTestCase() {
whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf())
whenever(inputManager.getInputDevice(0)).thenReturn(btStylusDevice)
whenever(btStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
- // whenever(btStylusDevice.bluetoothAddress).thenReturn("SO:ME:AD:DR:ES")
+ whenever(btStylusDevice.bluetoothAddress).thenReturn("SO:ME:AD:DR:ES")
stylusUsiPowerUi = StylusUsiPowerUI(contextSpy, notificationManager, inputManager, handler)
broadcastReceiver = stylusUsiPowerUi.receiver
@@ -179,7 +178,6 @@ class StylusUsiPowerUiTest : SysuiTestCase() {
}
@Test
- @Ignore("TODO(b/257936830): get bt address once input api available")
fun refresh_hasConnectedBluetoothStylus_cancelsNotification() {
whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(0))
@@ -189,7 +187,6 @@ class StylusUsiPowerUiTest : SysuiTestCase() {
}
@Test
- @Ignore("TODO(b/257936830): get bt address once input api available")
fun refresh_hasConnectedBluetoothStylus_existingNotification_cancelsNotification() {
stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.1f))
whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(0))
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index d558e69db653..466070fe14b2 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -109,6 +109,7 @@ import android.os.UserManager;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.IntArray;
@@ -260,6 +261,13 @@ public final class DisplayManagerService extends SystemService {
final SparseArray<Pair<IVirtualDevice, DisplayWindowPolicyController>>
mDisplayWindowPolicyControllers = new SparseArray<>();
+ /**
+ * Map of every internal primary display device {@link HighBrightnessModeMetadata}s indexed by
+ * {@link DisplayDevice#mUniqueId}.
+ */
+ public final ArrayMap<String, HighBrightnessModeMetadata> mHighBrightnessModeMetadataMap =
+ new ArrayMap<>();
+
// List of all currently registered display adapters.
private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
@@ -1640,7 +1648,16 @@ public final class DisplayManagerService extends SystemService {
DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId);
if (dpc != null) {
- dpc.onDisplayChanged();
+ final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
+ if (device == null) {
+ Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: "
+ + display.getDisplayIdLocked());
+ return;
+ }
+
+ final String uniqueId = device.getUniqueId();
+ HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
+ dpc.onDisplayChanged(hbmMetadata);
}
}
@@ -1698,7 +1715,15 @@ public final class DisplayManagerService extends SystemService {
final int displayId = display.getDisplayIdLocked();
final DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId);
if (dpc != null) {
- dpc.onDisplayChanged();
+ final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
+ if (device == null) {
+ Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: "
+ + display.getDisplayIdLocked());
+ return;
+ }
+ final String uniqueId = device.getUniqueId();
+ HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
+ dpc.onDisplayChanged(hbmMetadata);
}
}
@@ -2651,6 +2676,26 @@ public final class DisplayManagerService extends SystemService {
mLogicalDisplayMapper.forEachLocked(this::addDisplayPowerControllerLocked);
}
+ private HighBrightnessModeMetadata getHighBrightnessModeMetadata(LogicalDisplay display) {
+ final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
+ if (device == null) {
+ Slog.wtf(TAG, "Display Device is null in DisplayPowerController for display: "
+ + display.getDisplayIdLocked());
+ return null;
+ }
+
+ final String uniqueId = device.getUniqueId();
+
+ if (mHighBrightnessModeMetadataMap.containsKey(uniqueId)) {
+ return mHighBrightnessModeMetadataMap.get(uniqueId);
+ }
+
+ // HBM Time info not present. Create a new one for this physical display.
+ HighBrightnessModeMetadata hbmInfo = new HighBrightnessModeMetadata();
+ mHighBrightnessModeMetadataMap.put(uniqueId, hbmInfo);
+ return hbmInfo;
+ }
+
@RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
private void addDisplayPowerControllerLocked(LogicalDisplay display) {
if (mPowerHandler == null) {
@@ -2666,17 +2711,23 @@ public final class DisplayManagerService extends SystemService {
display, mSyncRoot);
final DisplayPowerControllerInterface displayPowerController;
+ // If display is internal and has a HighBrightnessModeMetadata mapping, use that.
+ // Or create a new one and use that.
+ // We also need to pass a mapping of the HighBrightnessModeTimeInfoMap to
+ // displayPowerController, so the hbm info can be correctly associated
+ // with the corresponding displaydevice.
+ HighBrightnessModeMetadata hbmMetadata = getHighBrightnessModeMetadata(display);
if (DeviceConfig.getBoolean("display_manager",
"use_newly_structured_display_power_controller", true)) {
displayPowerController = new DisplayPowerController2(
mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
- () -> handleBrightnessChange(display));
+ () -> handleBrightnessChange(display), hbmMetadata);
} else {
displayPowerController = new DisplayPowerController(
mContext, /* injector= */ null, mDisplayPowerCallbacks, mPowerHandler,
mSensorManager, mDisplayBlanker, display, mBrightnessTracker, brightnessSetting,
- () -> handleBrightnessChange(display));
+ () -> handleBrightnessChange(display), hbmMetadata);
}
mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController);
}
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index c960416b6328..f8d6c5f3ea4d 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -3081,10 +3081,10 @@ public class DisplayModeDirector {
@Override
public boolean supportsFrameRateOverride() {
- return SurfaceFlingerProperties.enable_frame_rate_override().orElse(true)
+ return SurfaceFlingerProperties.enable_frame_rate_override().orElse(false)
&& !SurfaceFlingerProperties.frame_rate_override_for_native_rates()
- .orElse(false)
- && SurfaceFlingerProperties.frame_rate_override_global().orElse(true);
+ .orElse(true)
+ && SurfaceFlingerProperties.frame_rate_override_global().orElse(false);
}
private DisplayManager getDisplayManager() {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index cdaa3d0e6d27..142ec68582f9 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -388,6 +388,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private float[] mNitsRange;
private final HighBrightnessModeController mHbmController;
+ private final HighBrightnessModeMetadata mHighBrightnessModeMetadata;
private final BrightnessThrottler mBrightnessThrottler;
@@ -505,13 +506,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
- Runnable onBrightnessChangeRunnable) {
+ Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata) {
mInjector = injector != null ? injector : new Injector();
mClock = mInjector.getClock();
mLogicalDisplay = logicalDisplay;
mDisplayId = mLogicalDisplay.getDisplayIdLocked();
mTag = "DisplayPowerController[" + mDisplayId + "]";
+ mHighBrightnessModeMetadata = hbmMetadata;
mSuspendBlockerIdUnfinishedBusiness = getSuspendBlockerUnfinishedBusinessId(mDisplayId);
mSuspendBlockerIdOnStateChanged = getSuspendBlockerOnStateChangedId(mDisplayId);
mSuspendBlockerIdProxPositive = getSuspendBlockerProxPositiveId(mDisplayId);
@@ -790,7 +792,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
* Make sure DisplayManagerService.mSyncRoot is held when this is called
*/
@Override
- public void onDisplayChanged() {
+ public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) {
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
if (device == null) {
Slog.wtf(mTag, "Display Device is null in DisplayPowerController for display: "
@@ -812,7 +814,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mUniqueDisplayId = uniqueId;
mDisplayStatsId = mUniqueDisplayId.hashCode();
mDisplayDeviceConfig = config;
- loadFromDisplayDeviceConfig(token, info);
+ loadFromDisplayDeviceConfig(token, info, hbmMetadata);
/// Since the underlying display-device changed, we really don't know the
// last command that was sent to change it's state. Lets assume it is unknown so
@@ -864,7 +866,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
- private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info) {
+ private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info,
+ HighBrightnessModeMetadata hbmMetadata) {
// All properties that depend on the associated DisplayDevice and the DDC must be
// updated here.
loadBrightnessRampRates();
@@ -877,6 +880,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mBrightnessRampIncreaseMaxTimeMillis,
mBrightnessRampDecreaseMaxTimeMillis);
}
+ mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
mDisplayDeviceConfig.getHighBrightnessModeData(),
new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
@@ -1961,7 +1965,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.update();
}
- }, mContext);
+ }, mHighBrightnessModeMetadata, mContext);
}
private BrightnessThrottler createBrightnessThrottlerLocked() {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index df0e2d38ce20..ba9fe38c7cb4 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -327,6 +327,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
private float[] mNitsRange;
private final HighBrightnessModeController mHbmController;
+ private final HighBrightnessModeMetadata mHighBrightnessModeMetadata;
private final BrightnessThrottler mBrightnessThrottler;
@@ -415,7 +416,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting,
- Runnable onBrightnessChangeRunnable) {
+ Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata) {
mInjector = injector != null ? injector : new Injector();
mClock = mInjector.getClock();
@@ -431,6 +432,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mDisplayPowerProximityStateController = mInjector.getDisplayPowerProximityStateController(
mWakelockController, mDisplayDeviceConfig, mHandler.getLooper(),
() -> updatePowerState(), mDisplayId, mSensorManager);
+ mHighBrightnessModeMetadata = hbmMetadata;
mDisplayStateController = new DisplayStateController(mDisplayPowerProximityStateController);
mTag = "DisplayPowerController2[" + mDisplayId + "]";
@@ -681,7 +683,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
* Make sure DisplayManagerService.mSyncRoot lock is held when this is called
*/
@Override
- public void onDisplayChanged() {
+ public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) {
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
if (device == null) {
Slog.wtf(mTag, "Display Device is null in DisplayPowerController2 for display: "
@@ -695,6 +697,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
final boolean isEnabled = mLogicalDisplay.isEnabledLocked();
final boolean isInTransition = mLogicalDisplay.isInTransitionLocked();
+
mHandler.post(() -> {
boolean changed = false;
if (mDisplayDevice != device) {
@@ -703,7 +706,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mUniqueDisplayId = uniqueId;
mDisplayStatsId = mUniqueDisplayId.hashCode();
mDisplayDeviceConfig = config;
- loadFromDisplayDeviceConfig(token, info);
+ loadFromDisplayDeviceConfig(token, info, hbmMetadata);
mDisplayPowerProximityStateController.notifyDisplayDeviceChanged(config);
// Since the underlying display-device changed, we really don't know the
@@ -750,7 +753,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
}
}
- private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info) {
+ private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info,
+ HighBrightnessModeMetadata hbmMetadata) {
// All properties that depend on the associated DisplayDevice and the DDC must be
// updated here.
loadBrightnessRampRates();
@@ -762,6 +766,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mBrightnessRampIncreaseMaxTimeMillis,
mBrightnessRampDecreaseMaxTimeMillis);
}
+ mHbmController.setHighBrightnessModeMetadata(hbmMetadata);
mHbmController.resetHbmData(info.width, info.height, token, info.uniqueId,
mDisplayDeviceConfig.getHighBrightnessModeData(),
new HighBrightnessModeController.HdrBrightnessDeviceConfig() {
@@ -1718,7 +1723,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.update();
}
- }, mContext);
+ }, mHighBrightnessModeMetadata, mContext);
}
private BrightnessThrottler createBrightnessThrottlerLocked() {
diff --git a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
index e750ee281413..7b0198465e68 100644
--- a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
+++ b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
@@ -31,10 +31,14 @@ import java.io.PrintWriter;
public interface DisplayPowerControllerInterface {
/**
- * Notified when the display is changed. We use this to apply any changes that might be needed
+ * Notified when the display is changed.
+ * We use this to apply any changes that might be needed
* when displays get swapped on foldable devices.
+ * We also pass the High brightness mode metadata like
+ * remaining time and hbm events for the corresponding
+ * physical display, to update the values correctly.
*/
- void onDisplayChanged();
+ void onDisplayChanged(HighBrightnessModeMetadata hbmInfo);
/**
* Unregisters all listeners and interrupts all running threads; halting future work.
diff --git a/services/core/java/com/android/server/display/HbmEvent.java b/services/core/java/com/android/server/display/HbmEvent.java
new file mode 100644
index 000000000000..5675e2f69230
--- /dev/null
+++ b/services/core/java/com/android/server/display/HbmEvent.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+
+/**
+ * Represents an event in which High Brightness Mode was enabled.
+ */
+class HbmEvent {
+ private long mStartTimeMillis;
+ private long mEndTimeMillis;
+
+ HbmEvent(long startTimeMillis, long endTimeMillis) {
+ this.mStartTimeMillis = startTimeMillis;
+ this.mEndTimeMillis = endTimeMillis;
+ }
+
+ public long getStartTimeMillis() {
+ return mStartTimeMillis;
+ }
+
+ public long getEndTimeMillis() {
+ return mEndTimeMillis;
+ }
+
+ @Override
+ public String toString() {
+ return "HbmEvent: {startTimeMillis:" + mStartTimeMillis + ", endTimeMillis: "
+ + mEndTimeMillis + "}, total: "
+ + ((mEndTimeMillis - mStartTimeMillis) / 1000) + "]";
+ }
+}
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeController.java b/services/core/java/com/android/server/display/HighBrightnessModeController.java
index f98c7dff97e3..2c843a4222dd 100644
--- a/services/core/java/com/android/server/display/HighBrightnessModeController.java
+++ b/services/core/java/com/android/server/display/HighBrightnessModeController.java
@@ -105,30 +105,23 @@ class HighBrightnessModeController {
private int mHbmStatsState = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF;
/**
- * If HBM is currently running, this is the start time for the current HBM session.
+ * If HBM is currently running, this is the start time and set of all events,
+ * for the current HBM session.
*/
- private long mRunningStartTimeMillis = -1;
-
- /**
- * Queue of previous HBM-events ordered from most recent to least recent.
- * Meant to store only the events that fall into the most recent
- * {@link HighBrightnessModeData#timeWindowMillis mHbmData.timeWindowMillis}.
- */
- private final ArrayDeque<HbmEvent> mEvents = new ArrayDeque<>();
-
+ private HighBrightnessModeMetadata mHighBrightnessModeMetadata = null;
HighBrightnessModeController(Handler handler, int width, int height, IBinder displayToken,
String displayUniqueId, float brightnessMin, float brightnessMax,
HighBrightnessModeData hbmData, HdrBrightnessDeviceConfig hdrBrightnessCfg,
- Runnable hbmChangeCallback, Context context) {
+ Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata, Context context) {
this(new Injector(), handler, width, height, displayToken, displayUniqueId, brightnessMin,
- brightnessMax, hbmData, hdrBrightnessCfg, hbmChangeCallback, context);
+ brightnessMax, hbmData, hdrBrightnessCfg, hbmChangeCallback, hbmMetadata, context);
}
@VisibleForTesting
HighBrightnessModeController(Injector injector, Handler handler, int width, int height,
IBinder displayToken, String displayUniqueId, float brightnessMin, float brightnessMax,
HighBrightnessModeData hbmData, HdrBrightnessDeviceConfig hdrBrightnessCfg,
- Runnable hbmChangeCallback, Context context) {
+ Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata, Context context) {
mInjector = injector;
mContext = context;
mClock = injector.getClock();
@@ -137,6 +130,7 @@ class HighBrightnessModeController {
mBrightnessMin = brightnessMin;
mBrightnessMax = brightnessMax;
mHbmChangeCallback = hbmChangeCallback;
+ mHighBrightnessModeMetadata = hbmMetadata;
mSkinThermalStatusObserver = new SkinThermalStatusObserver(mInjector, mHandler);
mSettingsObserver = new SettingsObserver(mHandler);
mRecalcRunnable = this::recalculateTimeAllowance;
@@ -222,19 +216,22 @@ class HighBrightnessModeController {
// If we are starting or ending a high brightness mode session, store the current
// session in mRunningStartTimeMillis, or the old one in mEvents.
- final boolean wasHbmDrainingAvailableTime = mRunningStartTimeMillis != -1;
+ final long runningStartTime = mHighBrightnessModeMetadata.getRunningStartTimeMillis();
+ final boolean wasHbmDrainingAvailableTime = runningStartTime != -1;
final boolean shouldHbmDrainAvailableTime = mBrightness > mHbmData.transitionPoint
&& !mIsHdrLayerPresent;
if (wasHbmDrainingAvailableTime != shouldHbmDrainAvailableTime) {
final long currentTime = mClock.uptimeMillis();
if (shouldHbmDrainAvailableTime) {
- mRunningStartTimeMillis = currentTime;
+ mHighBrightnessModeMetadata.setRunningStartTimeMillis(currentTime);
} else {
- mEvents.addFirst(new HbmEvent(mRunningStartTimeMillis, currentTime));
- mRunningStartTimeMillis = -1;
+ final HbmEvent hbmEvent = new HbmEvent(runningStartTime, currentTime);
+ mHighBrightnessModeMetadata.addHbmEvent(hbmEvent);
+ mHighBrightnessModeMetadata.setRunningStartTimeMillis(-1);
if (DEBUG) {
- Slog.d(TAG, "New HBM event: " + mEvents.peekFirst());
+ Slog.d(TAG, "New HBM event: "
+ + mHighBrightnessModeMetadata.getHbmEventQueue().peekFirst());
}
}
}
@@ -260,6 +257,10 @@ class HighBrightnessModeController {
mSettingsObserver.stopObserving();
}
+ void setHighBrightnessModeMetadata(HighBrightnessModeMetadata hbmInfo) {
+ mHighBrightnessModeMetadata = hbmInfo;
+ }
+
void resetHbmData(int width, int height, IBinder displayToken, String displayUniqueId,
HighBrightnessModeData hbmData, HdrBrightnessDeviceConfig hdrBrightnessCfg) {
mWidth = width;
@@ -316,20 +317,22 @@ class HighBrightnessModeController {
pw.println(" mBrightnessMax=" + mBrightnessMax);
pw.println(" remainingTime=" + calculateRemainingTime(mClock.uptimeMillis()));
pw.println(" mIsTimeAvailable= " + mIsTimeAvailable);
- pw.println(" mRunningStartTimeMillis=" + TimeUtils.formatUptime(mRunningStartTimeMillis));
+ pw.println(" mRunningStartTimeMillis="
+ + TimeUtils.formatUptime(mHighBrightnessModeMetadata.getRunningStartTimeMillis()));
pw.println(" mIsThermalStatusWithinLimit=" + mIsThermalStatusWithinLimit);
pw.println(" mIsBlockedByLowPowerMode=" + mIsBlockedByLowPowerMode);
pw.println(" width*height=" + mWidth + "*" + mHeight);
pw.println(" mEvents=");
final long currentTime = mClock.uptimeMillis();
long lastStartTime = currentTime;
- if (mRunningStartTimeMillis != -1) {
- lastStartTime = dumpHbmEvent(pw, new HbmEvent(mRunningStartTimeMillis, currentTime));
+ long runningStartTimeMillis = mHighBrightnessModeMetadata.getRunningStartTimeMillis();
+ if (runningStartTimeMillis != -1) {
+ lastStartTime = dumpHbmEvent(pw, new HbmEvent(runningStartTimeMillis, currentTime));
}
- for (HbmEvent event : mEvents) {
- if (lastStartTime > event.endTimeMillis) {
+ for (HbmEvent event : mHighBrightnessModeMetadata.getHbmEventQueue()) {
+ if (lastStartTime > event.getEndTimeMillis()) {
pw.println(" event: [normal brightness]: "
- + TimeUtils.formatDuration(lastStartTime - event.endTimeMillis));
+ + TimeUtils.formatDuration(lastStartTime - event.getEndTimeMillis()));
}
lastStartTime = dumpHbmEvent(pw, event);
}
@@ -338,12 +341,12 @@ class HighBrightnessModeController {
}
private long dumpHbmEvent(PrintWriter pw, HbmEvent event) {
- final long duration = event.endTimeMillis - event.startTimeMillis;
+ final long duration = event.getEndTimeMillis() - event.getStartTimeMillis();
pw.println(" event: ["
- + TimeUtils.formatUptime(event.startTimeMillis) + ", "
- + TimeUtils.formatUptime(event.endTimeMillis) + "] ("
+ + TimeUtils.formatUptime(event.getStartTimeMillis()) + ", "
+ + TimeUtils.formatUptime(event.getEndTimeMillis()) + "] ("
+ TimeUtils.formatDuration(duration) + ")");
- return event.startTimeMillis;
+ return event.getStartTimeMillis();
}
private boolean isCurrentlyAllowed() {
@@ -372,13 +375,15 @@ class HighBrightnessModeController {
// First, lets see how much time we've taken for any currently running
// session of HBM.
- if (mRunningStartTimeMillis > 0) {
- if (mRunningStartTimeMillis > currentTime) {
+ long runningStartTimeMillis = mHighBrightnessModeMetadata.getRunningStartTimeMillis();
+ if (runningStartTimeMillis > 0) {
+ if (runningStartTimeMillis > currentTime) {
Slog.e(TAG, "Start time set to the future. curr: " + currentTime
- + ", start: " + mRunningStartTimeMillis);
- mRunningStartTimeMillis = currentTime;
+ + ", start: " + runningStartTimeMillis);
+ mHighBrightnessModeMetadata.setRunningStartTimeMillis(currentTime);
+ runningStartTimeMillis = currentTime;
}
- timeAlreadyUsed = currentTime - mRunningStartTimeMillis;
+ timeAlreadyUsed = currentTime - runningStartTimeMillis;
}
if (DEBUG) {
@@ -387,18 +392,19 @@ class HighBrightnessModeController {
// Next, lets iterate through the history of previous sessions and add those times.
final long windowstartTimeMillis = currentTime - mHbmData.timeWindowMillis;
- Iterator<HbmEvent> it = mEvents.iterator();
+ Iterator<HbmEvent> it = mHighBrightnessModeMetadata.getHbmEventQueue().iterator();
while (it.hasNext()) {
final HbmEvent event = it.next();
// If this event ended before the current Timing window, discard forever and ever.
- if (event.endTimeMillis < windowstartTimeMillis) {
+ if (event.getEndTimeMillis() < windowstartTimeMillis) {
it.remove();
continue;
}
- final long startTimeMillis = Math.max(event.startTimeMillis, windowstartTimeMillis);
- timeAlreadyUsed += event.endTimeMillis - startTimeMillis;
+ final long startTimeMillis = Math.max(event.getStartTimeMillis(),
+ windowstartTimeMillis);
+ timeAlreadyUsed += event.getEndTimeMillis() - startTimeMillis;
}
if (DEBUG) {
@@ -425,17 +431,18 @@ class HighBrightnessModeController {
// Calculate the time at which we want to recalculate mIsTimeAvailable in case a lux or
// brightness change doesn't happen before then.
long nextTimeout = -1;
+ final ArrayDeque<HbmEvent> hbmEvents = mHighBrightnessModeMetadata.getHbmEventQueue();
if (mBrightness > mHbmData.transitionPoint) {
// if we're in high-lux now, timeout when we run out of allowed time.
nextTimeout = currentTime + remainingTime;
- } else if (!mIsTimeAvailable && mEvents.size() > 0) {
+ } else if (!mIsTimeAvailable && hbmEvents.size() > 0) {
// If we are not allowed...timeout when the oldest event moved outside of the timing
// window by at least minTime. Basically, we're calculating the soonest time we can
// get {@code timeMinMillis} back to us.
final long windowstartTimeMillis = currentTime - mHbmData.timeWindowMillis;
- final HbmEvent lastEvent = mEvents.peekLast();
+ final HbmEvent lastEvent = hbmEvents.peekLast();
final long startTimePlusMinMillis =
- Math.max(windowstartTimeMillis, lastEvent.startTimeMillis)
+ Math.max(windowstartTimeMillis, lastEvent.getStartTimeMillis())
+ mHbmData.timeMinMillis;
final long timeWhenMinIsGainedBack =
currentTime + (startTimePlusMinMillis - windowstartTimeMillis) - remainingTime;
@@ -459,9 +466,10 @@ class HighBrightnessModeController {
+ ", mUnthrottledBrightness: " + mUnthrottledBrightness
+ ", mThrottlingReason: "
+ BrightnessInfo.briMaxReasonToString(mThrottlingReason)
- + ", RunningStartTimeMillis: " + mRunningStartTimeMillis
+ + ", RunningStartTimeMillis: "
+ + mHighBrightnessModeMetadata.getRunningStartTimeMillis()
+ ", nextTimeout: " + (nextTimeout != -1 ? (nextTimeout - currentTime) : -1)
- + ", events: " + mEvents);
+ + ", events: " + hbmEvents);
}
if (nextTimeout != -1) {
@@ -588,25 +596,6 @@ class HighBrightnessModeController {
}
}
- /**
- * Represents an event in which High Brightness Mode was enabled.
- */
- private static class HbmEvent {
- public long startTimeMillis;
- public long endTimeMillis;
-
- HbmEvent(long startTimeMillis, long endTimeMillis) {
- this.startTimeMillis = startTimeMillis;
- this.endTimeMillis = endTimeMillis;
- }
-
- @Override
- public String toString() {
- return "[Event: {" + startTimeMillis + ", " + endTimeMillis + "}, total: "
- + ((endTimeMillis - startTimeMillis) / 1000) + "]";
- }
- }
-
@VisibleForTesting
class HdrListener extends SurfaceControlHdrLayerInfoListener {
@Override
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeMetadata.java b/services/core/java/com/android/server/display/HighBrightnessModeMetadata.java
new file mode 100644
index 000000000000..37234ff0bf19
--- /dev/null
+++ b/services/core/java/com/android/server/display/HighBrightnessModeMetadata.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import java.util.ArrayDeque;
+
+
+/**
+ * Represents High Brightness Mode metadata associated
+ * with a specific internal physical display.
+ * Required for separately storing data like time information,
+ * and related events when display was in HBM mode per
+ * physical internal display.
+ */
+class HighBrightnessModeMetadata {
+ /**
+ * Queue of previous HBM-events ordered from most recent to least recent.
+ * Meant to store only the events that fall into the most recent
+ * {@link HighBrightnessModeData#timeWindowMillis mHbmData.timeWindowMillis}.
+ */
+ private final ArrayDeque<HbmEvent> mEvents = new ArrayDeque<>();
+
+ /**
+ * If HBM is currently running, this is the start time for the current HBM session.
+ */
+ private long mRunningStartTimeMillis = -1;
+
+ public long getRunningStartTimeMillis() {
+ return mRunningStartTimeMillis;
+ }
+
+ public void setRunningStartTimeMillis(long setTime) {
+ mRunningStartTimeMillis = setTime;
+ }
+
+ public ArrayDeque<HbmEvent> getHbmEventQueue() {
+ return mEvents;
+ }
+
+ public void addHbmEvent(HbmEvent hbmEvent) {
+ mEvents.addFirst(hbmEvent);
+ }
+}
+
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0bd59a8509f8..1794e2ae4394 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5264,6 +5264,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return b;
}
+ // WARNING: it says `mSurfaceControl` below, but this CHANGES meaning after construction!
+ // DisplayAreas are added in `configureSurface()` *before* `mSurfaceControl` gets replaced
+ // with a wrapper or magnification surface so they end up in the right place; however,
+ // anything added or reparented to "the display" *afterwards* needs to be reparented to
+ // `getWindowinglayer()` (unless it's an overlay DisplayArea).
return b.setName(child.getName())
.setParent(mSurfaceControl);
}
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 7d3367fe8bf7..7b56b0c969c9 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1650,6 +1650,12 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
// DisplayContent is the "root", so we reinterpret it's wc as the window layer
// making the parent surface the displaycontent's surface.
return wc.getSurfaceControl();
+ } else if (wc.getParent().asDisplayContent() != null) {
+ // DisplayContent is kinda split into 2 pieces, the "real root" and the
+ // "windowing layer". So if the parent of the window is DC, then it really belongs on
+ // the windowing layer (unless it's an overlay display area, but those can't be in
+ // transitions anyways).
+ return wc.getParent().asDisplayContent().getWindowingLayer();
}
return wc.getParent().getSurfaceControl();
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
deleted file mode 100644
index 834f65fa9e97..000000000000
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.devicepolicy;
-
-import android.accounts.Account;
-import android.annotation.NonNull;
-import android.annotation.UserIdInt;
-import android.app.admin.DevicePolicyDrawableResource;
-import android.app.admin.DevicePolicySafetyChecker;
-import android.app.admin.DevicePolicyStringResource;
-import android.app.admin.FullyManagedDeviceProvisioningParams;
-import android.app.admin.IDevicePolicyManager;
-import android.app.admin.ManagedProfileProvisioningParams;
-import android.app.admin.ParcelableResource;
-import android.content.ComponentName;
-import android.os.UserHandle;
-import android.util.Slog;
-
-import com.android.server.SystemService;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Defines the required interface for IDevicePolicyManager implemenation.
- *
- * <p>The interface consists of public parts determined by {@link IDevicePolicyManager} and also
- * several package private methods required by internal infrastructure.
- *
- * <p>Whenever adding an AIDL method to {@link IDevicePolicyManager}, an empty override method
- * should be added here to avoid build breakage in downstream branches.
- */
-abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {
-
- private static final String TAG = BaseIDevicePolicyManager.class.getSimpleName();
-
- /**
- * To be called by {@link DevicePolicyManagerService#Lifecycle} during the various boot phases.
- *
- * @see {@link SystemService#onBootPhase}.
- */
- abstract void systemReady(int phase);
- /**
- * To be called by {@link DevicePolicyManagerService#Lifecycle} when a new user starts.
- *
- * @see {@link SystemService#onUserStarting}
- */
- abstract void handleStartUser(int userId);
- /**
- * To be called by {@link DevicePolicyManagerService#Lifecycle} when a user is being unlocked.
- *
- * @see {@link SystemService#onUserUnlocking}
- */
- abstract void handleUnlockUser(int userId);
- /**
- * To be called by {@link DevicePolicyManagerService#Lifecycle} after a user is being unlocked.
- *
- * @see {@link SystemService#onUserUnlocked}
- */
- abstract void handleOnUserUnlocked(int userId);
- /**
- * To be called by {@link DevicePolicyManagerService#Lifecycle} when a user is being stopped.
- *
- * @see {@link SystemService#onUserStopping}
- */
- abstract void handleStopUser(int userId);
-
- /**
- * Sets the {@link DevicePolicySafetyChecker}.
- *
- * <p>Currently, it's called only by {@code SystemServer} on
- * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE automotive builds}
- */
- public void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) {
- Slog.w(TAG, "setDevicePolicySafetyChecker() not implemented by " + getClass());
- }
-
- public void clearSystemUpdatePolicyFreezePeriodRecord() {
- }
-
- public boolean setKeyGrantForApp(ComponentName admin, String callerPackage, String alias,
- String packageName, boolean hasGrant) {
- return false;
- }
-
- public void setLocationEnabled(ComponentName who, boolean locationEnabled) {}
-
- public boolean isOrganizationOwnedDeviceWithManagedProfile() {
- return false;
- }
-
- public int getPersonalAppsSuspendedReasons(ComponentName admin) {
- return 0;
- }
-
- public void setPersonalAppsSuspended(ComponentName admin, boolean suspended) {
- }
-
- public void setManagedProfileMaximumTimeOff(ComponentName admin, long timeoutMs) {
- }
-
- public long getManagedProfileMaximumTimeOff(ComponentName admin) {
- return 0;
- }
-
- @Override
- public void acknowledgeDeviceCompliant() {}
-
- @Override
- public boolean isComplianceAcknowledgementRequired() {
- return false;
- }
-
- public boolean canProfileOwnerResetPasswordWhenLocked(int userId) {
- return false;
- }
-
- public String getEnrollmentSpecificId(String callerPackage) {
- return "";
- }
-
- public void setOrganizationIdForUser(
- @NonNull String callerPackage, @NonNull String enterpriseId, int userId) {}
-
- public UserHandle createAndProvisionManagedProfile(
- @NonNull ManagedProfileProvisioningParams provisioningParams, String callerPackage) {
- return null;
- }
-
- public void finalizeWorkProfileProvisioning(
- UserHandle managedProfileUser, Account migratedAccount) {
-
- }
-
- public void provisionFullyManagedDevice(
- FullyManagedDeviceProvisioningParams provisioningParams, String callerPackage) {
- }
-
- @Override
- public void setDeviceOwnerType(@NonNull ComponentName admin, int deviceOwnerType) {
- }
-
- @Override
- public int getDeviceOwnerType(@NonNull ComponentName admin) {
- return 0;
- }
-
- public void resetDefaultCrossProfileIntentFilters(@UserIdInt int userId) {}
-
- public boolean canAdminGrantSensorsPermissionsForUser(int userId) {
- return false;
- }
-
- @Override
- public boolean setKeyGrantToWifiAuth(String callerPackage, String alias, boolean hasGrant) {
- return false;
- }
-
- @Override
- public boolean isKeyPairGrantedToWifiAuth(String callerPackage, String alias) {
- return false;
- }
-
- @Override
- public void setDrawables(@NonNull List<DevicePolicyDrawableResource> drawables){}
-
- @Override
- public void resetDrawables(@NonNull List<String> drawableIds){}
-
- @Override
- public ParcelableResource getDrawable(
- String drawableId, String drawableStyle, String drawableSource) {
- return null;
- }
-
- @Override
- public void setStrings(@NonNull List<DevicePolicyStringResource> strings){}
-
- @Override
- public void resetStrings(@NonNull List<String> stringIds){}
-
- @Override
- public ParcelableResource getString(String stringId) {
- return null;
- }
-
- @Override
- public boolean shouldAllowBypassingDevicePolicyManagementRoleQualification() {
- return false;
- }
-
- @Override
- public List<UserHandle> getPolicyManagedProfiles(UserHandle userHandle) {
- return Collections.emptyList();
- }
-}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 0963e3b1d7d2..3470b04c9e4f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -221,6 +221,7 @@ import android.app.admin.DevicePolicyStringResource;
import android.app.admin.DeviceStateCache;
import android.app.admin.FactoryResetProtectionPolicy;
import android.app.admin.FullyManagedDeviceProvisioningParams;
+import android.app.admin.IDevicePolicyManager;
import android.app.admin.ManagedProfileProvisioningParams;
import android.app.admin.ManagedSubscriptionsPolicy;
import android.app.admin.NetworkEvent;
@@ -442,7 +443,7 @@ import java.util.stream.Collectors;
/**
* Implementation of the device policy APIs.
*/
-public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
+public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
protected static final String LOG_TAG = "DevicePolicyManager";
@@ -739,6 +740,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
private static final String KEEP_PROFILES_RUNNING_FLAG = "enable_keep_profiles_running";
private static final boolean DEFAULT_KEEP_PROFILES_RUNNING_FLAG = false;
+ private static final String ENABLE_WORK_PROFILE_TELEPHONY_FLAG =
+ "enable_work_profile_telephony";
+ private static final boolean DEFAULT_WORK_PROFILE_TELEPHONY_FLAG = false;
+
// TODO(b/261999445) remove the flag after rollout.
private static final String HEADLESS_FLAG = "headless";
private static final boolean DEFAULT_HEADLESS_FLAG = true;
@@ -920,23 +925,24 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
private final ArrayList<Object> mPendingUserCreatedCallbackTokens = new ArrayList<>();
public static final class Lifecycle extends SystemService {
- private BaseIDevicePolicyManager mService;
+ private DevicePolicyManagerService mService;
public Lifecycle(Context context) {
super(context);
String dpmsClassName = context.getResources()
.getString(R.string.config_deviceSpecificDevicePolicyManagerService);
if (TextUtils.isEmpty(dpmsClassName)) {
- dpmsClassName = DevicePolicyManagerService.class.getName();
- }
- try {
- Class<?> serviceClass = Class.forName(dpmsClassName);
- Constructor<?> constructor = serviceClass.getConstructor(Context.class);
- mService = (BaseIDevicePolicyManager) constructor.newInstance(context);
- } catch (Exception e) {
- throw new IllegalStateException(
- "Failed to instantiate DevicePolicyManagerService with class name: "
- + dpmsClassName, e);
+ mService = new DevicePolicyManagerService(context);
+ } else {
+ try {
+ Class<?> serviceClass = Class.forName(dpmsClassName);
+ Constructor<?> constructor = serviceClass.getConstructor(Context.class);
+ mService = (DevicePolicyManagerService) constructor.newInstance(context);
+ } catch (Exception e) {
+ throw new IllegalStateException(
+ "Failed to instantiate DevicePolicyManagerService with class name: "
+ + dpmsClassName, e);
+ }
}
}
@@ -1348,7 +1354,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
- @Override
public void setDevicePolicySafetyChecker(DevicePolicySafetyChecker safetyChecker) {
CallerIdentity callerIdentity = getCallerIdentity();
Preconditions.checkCallAuthorization(mIsAutomotive || isAdb(callerIdentity), "can only set "
@@ -3090,7 +3095,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
@VisibleForTesting
- @Override
void systemReady(int phase) {
if (!mHasFeature) {
return;
@@ -3100,7 +3104,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
onLockSettingsReady();
loadAdminDataAsync();
mOwners.systemReady();
- applyManagedSubscriptionsPolicyIfRequired();
+ if (isWorkProfileTelephonyFlagEnabled()) {
+ applyManagedSubscriptionsPolicyIfRequired();
+ }
break;
case SystemService.PHASE_ACTIVITY_MANAGER_READY:
synchronized (getLockObject()) {
@@ -3289,7 +3295,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
- @Override
void handleStartUser(int userId) {
synchronized (getLockObject()) {
pushScreenCapturePolicy(userId);
@@ -3337,7 +3342,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
targetUserId, protectedPackages));
}
- @Override
void handleUnlockUser(int userId) {
startOwnerService(userId, "unlock-user");
if (isCoexistenceFlagEnabled()) {
@@ -3345,12 +3349,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
- @Override
void handleOnUserUnlocked(int userId) {
showNewUserDisclaimerIfNecessary(userId);
}
- @Override
void handleStopUser(int userId) {
updateNetworkPreferenceForUser(userId, List.of(PreferentialNetworkServiceConfig.DEFAULT));
mDeviceAdminServiceController.stopServicesForUser(userId, /* actionForLog= */ "stop-user");
@@ -7018,8 +7020,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
mLockSettingsInternal.refreshStrongAuthTimeout(parentId);
- clearManagedSubscriptionsPolicy();
-
+ if (isWorkProfileTelephonyFlagEnabled()) {
+ clearManagedSubscriptionsPolicy();
+ }
Slogf.i(LOG_TAG, "Cleaning up device-wide policies done.");
}
@@ -10132,6 +10135,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
synchronized (mSubscriptionsChangedListenerLock) {
pw.println("Subscription changed listener : " + mSubscriptionsChangedListener);
}
+ pw.println(
+ "Flag enable_work_profile_telephony : " + isWorkProfileTelephonyFlagEnabled());
+
mHandler.post(() -> handleDump(pw));
dumpResources(pw);
}
@@ -20104,6 +20110,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
DEFAULT_KEEP_PROFILES_RUNNING_FLAG);
}
+ private static boolean isWorkProfileTelephonyFlagEnabled() {
+ return DeviceConfig.getBoolean(
+ NAMESPACE_DEVICE_POLICY_MANAGER,
+ ENABLE_WORK_PROFILE_TELEPHONY_FLAG,
+ DEFAULT_WORK_PROFILE_TELEPHONY_FLAG);
+ }
+
@Override
public void setMtePolicy(int flags) {
final Set<Integer> allowedModes =
@@ -20184,10 +20197,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public ManagedSubscriptionsPolicy getManagedSubscriptionsPolicy() {
- synchronized (getLockObject()) {
- ActiveAdmin admin = getProfileOwnerOfOrganizationOwnedDeviceLocked();
- if (admin != null && admin.mManagedSubscriptionsPolicy != null) {
- return admin.mManagedSubscriptionsPolicy;
+ if (isWorkProfileTelephonyFlagEnabled()) {
+ synchronized (getLockObject()) {
+ ActiveAdmin admin = getProfileOwnerOfOrganizationOwnedDeviceLocked();
+ if (admin != null && admin.mManagedSubscriptionsPolicy != null) {
+ return admin.mManagedSubscriptionsPolicy;
+ }
}
}
return new ManagedSubscriptionsPolicy(
@@ -20196,9 +20211,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public void setManagedSubscriptionsPolicy(ManagedSubscriptionsPolicy policy) {
+ if (!isWorkProfileTelephonyFlagEnabled()) {
+ throw new UnsupportedOperationException("This api is not enabled");
+ }
CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller),
- "This policy can only be set by a profile owner on an organization-owned device.");
+ "This policy can only be set by a profile owner on an organization-owned "
+ + "device.");
synchronized (getLockObject()) {
final ActiveAdmin admin = getProfileOwnerLocked(caller.getUserId());
@@ -20316,4 +20335,4 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
}
-} \ No newline at end of file
+}
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 f2cba40685e4..2a790a1c8e57 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -80,6 +80,8 @@ public final class DisplayPowerController2Test {
@Mock
private DisplayBlanker mDisplayBlankerMock;
@Mock
+ private HighBrightnessModeMetadata mHighBrightnessModeMetadataMock;
+ @Mock
private LogicalDisplay mLogicalDisplayMock;
@Mock
private DisplayDevice mDisplayDeviceMock;
@@ -169,7 +171,7 @@ public final class DisplayPowerController2Test {
mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
- });
+ }, mHighBrightnessModeMetadataMock);
when(mDisplayPowerStateMock.getScreenState()).thenReturn(Display.STATE_ON);
// send a display power request
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 4f8cb8876b3f..d99ed7877ca8 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -84,6 +84,8 @@ public final class DisplayPowerControllerTest {
@Mock
private DisplayDevice mDisplayDeviceMock;
@Mock
+ private HighBrightnessModeMetadata mHighBrightnessModeMetadataMock;
+ @Mock
private BrightnessTracker mBrightnessTrackerMock;
@Mock
private BrightnessSetting mBrightnessSettingMock;
@@ -151,7 +153,7 @@ public final class DisplayPowerControllerTest {
mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
- });
+ }, mHighBrightnessModeMetadataMock);
when(mDisplayPowerStateMock.getScreenState()).thenReturn(Display.STATE_ON);
// send a display power request
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 4998a6c20e63..60483f11a479 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -134,6 +134,7 @@ import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.platform.test.annotations.Presubmit;
+import android.provider.DeviceConfig;
import android.provider.Settings;
import android.security.KeyChain;
import android.security.keystore.AttestationUtils;
@@ -259,6 +260,8 @@ public class DevicePolicyManagerTest extends DpmTestBase {
private static final String PROFILE_OFF_SUSPENSION_TITLE = "suspension_title";
private static final String PROFILE_OFF_SUSPENSION_TEXT = "suspension_text";
private static final String PROFILE_OFF_SUSPENSION_SOON_TEXT = "suspension_tomorrow_text";
+ private static final String FLAG_ENABLE_WORK_PROFILE_TELEPHONY =
+ "enable_work_profile_telephony";
@Before
public void setUp() throws Exception {
@@ -4982,7 +4985,8 @@ public class DevicePolicyManagerTest extends DpmTestBase {
public void testWipeDataManagedProfileOnOrganizationOwnedDevice() throws Exception {
setupProfileOwner();
configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
-
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
+ FLAG_ENABLE_WORK_PROFILE_TELEPHONY, "true", false);
// Even if the caller is the managed profile, the current user is the user 0
when(getServices().iactivityManager.getCurrentUser())
.thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
@@ -5043,6 +5047,8 @@ public class DevicePolicyManagerTest extends DpmTestBase {
verify(getServices().packageManagerInternal)
.unsuspendForSuspendingPackage(PLATFORM_PACKAGE_NAME, UserHandle.USER_SYSTEM);
verify(getServices().subscriptionManager).setSubscriptionUserHandle(0, null);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
+ FLAG_ENABLE_WORK_PROFILE_TELEPHONY, "false", false);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/display/HbmEventTest.java b/services/tests/servicestests/src/com/android/server/display/HbmEventTest.java
new file mode 100644
index 000000000000..24fc34849829
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/HbmEventTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import static org.junit.Assert.assertEquals;
+
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class HbmEventTest {
+ private long mStartTimeMillis;
+ private long mEndTimeMillis;
+ private HbmEvent mHbmEvent;
+
+ @Before
+ public void setUp() {
+ mStartTimeMillis = 10;
+ mEndTimeMillis = 20;
+ mHbmEvent = new HbmEvent(mStartTimeMillis, mEndTimeMillis);
+ }
+
+ @Test
+ public void getCorrectValues() {
+ assertEquals(mHbmEvent.getStartTimeMillis(), mStartTimeMillis);
+ assertEquals(mHbmEvent.getEndTimeMillis(), mEndTimeMillis);
+ }
+
+ @Test
+ public void toStringGeneratesExpectedString() {
+ String actualString = mHbmEvent.toString();
+ String expectedString = "HbmEvent: {startTimeMillis:" + mStartTimeMillis
+ + ", endTimeMillis: " + mEndTimeMillis + "}, total: "
+ + ((mEndTimeMillis - mStartTimeMillis) / 1000) + "]";
+ assertEquals(actualString, expectedString);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
index a1e5ce74014b..2655c3f05809 100644
--- a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java
@@ -96,6 +96,7 @@ public class HighBrightnessModeControllerTest {
private Binder mDisplayToken;
private String mDisplayUniqueId;
private Context mContextSpy;
+ private HighBrightnessModeMetadata mHighBrightnessModeMetadata;
@Rule
public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
@@ -118,6 +119,7 @@ public class HighBrightnessModeControllerTest {
mTestLooper = new TestLooper(mClock::now);
mDisplayToken = null;
mDisplayUniqueId = "unique_id";
+
mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
when(mContextSpy.getContentResolver()).thenReturn(resolver);
@@ -134,7 +136,8 @@ public class HighBrightnessModeControllerTest {
initHandler(null);
final HighBrightnessModeController hbmc = new HighBrightnessModeController(
mInjectorMock, mHandler, DISPLAY_WIDTH, DISPLAY_HEIGHT, mDisplayToken,
- mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, null, null, () -> {}, mContextSpy);
+ mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, null, null, () -> {},
+ null, mContextSpy);
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
assertEquals(hbmc.getTransitionPoint(), HBM_TRANSITION_POINT_INVALID, 0.0f);
}
@@ -144,7 +147,8 @@ public class HighBrightnessModeControllerTest {
initHandler(null);
final HighBrightnessModeController hbmc = new HighBrightnessModeController(
mInjectorMock, mHandler, DISPLAY_WIDTH, DISPLAY_HEIGHT, mDisplayToken,
- mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, null, null, () -> {}, mContextSpy);
+ mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, null, null, () -> {},
+ null, mContextSpy);
hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED);
hbmc.onAmbientLuxChange(MINIMUM_LUX - 1); // below allowed range
assertState(hbmc, DEFAULT_MIN, DEFAULT_MAX, HIGH_BRIGHTNESS_MODE_OFF);
@@ -699,9 +703,12 @@ public class HighBrightnessModeControllerTest {
// Creates instance with standard initialization values.
private HighBrightnessModeController createDefaultHbm(OffsettableClock clock) {
initHandler(clock);
+ if (mHighBrightnessModeMetadata == null) {
+ mHighBrightnessModeMetadata = new HighBrightnessModeMetadata();
+ }
return new HighBrightnessModeController(mInjectorMock, mHandler, DISPLAY_WIDTH,
DISPLAY_HEIGHT, mDisplayToken, mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX,
- DEFAULT_HBM_DATA, null, () -> {}, mContextSpy);
+ DEFAULT_HBM_DATA, null, () -> {}, mHighBrightnessModeMetadata, mContextSpy);
}
private void initHandler(OffsettableClock clock) {
diff --git a/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeMetadataTest.java b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeMetadataTest.java
new file mode 100644
index 000000000000..ede54e096ad0
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/HighBrightnessModeMetadataTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class HighBrightnessModeMetadataTest {
+ private HighBrightnessModeMetadata mHighBrightnessModeMetadata;
+
+ private long mRunningStartTimeMillis = -1;
+
+ @Before
+ public void setUp() {
+ mHighBrightnessModeMetadata = new HighBrightnessModeMetadata();
+ }
+
+ @Test
+ public void checkDefaultValues() {
+ assertEquals(mHighBrightnessModeMetadata.getRunningStartTimeMillis(),
+ mRunningStartTimeMillis);
+ assertEquals(mHighBrightnessModeMetadata.getHbmEventQueue().size(), 0);
+ }
+
+ @Test
+ public void checkSetValues() {
+ mRunningStartTimeMillis = 10;
+ mHighBrightnessModeMetadata.setRunningStartTimeMillis(mRunningStartTimeMillis);
+ assertEquals(mHighBrightnessModeMetadata.getRunningStartTimeMillis(),
+ mRunningStartTimeMillis);
+ HbmEvent expectedHbmEvent = new HbmEvent(10, 20);
+ mHighBrightnessModeMetadata.addHbmEvent(expectedHbmEvent);
+ HbmEvent actualHbmEvent = mHighBrightnessModeMetadata.getHbmEventQueue().peekFirst();
+ assertEquals(expectedHbmEvent.toString(), actualHbmEvent.toString());
+ }
+}