diff options
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()); + } +} |