diff options
37 files changed, 1166 insertions, 767 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index d1d798346c97..5721bdf50fa7 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -53897,6 +53897,7 @@ package android.view { field public static final String PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH = "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH"; field public static final String PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE = "android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE"; field public static final String PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE = "android.window.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE"; + field @FlaggedApi("com.android.window.flags.app_compat_properties_api") public static final String PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE = "android.window.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE"; field public static final String PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE = "android.window.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE"; field public static final String PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS = "android.window.PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS"; field public static final String PROPERTY_COMPAT_ENABLE_FAKE_FOCUS = "android.window.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS"; diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 820ff3e308e4..be420debc88f 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -77,6 +77,7 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.StrictMode; import android.os.SystemProperties; +import android.os.Trace; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; @@ -91,7 +92,6 @@ import com.android.internal.R; import libcore.io.IoUtils; import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -614,11 +614,14 @@ public class WallpaperManager { ColorManagementProxy cmProxy) { if (mService != null) { try { + Trace.beginSection("WPMS.isWallpaperSupported"); if (!mService.isWallpaperSupported(context.getOpPackageName())) { return null; } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); + } finally { + Trace.endSection(); } } synchronized (this) { @@ -629,6 +632,7 @@ public class WallpaperManager { mCachedWallpaper = null; Bitmap currentWallpaper = null; try { + Trace.beginSection("WPMS.getCurrentWallpaperLocked"); currentWallpaper = getCurrentWallpaperLocked( context, which, userId, hardware, cmProxy); } catch (OutOfMemoryError e) { @@ -654,6 +658,8 @@ public class WallpaperManager { // Post-O apps really most sincerely need the permission. throw e; } + } finally { + Trace.endSection(); } if (currentWallpaper != null) { mCachedWallpaper = new CachedWallpaper(currentWallpaper, userId, which); @@ -732,19 +738,15 @@ public class WallpaperManager { try { Bundle params = new Bundle(); + Trace.beginSection("WPMS.getWallpaperWithFeature_" + which); ParcelFileDescriptor pfd = mService.getWallpaperWithFeature( context.getOpPackageName(), context.getAttributionTag(), this, which, params, userId, /* getCropped = */ true); + Trace.endSection(); if (pfd != null) { - try (BufferedInputStream bis = new BufferedInputStream( - new ParcelFileDescriptor.AutoCloseInputStream(pfd))) { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int data; - while ((data = bis.read()) != -1) { - baos.write(data); - } - ImageDecoder.Source src = ImageDecoder.createSource(baos.toByteArray()); + try (InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) { + ImageDecoder.Source src = ImageDecoder.createSource(is.readAllBytes()); return ImageDecoder.decodeBitmap(src, ((decoder, info, source) -> { // Mutable and hardware config can't be set at the same time. decoder.setMutableRequired(!hardware); @@ -764,13 +766,18 @@ public class WallpaperManager { } private Bitmap getDefaultWallpaper(Context context, @SetWallpaperFlags int which) { + Trace.beginSection("WPMS.getDefaultWallpaper_" + which); Bitmap defaultWallpaper = mDefaultWallpaper; if (defaultWallpaper == null || defaultWallpaper.isRecycled()) { defaultWallpaper = null; + Trace.beginSection("WPMS.openDefaultWallpaper"); try (InputStream is = openDefaultWallpaper(context, which)) { + Trace.endSection(); if (is != null) { BitmapFactory.Options options = new BitmapFactory.Options(); + Trace.beginSection("WPMS.decodeStream"); defaultWallpaper = BitmapFactory.decodeStream(is, null, options); + Trace.endSection(); } } catch (OutOfMemoryError | IOException e) { Log.w(TAG, "Can't decode stream", e); @@ -779,6 +786,7 @@ public class WallpaperManager { synchronized (this) { mDefaultWallpaper = defaultWallpaper; } + Trace.endSection(); return defaultWallpaper; } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 290ae4ac0e55..4af657dab0cd 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7330,7 +7330,7 @@ public final class Settings { "hearing_aid_media_routing"; /** - * System sounds routing value for hearing aid. It routes system sounds to hearing aid + * Notification routing value for hearing aid. It routes notification sounds to hearing aid * or device speaker. * <ul> * <li> 0 = Default @@ -7339,8 +7339,8 @@ public final class Settings { * </ul> * @hide */ - public static final String HEARING_AID_SYSTEM_SOUNDS_ROUTING = - "hearing_aid_system_sounds_routing"; + public static final String HEARING_AID_NOTIFICATION_ROUTING = + "hearing_aid_notification_routing"; /** * Setting to indicate that on device captions are enabled. diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index e3d9c605ff63..1712fd3c3323 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -122,7 +122,6 @@ import android.view.WindowInsets.Side.InsetsSide; import android.view.WindowInsets.Type; import android.view.WindowInsets.Type.InsetsType; import android.view.accessibility.AccessibilityNodeInfo; -import android.window.ITrustedPresentationListener; import android.window.TaskFpsCallback; import android.window.TrustedPresentationThresholds; @@ -1280,9 +1279,8 @@ public interface WindowManager extends ViewManager { * android:value="true|false"/> * </application> * </pre> - * @hide */ - // TODO(b/279428317): Make this public API. + @FlaggedApi(Flags.FLAG_APP_COMPAT_PROPERTIES_API) String PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE = "android.window.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE"; diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto index 9ca1849dedc2..104c023f550d 100644 --- a/core/proto/android/providers/settings/secure.proto +++ b/core/proto/android/providers/settings/secure.proto @@ -93,7 +93,7 @@ message SecureSettingsProto { optional SettingProto hearing_aid_ringtone_routing = 46 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto hearing_aid_call_routing = 47 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto hearing_aid_media_routing = 48 [ (android.privacy).dest = DEST_AUTOMATIC ]; - optional SettingProto hearing_aid_system_sounds_routing = 49 [ (android.privacy).dest = DEST_AUTOMATIC ]; + optional SettingProto hearing_aid_notification_routing = 49 [ (android.privacy).dest = DEST_AUTOMATIC ]; optional SettingProto accessibility_magnification_joystick_enabled = 50 [ (android.privacy).dest = DEST_AUTOMATIC ]; // Settings for font scaling optional SettingProto accessibility_font_scaling_has_been_changed = 51 [ (android.privacy).dest = DEST_AUTOMATIC ]; diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto index 404fa39fb6ed..382a82cd090e 100644 --- a/core/proto/android/server/windowmanagerservice.proto +++ b/core/proto/android/server/windowmanagerservice.proto @@ -394,6 +394,7 @@ message ActivityRecordProto { optional bool should_force_rotate_for_camera_compat = 39; optional bool should_refresh_activity_for_camera_compat = 40; optional bool should_refresh_activity_via_pause_for_camera_compat = 41; + optional bool should_override_min_aspect_ratio = 42; } /* represents WindowToken */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEducationController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEducationController.kt index e57f02c71e44..bd4708259b50 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEducationController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEducationController.kt @@ -40,7 +40,13 @@ class BubbleEducationController(private val context: Context) { /** Whether education view should show for the collapsed stack. */ fun shouldShowStackEducation(bubble: BubbleViewProvider?): Boolean { - val shouldShow = bubble != null && + if (BubbleDebugConfig.neverShowUserEducation(context)) { + logDebug("Show stack edu: never") + return false + } + + val shouldShow = + bubble != null && bubble.isConversationBubble && // show education for conversation bubbles only (!hasSeenStackEducation || BubbleDebugConfig.forceShowUserEducation(context)) logDebug("Show stack edu: $shouldShow") @@ -49,7 +55,13 @@ class BubbleEducationController(private val context: Context) { /** Whether the educational view should show for the expanded view "manage" menu. */ fun shouldShowManageEducation(bubble: BubbleViewProvider?): Boolean { - val shouldShow = bubble != null && + if (BubbleDebugConfig.neverShowUserEducation(context)) { + logDebug("Show manage edu: never") + return false + } + + val shouldShow = + bubble != null && bubble.isConversationBubble && // show education for conversation bubbles only (!hasSeenManageEducation || BubbleDebugConfig.forceShowUserEducation(context)) logDebug("Show manage edu: $shouldShow") diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingConstants.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingConstants.java index d8475b3f22af..ca0cad759a08 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingConstants.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingConstants.java @@ -39,21 +39,22 @@ public final class HearingAidAudioRoutingConstants { public static final int[] MEDIA_ROUTING_ATTRIBUTES = new int[] { // Stands for STRATEGY_MEDIA, including USAGE_GAME, USAGE_ASSISTANT, // USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, USAGE_ASSISTANCE_SONIFICATION - AudioAttributes.USAGE_MEDIA + AudioAttributes.USAGE_MEDIA, + // Stands for STRATEGY_ACCESSIBILITY + AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY, + // Stands for STRATEGY_DTMF + AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING, }; - public static final int[] RINGTONE_ROUTING_ATTRIBUTE = new int[] { + public static final int[] RINGTONE_ROUTING_ATTRIBUTES = new int[] { // Stands for STRATEGY_SONIFICATION, including USAGE_ALARM AudioAttributes.USAGE_NOTIFICATION_RINGTONE }; - public static final int[] SYSTEM_SOUNDS_ROUTING_ATTRIBUTES = new int[] { + public static final int[] NOTIFICATION_ROUTING_ATTRIBUTES = new int[] { // Stands for STRATEGY_SONIFICATION_RESPECTFUL, including USAGE_NOTIFICATION_EVENT AudioAttributes.USAGE_NOTIFICATION, - // Stands for STRATEGY_ACCESSIBILITY - AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY, - // Stands for STRATEGY_DTMF - AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING, + }; @Retention(RetentionPolicy.SOURCE) diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java index 111a2c1a07ea..3a15b7108e3f 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java @@ -26,6 +26,7 @@ import android.media.AudioDeviceAttributes; import android.media.audiopolicy.AudioProductStrategy; import android.os.ParcelUuid; import android.provider.Settings; +import android.util.FeatureFlagUtils; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; @@ -42,11 +43,13 @@ public class HearingAidDeviceManager { private static final boolean DEBUG = BluetoothUtils.D; private final ContentResolver mContentResolver; + private final Context mContext; private final LocalBluetoothManager mBtManager; private final List<CachedBluetoothDevice> mCachedDevices; private final HearingAidAudioRoutingHelper mRoutingHelper; HearingAidDeviceManager(Context context, LocalBluetoothManager localBtManager, List<CachedBluetoothDevice> CachedDevices) { + mContext = context; mContentResolver = context.getContentResolver(); mBtManager = localBtManager; mCachedDevices = CachedDevices; @@ -56,6 +59,7 @@ public class HearingAidDeviceManager { @VisibleForTesting HearingAidDeviceManager(Context context, LocalBluetoothManager localBtManager, List<CachedBluetoothDevice> cachedDevices, HearingAidAudioRoutingHelper routingHelper) { + mContext = context; mContentResolver = context.getContentResolver(); mBtManager = localBtManager; mCachedDevices = cachedDevices; @@ -285,11 +289,13 @@ public class HearingAidDeviceManager { } void onActiveDeviceChanged(CachedBluetoothDevice device) { - if (device.isActiveDevice(BluetoothProfile.HEARING_AID) || device.isActiveDevice( - BluetoothProfile.LE_AUDIO)) { - setAudioRoutingConfig(device); - } else { - clearAudioRoutingConfig(); + if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_AUDIO_ROUTING)) { + if (device.isActiveDevice(BluetoothProfile.HEARING_AID) || device.isActiveDevice( + BluetoothProfile.LE_AUDIO)) { + setAudioRoutingConfig(device); + } else { + clearAudioRoutingConfig(); + } } } @@ -312,7 +318,7 @@ public class HearingAidDeviceManager { Settings.Secure.HEARING_AID_RINGTONE_ROUTING, HearingAidAudioRoutingConstants.RoutingValue.AUTO); final int systemSoundsRoutingValue = Settings.Secure.getInt(mContentResolver, - Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING, + Settings.Secure.HEARING_AID_NOTIFICATION_ROUTING, HearingAidAudioRoutingConstants.RoutingValue.AUTO); setPreferredDeviceRoutingStrategies( @@ -322,10 +328,10 @@ public class HearingAidDeviceManager { HearingAidAudioRoutingConstants.MEDIA_ROUTING_ATTRIBUTES, hearingDeviceAttributes, mediaRoutingValue); setPreferredDeviceRoutingStrategies( - HearingAidAudioRoutingConstants.RINGTONE_ROUTING_ATTRIBUTE, + HearingAidAudioRoutingConstants.RINGTONE_ROUTING_ATTRIBUTES, hearingDeviceAttributes, ringtoneRoutingValue); setPreferredDeviceRoutingStrategies( - HearingAidAudioRoutingConstants.SYSTEM_SOUNDS_ROUTING_ATTRIBUTES, + HearingAidAudioRoutingConstants.NOTIFICATION_ROUTING_ATTRIBUTES, hearingDeviceAttributes, systemSoundsRoutingValue); } @@ -338,10 +344,10 @@ public class HearingAidDeviceManager { HearingAidAudioRoutingConstants.MEDIA_ROUTING_ATTRIBUTES, /* hearingDevice = */ null, HearingAidAudioRoutingConstants.RoutingValue.AUTO); setPreferredDeviceRoutingStrategies( - HearingAidAudioRoutingConstants.RINGTONE_ROUTING_ATTRIBUTE, + HearingAidAudioRoutingConstants.RINGTONE_ROUTING_ATTRIBUTES, /* hearingDevice = */ null, HearingAidAudioRoutingConstants.RoutingValue.AUTO); setPreferredDeviceRoutingStrategies( - HearingAidAudioRoutingConstants.SYSTEM_SOUNDS_ROUTING_ATTRIBUTES, + HearingAidAudioRoutingConstants.NOTIFICATION_ROUTING_ATTRIBUTES, /* hearingDevice = */ null, HearingAidAudioRoutingConstants.RoutingValue.AUTO); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java index ea10944be0e9..24fd06e51418 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java @@ -42,6 +42,7 @@ import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.media.audiopolicy.AudioProductStrategy; import android.os.Parcel; +import android.util.FeatureFlagUtils; import androidx.test.core.app.ApplicationProvider; @@ -109,6 +110,7 @@ public class HearingAidDeviceManagerTest { @Before public void setUp() { + FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_AUDIO_ROUTING, true); when(mDevice1.getAddress()).thenReturn(DEVICE_ADDRESS_1); when(mDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2); when(mDevice1.getName()).thenReturn(DEVICE_NAME_1); diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index 2167a8ad8fdb..5004f251cfd3 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -247,7 +247,7 @@ public class SecureSettings { Settings.Secure.HEARING_AID_RINGTONE_ROUTING, Settings.Secure.HEARING_AID_CALL_ROUTING, Settings.Secure.HEARING_AID_MEDIA_ROUTING, - Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING, + Settings.Secure.HEARING_AID_NOTIFICATION_ROUTING, Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED, Settings.Secure.SEARCH_PRESS_HOLD_NAV_HANDLE_ENABLED, Settings.Secure.SEARCH_LONG_PRESS_HOME_ENABLED, diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index 868623f5c537..0b0e182746e5 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -396,7 +396,7 @@ public class SecureSettingsValidators { new DiscreteValueValidator(new String[] {"0", "1", "2"})); VALIDATORS.put(Secure.HEARING_AID_MEDIA_ROUTING, new DiscreteValueValidator(new String[] {"0", "1", "2"})); - VALIDATORS.put(Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING, + VALIDATORS.put(Secure.HEARING_AID_NOTIFICATION_ROUTING, new DiscreteValueValidator(new String[] {"0", "1", "2"})); VALIDATORS.put(Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_EDGE_HAPTIC_ENABLED, diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index 5afcd5db1b5f..1670a705f939 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -1866,8 +1866,8 @@ class SettingsProtoDumpUtil { Settings.Secure.HEARING_AID_MEDIA_ROUTING, SecureSettingsProto.Accessibility.HEARING_AID_MEDIA_ROUTING); dumpSetting(s, p, - Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING, - SecureSettingsProto.Accessibility.HEARING_AID_SYSTEM_SOUNDS_ROUTING); + Settings.Secure.HEARING_AID_NOTIFICATION_ROUTING, + SecureSettingsProto.Accessibility.HEARING_AID_NOTIFICATION_ROUTING); dumpSetting(s, p, Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED, SecureSettingsProto.Accessibility.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED); diff --git a/packages/SystemUI/proguard_common.flags b/packages/SystemUI/proguard_common.flags index 21b019eacdcc..f9546c46e915 100644 --- a/packages/SystemUI/proguard_common.flags +++ b/packages/SystemUI/proguard_common.flags @@ -38,6 +38,11 @@ -keepnames class com.android.internal.protolog.** { *; } -keepnames class android.hardware.common.** { *; } +# TODO(b/316553881): Statically linking flags into SystemUI and bootclasspath might not be a +# good idea in the first place +-keepnames class com.android.window.flags.Flags { public *; } + + # Allows proguard to make private and protected methods and fields public as # part of optimization. This lets proguard inline trivial getter/setter methods. -allowaccessmodification diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 33a0a06e940c..deed6c8c7f25 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -543,12 +543,16 @@ <!-- ID for the camera of outer display that needs extra protection --> <string translatable="false" name="config_protectedCameraId"></string> + <!-- Physical ID for the camera of outer display that needs extra protection --> + <string translatable="false" name="config_protectedPhysicalCameraId"></string> <!-- Similar to config_frontBuiltInDisplayCutoutProtection but for inner display. --> <string translatable="false" name="config_innerBuiltInDisplayCutoutProtection"></string> <!-- ID for the camera of inner display that needs extra protection --> <string translatable="false" name="config_protectedInnerCameraId"></string> + <!-- Physical ID for the camera of inner display that needs extra protection --> + <string translatable="false" name="config_protectedInnerPhysicalCameraId"></string> <!-- Comma-separated list of packages to exclude from camera protection e.g. "com.android.systemui,com.android.xyz" --> diff --git a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt index d33d279023da..5f5cca86cce6 100644 --- a/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt +++ b/packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt @@ -38,26 +38,75 @@ class CameraAvailabilityListener( excludedPackages: String, private val executor: Executor ) { + private var activeProtectionInfo: CameraProtectionInfo? = null + private var openCamera: OpenCameraInfo? = null + private val unavailablePhysicalCameras = mutableSetOf<String>() private val excludedPackageIds: Set<String> private val listeners = mutableListOf<CameraTransitionCallback>() private val availabilityCallback: CameraManager.AvailabilityCallback = - object : CameraManager.AvailabilityCallback() { - override fun onCameraClosed(cameraId: String) { - cameraProtectionInfoList.forEach { - if (cameraId == it.cameraId) { - notifyCameraInactive() - } + object : CameraManager.AvailabilityCallback() { + override fun onCameraClosed(logicalCameraId: String) { + openCamera = null + if (activeProtectionInfo?.logicalCameraId == logicalCameraId) { + notifyCameraInactive() + } + activeProtectionInfo = null + } + + override fun onCameraOpened(logicalCameraId: String, packageId: String) { + openCamera = OpenCameraInfo(logicalCameraId, packageId) + if (isExcluded(packageId)) { + return + } + val protectionInfo = + cameraProtectionInfoList.firstOrNull { + logicalCameraId == it.logicalCameraId && + it.physicalCameraId !in unavailablePhysicalCameras } + if (protectionInfo != null) { + activeProtectionInfo = protectionInfo + notifyCameraActive(protectionInfo) } + } - override fun onCameraOpened(cameraId: String, packageId: String) { - cameraProtectionInfoList.forEach { - if (cameraId == it.cameraId && !isExcluded(packageId)) { - notifyCameraActive(it) - } + override fun onPhysicalCameraAvailable( + logicalCameraId: String, + physicalCameraId: String + ) { + unavailablePhysicalCameras -= physicalCameraId + val openCamera = this@CameraAvailabilityListener.openCamera ?: return + if (openCamera.logicalCameraId != logicalCameraId) { + return + } + if (isExcluded(openCamera.packageId)) { + return + } + val newActiveInfo = + cameraProtectionInfoList.find { + it.logicalCameraId == logicalCameraId && + it.physicalCameraId == physicalCameraId } + if (newActiveInfo != null) { + activeProtectionInfo = newActiveInfo + notifyCameraActive(newActiveInfo) } - } + } + + override fun onPhysicalCameraUnavailable( + logicalCameraId: String, + physicalCameraId: String + ) { + unavailablePhysicalCameras += physicalCameraId + val activeInfo = activeProtectionInfo ?: return + if ( + activeInfo.logicalCameraId == logicalCameraId && + activeInfo.physicalCameraId == physicalCameraId + ) { + activeProtectionInfo = null + notifyCameraInactive() + } + } + } init { excludedPackageIds = excludedPackages.split(",").toSet() @@ -106,24 +155,21 @@ class CameraAvailabilityListener( listeners.forEach { it.onHideCameraProtection() } } - /** - * Callbacks to tell a listener that a relevant camera turned on and off. - */ + /** Callbacks to tell a listener that a relevant camera turned on and off. */ interface CameraTransitionCallback { fun onApplyCameraProtection(protectionPath: Path, bounds: Rect) + fun onHideCameraProtection() } companion object Factory { fun build(context: Context, executor: Executor): CameraAvailabilityListener { - val manager = context - .getSystemService(Context.CAMERA_SERVICE) as CameraManager + val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager val res = context.resources val cameraProtectionInfoList = loadCameraProtectionInfoList(res) val excluded = res.getString(R.string.config_cameraProtectionExcludedPackages) - return CameraAvailabilityListener( - manager, cameraProtectionInfoList, excluded, executor) + return CameraAvailabilityListener(manager, cameraProtectionInfoList, excluded, executor) } private fun pathFromString(pathString: String): Path { @@ -140,19 +186,23 @@ class CameraAvailabilityListener( private fun loadCameraProtectionInfoList(res: Resources): List<CameraProtectionInfo> { val list = mutableListOf<CameraProtectionInfo>() - val front = loadCameraProtectionInfo( + val front = + loadCameraProtectionInfo( res, R.string.config_protectedCameraId, + R.string.config_protectedPhysicalCameraId, R.string.config_frontBuiltInDisplayCutoutProtection - ) + ) if (front != null) { list.add(front) } - val inner = loadCameraProtectionInfo( + val inner = + loadCameraProtectionInfo( res, R.string.config_protectedInnerCameraId, + R.string.config_protectedInnerPhysicalCameraId, R.string.config_innerBuiltInDisplayCutoutProtection - ) + ) if (inner != null) { list.add(inner) } @@ -160,30 +210,44 @@ class CameraAvailabilityListener( } private fun loadCameraProtectionInfo( - res: Resources, - cameraIdRes: Int, - pathRes: Int + res: Resources, + cameraIdRes: Int, + physicalCameraIdRes: Int, + pathRes: Int ): CameraProtectionInfo? { - val cameraId = res.getString(cameraIdRes) - if (cameraId == null || cameraId.isEmpty()) { + val logicalCameraId = res.getString(cameraIdRes) + if (logicalCameraId.isNullOrEmpty()) { return null } + val physicalCameraId = res.getString(physicalCameraIdRes) val protectionPath = pathFromString(res.getString(pathRes)) val computed = RectF() protectionPath.computeBounds(computed) - val protectionBounds = Rect( + val protectionBounds = + Rect( computed.left.roundToInt(), computed.top.roundToInt(), computed.right.roundToInt(), computed.bottom.roundToInt() + ) + return CameraProtectionInfo( + logicalCameraId, + physicalCameraId, + protectionPath, + protectionBounds ) - return CameraProtectionInfo(cameraId, protectionPath, protectionBounds) } } - data class CameraProtectionInfo ( - val cameraId: String, - val cutoutProtectionPath: Path, - val cutoutBounds: Rect + data class CameraProtectionInfo( + val logicalCameraId: String, + val physicalCameraId: String?, + val cutoutProtectionPath: Path, + val cutoutBounds: Rect, + ) + + private data class OpenCameraInfo( + val logicalCameraId: String, + val packageId: String, ) } diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 6faee8cd1c4f..008de4387c4a 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -179,6 +179,7 @@ public class ScreenDecorations implements CoreStartable, Dumpable { @VisibleForTesting protected DisplayInfo mDisplayInfo = new DisplayInfo(); private DisplayCutout mDisplayCutout; + private boolean mPendingManualConfigUpdate; @VisibleForTesting protected void showCameraProtection(@NonNull Path protectionPath, @NonNull Rect bounds) { @@ -571,6 +572,11 @@ public class ScreenDecorations implements CoreStartable, Dumpable { setupDecorations(); return; } + + if (mPendingManualConfigUpdate) { + mPendingManualConfigUpdate = false; + onConfigurationChanged(mContext.getResources().getConfiguration()); + } } } }; @@ -1064,6 +1070,15 @@ public class ScreenDecorations implements CoreStartable, Dumpable { mExecutor.execute(() -> { Trace.beginSection("ScreenDecorations#onConfigurationChanged"); + mContext.getDisplay().getDisplayInfo(mDisplayInfo); + if (displaySizeChanged(mDisplaySize, mDisplayInfo)) { + // We expect the display change event to happen first, but in this case, we received + // onConfigurationChanged first. + // Return so that we handle the display change event first, and then manually + // trigger the config update. + mPendingManualConfigUpdate = true; + return; + } int oldRotation = mRotation; mPendingConfigChange = false; updateConfiguration(); diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java index 45433e62f214..3de9e68909cf 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java @@ -1054,6 +1054,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene return; } Trace.instantForTrack(Trace.TRACE_TAG_APP, "bugreport", "BugReportAction#onPress"); + Log.d(TAG, "BugReportAction#onPress"); // Add a little delay before executing, to give the // dialog a chance to go away before it takes a // screenshot. @@ -1069,6 +1070,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene Log.w(TAG, "Bugreport handler could not be launched"); Trace.instantForTrack(Trace.TRACE_TAG_APP, "bugreport", "BugReportAction#requestingInteractiveBugReport"); + Log.d(TAG, "BugReportAction#requestingInteractiveBugReport"); mIActivityManager.requestInteractiveBugReport(); } } catch (RemoteException e) { @@ -1090,6 +1092,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene mUiEventLogger.log(GlobalActionsEvent.GA_BUGREPORT_LONG_PRESS); Trace.instantForTrack(Trace.TRACE_TAG_APP, "bugreport", "BugReportAction#requestingFullBugReport"); + Log.d(TAG, "BugReportAction#requestingFullBugReport"); mIActivityManager.requestFullBugReport(); } catch (RemoteException e) { } diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java index 789a1e401ae6..e08eb37b79ba 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java @@ -66,7 +66,8 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public class TileLifecycleManager extends BroadcastReceiver implements IQSTileService, ServiceConnection, IBinder.DeathRecipient { - public static final boolean DEBUG = false; + + private final boolean mDebug = Log.isLoggable(TAG, Log.DEBUG); private static final String TAG = "TileLifecycleManager"; @@ -101,7 +102,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements private Set<Integer> mQueuedMessages = new ArraySet<>(); @Nullable - private QSTileServiceWrapper mWrapper; + private volatile QSTileServiceWrapper mWrapper; private boolean mListening; private IBinder mClickBinder; @@ -132,7 +133,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements mPackageManagerAdapter = packageManagerAdapter; mBroadcastDispatcher = broadcastDispatcher; mActivityManager = activityManager; - if (DEBUG) Log.d(TAG, "Creating " + mIntent + " " + mUser); + if (mDebug) Log.d(TAG, "Creating " + mIntent + " " + mUser); } /** Injectable factory for TileLifecycleManager. */ @@ -215,10 +216,11 @@ public class TileLifecycleManager extends BroadcastReceiver implements if (!checkComponentState()) { return; } - if (DEBUG) Log.d(TAG, "Binding service " + mIntent + " " + mUser); + if (mDebug) Log.d(TAG, "Binding service " + mIntent + " " + mUser); mBindTryCount++; try { - mIsBound.set(bindServices()); + // Only try a new binding if we are not currently bound. + mIsBound.compareAndSet(false, bindServices()); if (!mIsBound.get()) { mContext.unbindService(this); } @@ -227,19 +229,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements mIsBound.set(false); } } else { - if (DEBUG) Log.d(TAG, "Unbinding service " + mIntent + " " + mUser); - // Give it another chance next time it needs to be bound, out of kindness. - mBindTryCount = 0; - freeWrapper(); - if (mIsBound.get()) { - try { - mContext.unbindService(this); - } catch (Exception e) { - Log.e(TAG, "Failed to unbind service " - + mIntent.getComponent().flattenToShortString(), e); - } - mIsBound.set(false); - } + unbindService(); } } @@ -264,9 +254,26 @@ public class TileLifecycleManager extends BroadcastReceiver implements mUser); } + @WorkerThread + private void unbindService() { + if (mDebug) Log.d(TAG, "Unbinding service " + mIntent + " " + mUser); + // Give it another chance next time it needs to be bound, out of kindness. + mBindTryCount = 0; + freeWrapper(); + if (mIsBound.get()) { + try { + mContext.unbindService(this); + } catch (Exception e) { + Log.e(TAG, "Failed to unbind service " + + mIntent.getComponent().flattenToShortString(), e); + } + mIsBound.set(false); + } + } + @Override public void onServiceConnected(ComponentName name, IBinder service) { - if (DEBUG) Log.d(TAG, "onServiceConnected " + name); + if (mDebug) Log.d(TAG, "onServiceConnected " + name); // Got a connection, set the binding count to 0. mBindTryCount = 0; final QSTileServiceWrapper wrapper = new QSTileServiceWrapper(Stub.asInterface(service)); @@ -284,11 +291,17 @@ public class TileLifecycleManager extends BroadcastReceiver implements } @Override - public void onServiceDisconnected(ComponentName name) { - if (DEBUG) Log.d(TAG, "onServiceDisconnected " + name); + public void onBindingDied(ComponentName name) { + if (mDebug) Log.d(TAG, "onBindingDied " + name); handleDeath(); } + @Override + public void onServiceDisconnected(ComponentName name) { + if (mDebug) Log.d(TAG, "onServiceDisconnected " + name); + freeWrapper(); + } + private void handlePendingMessages() { // This ordering is laid out manually to make sure we preserve the TileService // lifecycle. @@ -298,35 +311,36 @@ public class TileLifecycleManager extends BroadcastReceiver implements mQueuedMessages.clear(); } if (queue.contains(MSG_ON_ADDED)) { - if (DEBUG) Log.d(TAG, "Handling pending onAdded"); + if (mDebug) Log.d(TAG, "Handling pending onAdded " + getComponent()); onTileAdded(); } if (mListening) { - if (DEBUG) Log.d(TAG, "Handling pending onStartListening"); + if (mDebug) Log.d(TAG, "Handling pending onStartListening " + getComponent()); onStartListening(); } if (queue.contains(MSG_ON_CLICK)) { - if (DEBUG) Log.d(TAG, "Handling pending onClick"); + if (mDebug) Log.d(TAG, "Handling pending onClick " + getComponent()); if (!mListening) { - Log.w(TAG, "Managed to get click on non-listening state..."); + Log.w(TAG, "Managed to get click on non-listening state... " + getComponent()); // Skipping click since lost click privileges. } else { onClick(mClickBinder); } } if (queue.contains(MSG_ON_UNLOCK_COMPLETE)) { - if (DEBUG) Log.d(TAG, "Handling pending onUnlockComplete"); + if (mDebug) Log.d(TAG, "Handling pending onUnlockComplete " + getComponent()); if (!mListening) { - Log.w(TAG, "Managed to get unlock on non-listening state..."); + Log.w(TAG, + "Managed to get unlock on non-listening state... " + getComponent()); // Skipping unlock since lost click privileges. } else { onUnlockComplete(); } } if (queue.contains(MSG_ON_REMOVED)) { - if (DEBUG) Log.d(TAG, "Handling pending onRemoved"); + if (mDebug) Log.d(TAG, "Handling pending onRemoved " + getComponent()); if (mListening) { - Log.w(TAG, "Managed to get remove in listening state..."); + Log.w(TAG, "Managed to get remove in listening state... " + getComponent()); onStopListening(); } onTileRemoved(); @@ -340,28 +354,44 @@ public class TileLifecycleManager extends BroadcastReceiver implements } public void handleDestroy() { - if (DEBUG) Log.d(TAG, "handleDestroy"); + if (mDebug) Log.d(TAG, "handleDestroy"); if (mPackageReceiverRegistered.get() || mUserReceiverRegistered.get()) { stopPackageListening(); } mChangeListener = null; } + /** + * Handles a dead binder. + * + * It means that we need to clean up the binding (calling unbindService). After that, if we + * are supposed to be bound, we will try to bind after some amount of time. + */ private void handleDeath() { - if (mWrapper == null) return; - freeWrapper(); - // Clearly not bound anymore - mIsBound.set(false); - if (!mBound.get()) return; - if (DEBUG) Log.d(TAG, "handleDeath"); - if (checkComponentState()) { - if (isDeathRebindScheduled.compareAndSet(false, true)) { - mExecutor.executeDelayed(() -> { - setBindService(true); - isDeathRebindScheduled.set(false); - }, getRebindDelay()); + mExecutor.execute(() -> { + if (!mIsBound.get()) { + // If we are already not bound, don't do anything else. + return; } - } + // Clearly we shouldn't be bound anymore + if (mDebug) Log.d(TAG, "handleDeath " + getComponent()); + // Binder died, make sure that we unbind. However, we don't want to call setBindService + // as we still may want to rebind. + unbindService(); + // If mBound is true (meaning that we should be bound), then reschedule binding for + // later. + if (mBound.get() && checkComponentState()) { + if (isDeathRebindScheduled.compareAndSet(false, true)) { + mExecutor.executeDelayed(() -> { + // Only rebind if we are supposed to, but remove the scheduling anyway. + if (mBound.get()) { + setBindService(true); + } + isDeathRebindScheduled.set(false); + }, getRebindDelay()); + } + } + }); } /** @@ -379,7 +409,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements } else { delay = mBindRetryDelay; } - Log.i(TAG, "Rebinding with a delay=" + delay); + if (mDebug) Log.i(TAG, "Rebinding with a delay=" + delay + " - " + getComponent()); return delay; } @@ -392,7 +422,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements } private void startPackageListening() { - if (DEBUG) Log.d(TAG, "startPackageListening"); + if (mDebug) Log.d(TAG, "startPackageListening " + getComponent()); IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); filter.addAction(Intent.ACTION_PACKAGE_CHANGED); filter.addDataScheme("package"); @@ -402,7 +432,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements this, mUser, filter, null, mHandler, Context.RECEIVER_EXPORTED); } catch (Exception ex) { mPackageReceiverRegistered.set(false); - Log.e(TAG, "Could not register package receiver", ex); + Log.e(TAG, "Could not register package receiver " + getComponent(), ex); } filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED); try { @@ -410,12 +440,12 @@ public class TileLifecycleManager extends BroadcastReceiver implements mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mHandler, mUser); } catch (Exception ex) { mUserReceiverRegistered.set(false); - Log.e(TAG, "Could not register unlock receiver", ex); + Log.e(TAG, "Could not register unlock receiver " + getComponent(), ex); } } private void stopPackageListening() { - if (DEBUG) Log.d(TAG, "stopPackageListening"); + if (mDebug) Log.d(TAG, "stopPackageListening " + getComponent()); if (mUserReceiverRegistered.compareAndSet(true, false)) { mBroadcastDispatcher.unregisterReceiver(this); } @@ -430,7 +460,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements @Override public void onReceive(Context context, Intent intent) { - if (DEBUG) Log.d(TAG, "onReceive: " + intent); + if (mDebug) Log.d(TAG, "onReceive: " + intent); if (!Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) { Uri data = intent.getData(); String pkgName = data.getEncodedSchemeSpecificPart(); @@ -446,7 +476,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements if (mBound.get()) { // Trying to bind again will check the state of the package before bothering to // bind. - if (DEBUG) Log.d(TAG, "Trying to rebind"); + if (mDebug) Log.d(TAG, "Trying to rebind " + getComponent()); setBindService(true); } @@ -458,7 +488,9 @@ public class TileLifecycleManager extends BroadcastReceiver implements try { ServiceInfo si = mPackageManagerAdapter.getServiceInfo(mIntent.getComponent(), 0, mUser.getIdentifier()); - if (DEBUG && si == null) Log.d(TAG, "Can't find component " + mIntent.getComponent()); + if (mDebug && si == null) { + Log.d(TAG, "Can't find component " + mIntent.getComponent()); + } return si != null; } catch (RemoteException e) { // Shouldn't happen. @@ -472,7 +504,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements mPackageManagerAdapter.getPackageInfoAsUser(packageName, 0, mUser.getIdentifier()); return true; } catch (PackageManager.NameNotFoundException e) { - if (DEBUG) { + if (mDebug) { Log.d(TAG, "Package not available: " + packageName, e); } else { Log.d(TAG, "Package not available: " + packageName); @@ -489,7 +521,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements @Override public void onTileAdded() { - if (DEBUG) Log.d(TAG, "onTileAdded"); + if (mDebug) Log.d(TAG, "onTileAdded " + getComponent()); if (mWrapper == null || !mWrapper.onTileAdded()) { queueMessage(MSG_ON_ADDED); handleDeath(); @@ -498,7 +530,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements @Override public void onTileRemoved() { - if (DEBUG) Log.d(TAG, "onTileRemoved"); + if (mDebug) Log.d(TAG, "onTileRemoved " + getComponent()); if (mWrapper == null || !mWrapper.onTileRemoved()) { queueMessage(MSG_ON_REMOVED); handleDeath(); @@ -507,7 +539,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements @Override public void onStartListening() { - if (DEBUG) Log.d(TAG, "onStartListening"); + if (mDebug) Log.d(TAG, "onStartListening " + getComponent()); mListening = true; if (mWrapper != null && !mWrapper.onStartListening()) { handleDeath(); @@ -516,7 +548,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements @Override public void onStopListening() { - if (DEBUG) Log.d(TAG, "onStopListening"); + if (mDebug) Log.d(TAG, "onStopListening " + getComponent()); mListening = false; if (mWrapper != null && !mWrapper.onStopListening()) { handleDeath(); @@ -525,7 +557,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements @Override public void onClick(IBinder iBinder) { - if (DEBUG) Log.d(TAG, "onClick " + iBinder + " " + mUser); + if (mDebug) Log.d(TAG, "onClick " + iBinder + " " + getComponent() + " " + mUser); if (mWrapper == null || !mWrapper.onClick(iBinder)) { mClickBinder = iBinder; queueMessage(MSG_ON_CLICK); @@ -535,7 +567,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements @Override public void onUnlockComplete() { - if (DEBUG) Log.d(TAG, "onUnlockComplete"); + if (mDebug) Log.d(TAG, "onUnlockComplete " + getComponent()); if (mWrapper == null || !mWrapper.onUnlockComplete()) { queueMessage(MSG_ON_UNLOCK_COMPLETE); handleDeath(); @@ -550,7 +582,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements @Override public void binderDied() { - if (DEBUG) Log.d(TAG, "binderDeath"); + if (mDebug) Log.d(TAG, "binderDeath " + getComponent()); handleDeath(); } diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java index fdf5966419b4..20fef927e8d1 100644 --- a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java @@ -317,10 +317,11 @@ public class ImageWallpaper extends WallpaperService { } private void loadWallpaperAndDrawFrameInternal() { - Trace.beginSection("ImageWallpaper.CanvasEngine#loadWallpaper"); + Trace.beginSection("WPMS.ImageWallpaper.CanvasEngine#loadWallpaper"); boolean loadSuccess = false; Bitmap bitmap; try { + Trace.beginSection("WPMS.getBitmapAsUser"); bitmap = mWallpaperManager.getBitmapAsUser( mUserTracker.getUserId(), false, getSourceFlag(), true); if (bitmap != null @@ -333,15 +334,22 @@ public class ImageWallpaper extends WallpaperService { // be loaded, we will go into a cycle. Don't do a build where the // default wallpaper can't be loaded. Log.w(TAG, "Unable to load wallpaper!", exception); + Trace.beginSection("WPMS.clearWallpaper"); mWallpaperManager.clearWallpaper(getWallpaperFlags(), mUserTracker.getUserId()); + Trace.endSection(); try { + Trace.beginSection("WPMS.getBitmapAsUser_defaultWallpaper"); bitmap = mWallpaperManager.getBitmapAsUser( mUserTracker.getUserId(), false, getSourceFlag(), true); } catch (RuntimeException | OutOfMemoryError e) { Log.w(TAG, "Unable to load default wallpaper!", e); bitmap = null; + } finally { + Trace.endSection(); } + } finally { + Trace.endSection(); } if (bitmap == null) { @@ -355,15 +363,23 @@ public class ImageWallpaper extends WallpaperService { loadSuccess = true; // recycle the previously loaded bitmap if (mBitmap != null) { + Trace.beginSection("WPMS.mBitmap.recycle"); mBitmap.recycle(); + Trace.endSection(); } mBitmap = bitmap; + Trace.beginSection("WPMS.wallpaperSupportsWcg"); mWideColorGamut = mWallpaperManager.wallpaperSupportsWcg(getSourceFlag()); + Trace.endSection(); // +2 usages for the color extraction and the delayed unload. mBitmapUsages += 2; + Trace.beginSection("WPMS.recomputeColorExtractorMiniBitmap"); recomputeColorExtractorMiniBitmap(); + Trace.endSection(); + Trace.beginSection("WPMS.drawFrameInternal"); drawFrameInternal(); + Trace.endSection(); /* * after loading, the bitmap will be unloaded after all these conditions: diff --git a/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt index b1421b21b377..e921a59f5860 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt @@ -9,30 +9,34 @@ import android.util.PathParser import androidx.test.filters.SmallTest import com.android.systemui.res.R import com.android.systemui.util.mockito.any -import com.android.systemui.util.mockito.withArgCaptor +import com.android.systemui.util.mockito.mock +import com.android.systemui.util.mockito.whenever +import com.google.common.truth.Expect import java.util.concurrent.Executor import kotlin.math.roundToInt -import kotlin.test.assertEquals -import kotlin.test.assertNotNull import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.Mockito.never -import org.mockito.Mockito.verify -import org.mockito.MockitoAnnotations @RunWith(AndroidTestingRunner::class) @SmallTest class CameraAvailabilityListenerTest : SysuiTestCase() { companion object { - const val EXCLUDED_PKG = "test.excluded.package" - const val CAMERA_ID_FRONT = "0" - const val CAMERA_ID_INNER = "1" - const val PROTECTION_PATH_STRING_FRONT = "M 50,50 a 20,20 0 1 0 40,0 a 20,20 0 1 0 -40,0 Z" - const val PROTECTION_PATH_STRING_INNER = "M 40,40 a 10,10 0 1 0 20,0 a 10,10 0 1 0 -20,0 Z" - val PATH_RECT_FRONT = rectFromPath(pathFromString(PROTECTION_PATH_STRING_FRONT)) - val PATH_RECT_INNER = rectFromPath(pathFromString(PROTECTION_PATH_STRING_INNER)) + private const val EXCLUDED_PKG = "test.excluded.package" + private const val LOGICAL_CAMERA_ID_NOT_SPECIFIED = "" + private const val LOGICAL_CAMERA_ID_REAR = "0" + private const val LOGICAL_CAMERA_ID_FRONT = "1" + private const val PHYSICAL_CAMERA_ID_OUTER_FRONT = "5" + private const val PHYSICAL_CAMERA_ID_INNER_FRONT = "6" + private const val PROTECTION_PATH_STRING_OUTER_FRONT = + "M 50,50 a 20,20 0 1 0 40,0 a 20,20 0 1 0 -40,0 Z" + private const val PROTECTION_PATH_STRING_INNER_FRONT = + "M 40,40 a 10,10 0 1 0 20,0 a 10,10 0 1 0 -20,0 Z" + private val PATH_RECT_FRONT = + rectFromPath(pathFromString(PROTECTION_PATH_STRING_OUTER_FRONT)) + private val PATH_RECT_INNER = + rectFromPath(pathFromString(PROTECTION_PATH_STRING_INNER_FRONT)) private fun pathFromString(pathString: String): Path { val spec = pathString.trim() @@ -58,105 +62,310 @@ class CameraAvailabilityListenerTest : SysuiTestCase() { } } - @Mock private lateinit var cameraManager: CameraManager - @Mock - private lateinit var cameraTransitionCb: CameraAvailabilityListener.CameraTransitionCallback - private lateinit var cameraAvailabilityListener: CameraAvailabilityListener + @get:Rule val expect: Expect = Expect.create() + + private val cameraManager = mock<CameraManager>() + private val cameraTransitionCallback = TestCameraTransitionCallback() + + private lateinit var cameraAvailabilityCallback: CameraManager.AvailabilityCallback @Before fun setUp() { - MockitoAnnotations.initMocks(this) - context - .getOrCreateTestableResources() - .addOverride(R.string.config_cameraProtectionExcludedPackages, EXCLUDED_PKG) - context - .getOrCreateTestableResources() - .addOverride(R.string.config_protectedCameraId, CAMERA_ID_FRONT) - context - .getOrCreateTestableResources() - .addOverride( - R.string.config_frontBuiltInDisplayCutoutProtection, - PROTECTION_PATH_STRING_FRONT - ) - context - .getOrCreateTestableResources() - .addOverride(R.string.config_protectedInnerCameraId, CAMERA_ID_INNER) - context - .getOrCreateTestableResources() - .addOverride( - R.string.config_innerBuiltInDisplayCutoutProtection, - PROTECTION_PATH_STRING_INNER + overrideResource(R.string.config_cameraProtectionExcludedPackages, EXCLUDED_PKG) + setOuterFrontCameraId(LOGICAL_CAMERA_ID_FRONT) + setOuterFrontPhysicalCameraId(PHYSICAL_CAMERA_ID_OUTER_FRONT) + overrideResource( + R.string.config_frontBuiltInDisplayCutoutProtection, + PROTECTION_PATH_STRING_OUTER_FRONT + ) + setInnerFrontCameraId(LOGICAL_CAMERA_ID_FRONT) + setInnerFrontPhysicalCameraId(PHYSICAL_CAMERA_ID_INNER_FRONT) + overrideResource( + R.string.config_innerBuiltInDisplayCutoutProtection, + PROTECTION_PATH_STRING_INNER_FRONT + ) + context.addMockSystemService(CameraManager::class.java, cameraManager) + + whenever( + cameraManager.registerAvailabilityCallback( + any(Executor::class.java), + any(CameraManager.AvailabilityCallback::class.java) + ) ) + .thenAnswer { + cameraAvailabilityCallback = it.arguments[1] as CameraManager.AvailabilityCallback + return@thenAnswer Unit + } + } - context.addMockSystemService(CameraManager::class.java, cameraManager) + @Test + fun onCameraOpened_matchesOuterFrontInfo_showsOuterProtection() { + setInnerFrontCameraId(LOGICAL_CAMERA_ID_NOT_SPECIFIED) + createAndStartSut() - cameraAvailabilityListener = - CameraAvailabilityListener.Factory.build(context, context.mainExecutor) + openCamera(LOGICAL_CAMERA_ID_FRONT) + + assertOuterProtectionShowing() } @Test - fun testFrontCamera() { - var path: Path? = null - var rect: Rect? = null - val callback = - object : CameraAvailabilityListener.CameraTransitionCallback { - override fun onApplyCameraProtection(protectionPath: Path, bounds: Rect) { - path = protectionPath - rect = bounds - } + fun onCameraOpened_matchesInnerFrontInfo_showsInnerProtection() { + setOuterFrontCameraId(LOGICAL_CAMERA_ID_NOT_SPECIFIED) + createAndStartSut() - override fun onHideCameraProtection() {} - } + openCamera(LOGICAL_CAMERA_ID_FRONT) - cameraAvailabilityListener.addTransitionCallback(callback) - cameraAvailabilityListener.startListening() + assertInnerProtectionShowing() + } - val callbackCaptor = withArgCaptor { - verify(cameraManager).registerAvailabilityCallback(any(Executor::class.java), capture()) - } + @Test + fun onCameraOpened_doesNotMatchAnyProtectionInfo_doesNotShowProtection() { + createAndStartSut() - callbackCaptor.onCameraOpened(CAMERA_ID_FRONT, "") - assertNotNull(path) - assertEquals(PATH_RECT_FRONT, rect) + openCamera(LOGICAL_CAMERA_ID_REAR) + + assertProtectionNotShowing() } @Test - fun testInnerCamera() { - var path: Path? = null - var rect: Rect? = null - val callback = - object : CameraAvailabilityListener.CameraTransitionCallback { - override fun onApplyCameraProtection(protectionPath: Path, bounds: Rect) { - path = protectionPath - rect = bounds - } + fun onCameraOpened_matchesInnerAndOuter_innerUnavailable_showsOuterProtection() { + val dupeCameraId = "1" + setInnerFrontCameraId(dupeCameraId) + setOuterFrontCameraId(dupeCameraId) + createAndStartSut() - override fun onHideCameraProtection() {} - } + setPhysicalCameraUnavailable(dupeCameraId, PHYSICAL_CAMERA_ID_INNER_FRONT) + openCamera(dupeCameraId) - cameraAvailabilityListener.addTransitionCallback(callback) - cameraAvailabilityListener.startListening() + assertOuterProtectionShowing() + } - val callbackCaptor = withArgCaptor { - verify(cameraManager).registerAvailabilityCallback(any(Executor::class.java), capture()) - } + @Test + fun onCameraOpened_matchesInnerAndOuter_outerUnavailable_showsInnerFrontProtection() { + val dupeCameraId = "1" + setInnerFrontCameraId(dupeCameraId) + setOuterFrontCameraId(dupeCameraId) + createAndStartSut() + + setPhysicalCameraUnavailable(dupeCameraId, PHYSICAL_CAMERA_ID_OUTER_FRONT) + openCamera(dupeCameraId) - callbackCaptor.onCameraOpened(CAMERA_ID_INNER, "") - assertNotNull(path) - assertEquals(PATH_RECT_INNER, rect) + assertInnerProtectionShowing() } @Test - fun testExcludedPackage() { - cameraAvailabilityListener.addTransitionCallback(cameraTransitionCb) - cameraAvailabilityListener.startListening() + fun onCameraOpened_matchesOuterFrontInfo_packageExcluded_doesNotShowProtection() { + setInnerFrontCameraId(LOGICAL_CAMERA_ID_NOT_SPECIFIED) + createAndStartSut() + + openCamera(LOGICAL_CAMERA_ID_FRONT, EXCLUDED_PKG) + + assertProtectionNotShowing() + } + + @Test + fun onCameraOpened_matchesInnerFrontInfo_packageExcluded_doesNotShowProtection() { + setOuterFrontCameraId(LOGICAL_CAMERA_ID_NOT_SPECIFIED) + createAndStartSut() + + openCamera(LOGICAL_CAMERA_ID_FRONT, EXCLUDED_PKG) + + assertProtectionNotShowing() + } + + @Test + fun onCameraClosed_matchesActiveOuterFrontProtection_hidesProtection() { + setInnerFrontCameraId(LOGICAL_CAMERA_ID_NOT_SPECIFIED) + createAndStartSut() + openCamera(LOGICAL_CAMERA_ID_FRONT) + + closeCamera(LOGICAL_CAMERA_ID_FRONT) + + assertProtectionNotShowing() + } + + @Test + fun onCameraClosed_matchesActiveInnerFrontProtection_hidesProtection() { + setOuterFrontCameraId(LOGICAL_CAMERA_ID_NOT_SPECIFIED) + createAndStartSut() + openCamera(LOGICAL_CAMERA_ID_FRONT) + + closeCamera(LOGICAL_CAMERA_ID_FRONT) + + assertProtectionNotShowing() + } + + @Test + fun onCameraClosed_doesNotMatchActiveOuterFrontProtection_keepsShowingProtection() { + setInnerFrontCameraId(LOGICAL_CAMERA_ID_NOT_SPECIFIED) + createAndStartSut() + openCamera(LOGICAL_CAMERA_ID_FRONT) + + closeCamera(LOGICAL_CAMERA_ID_REAR) + + assertOuterProtectionShowing() + } + + @Test + fun onCameraClosed_doesNotMatchActiveInnerFrontProtection_keepsShowingProtection() { + setOuterFrontCameraId(LOGICAL_CAMERA_ID_NOT_SPECIFIED) + createAndStartSut() + openCamera(LOGICAL_CAMERA_ID_FRONT) + + closeCamera(LOGICAL_CAMERA_ID_REAR) + + assertInnerProtectionShowing() + } + + @Test + fun onPhysicalCameraAvailable_cameraOpen_matchesOuterFront_showsOuterFrontProtection() { + val logicalCameraId = "1" + setOuterFrontCameraId(logicalCameraId) + setInnerFrontCameraId(logicalCameraId) + createAndStartSut() + setPhysicalCameraUnavailable(logicalCameraId, PHYSICAL_CAMERA_ID_OUTER_FRONT) + openCamera(logicalCameraId) + + setPhysicalCameraAvailable(logicalCameraId, PHYSICAL_CAMERA_ID_OUTER_FRONT) + + assertOuterProtectionShowing() + } - val callbackCaptor = withArgCaptor { - verify(cameraManager).registerAvailabilityCallback(any(Executor::class.java), capture()) + @Test + fun onPhysicalCameraAvailable_cameraClosed_matchesOuterFront_doesNotShowProtection() { + val logicalCameraId = "1" + setOuterFrontCameraId(logicalCameraId) + setInnerFrontCameraId(logicalCameraId) + createAndStartSut() + setPhysicalCameraUnavailable(logicalCameraId, PHYSICAL_CAMERA_ID_OUTER_FRONT) + + setPhysicalCameraAvailable(logicalCameraId, PHYSICAL_CAMERA_ID_OUTER_FRONT) + + assertProtectionNotShowing() + } + + @Test + fun onPhysicalCameraAvailable_cameraOpen_matchesInnerFront_showsInnerFrontProtection() { + val logicalCameraId = "1" + setOuterFrontCameraId(logicalCameraId) + setInnerFrontCameraId(logicalCameraId) + createAndStartSut() + setPhysicalCameraUnavailable(logicalCameraId, PHYSICAL_CAMERA_ID_INNER_FRONT) + openCamera(logicalCameraId) + + setPhysicalCameraAvailable(logicalCameraId, PHYSICAL_CAMERA_ID_INNER_FRONT) + + assertInnerProtectionShowing() + } + + @Test + fun onPhysicalCameraAvailable_cameraClosed_matchesInnerFront_doesNotShowProtection() { + val logicalCameraId = "1" + setOuterFrontCameraId(logicalCameraId) + setInnerFrontCameraId(logicalCameraId) + createAndStartSut() + setPhysicalCameraUnavailable(logicalCameraId, PHYSICAL_CAMERA_ID_INNER_FRONT) + + setPhysicalCameraAvailable(logicalCameraId, PHYSICAL_CAMERA_ID_INNER_FRONT) + + assertProtectionNotShowing() + } + + @Test + fun onPhysicalCameraUnavailable_matchesActiveProtection_hidesProtection() { + setInnerFrontCameraId(LOGICAL_CAMERA_ID_NOT_SPECIFIED) + createAndStartSut() + openCamera(LOGICAL_CAMERA_ID_FRONT) + + setPhysicalCameraUnavailable(LOGICAL_CAMERA_ID_FRONT, PHYSICAL_CAMERA_ID_OUTER_FRONT) + + assertProtectionNotShowing() + } + + @Test + fun onPhysicalCameraUnavailable_doesNotMatchActiveProtection_keepsShowingProtection() { + setInnerFrontCameraId(LOGICAL_CAMERA_ID_NOT_SPECIFIED) + createAndStartSut() + openCamera(LOGICAL_CAMERA_ID_FRONT) + + setPhysicalCameraUnavailable(LOGICAL_CAMERA_ID_FRONT, PHYSICAL_CAMERA_ID_INNER_FRONT) + + assertOuterProtectionShowing() + } + + private fun openCamera(logicalCameraId: String, packageId: String = "") { + cameraAvailabilityCallback.onCameraOpened(logicalCameraId, packageId) + } + + private fun closeCamera(logicalCameraId: String) { + cameraAvailabilityCallback.onCameraClosed(logicalCameraId) + } + + private fun setPhysicalCameraAvailable(logicalCameraId: String, physicalCameraId: String) { + cameraAvailabilityCallback.onPhysicalCameraAvailable(logicalCameraId, physicalCameraId) + } + + private fun setPhysicalCameraUnavailable(logicalCameraId: String, physicalCameraId: String) { + cameraAvailabilityCallback.onPhysicalCameraUnavailable(logicalCameraId, physicalCameraId) + } + + private fun assertOuterProtectionShowing() { + expect.that(cameraTransitionCallback.shouldShowProtection).isTrue() + expect.that(cameraTransitionCallback.protectionPath).isNotNull() + expect.that(cameraTransitionCallback.protectionBounds).isEqualTo(PATH_RECT_FRONT) + } + + private fun assertInnerProtectionShowing() { + expect.that(cameraTransitionCallback.shouldShowProtection).isTrue() + expect.that(cameraTransitionCallback.protectionPath).isNotNull() + expect.that(cameraTransitionCallback.protectionBounds).isEqualTo(PATH_RECT_INNER) + } + + private fun assertProtectionNotShowing() { + expect.that(cameraTransitionCallback.shouldShowProtection).isFalse() + expect.that(cameraTransitionCallback.protectionBounds).isNull() + expect.that(cameraTransitionCallback.protectionPath).isNull() + } + + private fun setOuterFrontCameraId(id: String) { + overrideResource(R.string.config_protectedCameraId, id) + } + + private fun setOuterFrontPhysicalCameraId(id: String) { + overrideResource(R.string.config_protectedPhysicalCameraId, id) + } + + private fun setInnerFrontCameraId(id: String) { + overrideResource(R.string.config_protectedInnerCameraId, id) + } + + private fun setInnerFrontPhysicalCameraId(id: String) { + overrideResource(R.string.config_protectedInnerPhysicalCameraId, id) + } + + private fun createAndStartSut(): CameraAvailabilityListener { + return CameraAvailabilityListener.build(context, context.mainExecutor).also { + it.addTransitionCallback(cameraTransitionCallback) + it.startListening() + } + } + + private class TestCameraTransitionCallback : + CameraAvailabilityListener.CameraTransitionCallback { + var shouldShowProtection = false + var protectionPath: Path? = null + var protectionBounds: Rect? = null + + override fun onApplyCameraProtection(protectionPath: Path, bounds: Rect) { + shouldShowProtection = true + this.protectionPath = protectionPath + this.protectionBounds = bounds } - callbackCaptor.onCameraOpened(CAMERA_ID_FRONT, EXCLUDED_PKG) - verify(cameraTransitionCb, never()) - .onApplyCameraProtection(any(Path::class.java), any(Rect::class.java)) + override fun onHideCameraProtection() { + shouldShowProtection = false + protectionPath = null + protectionBounds = null + } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java index fbd63c6bbdae..81424565daee 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java @@ -29,6 +29,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -300,8 +301,10 @@ public class TileLifecycleManagerTest extends SysuiTestCase { mStateManager.onStartListening(); mStateManager.executeSetBindService(true); mExecutor.runAllReady(); - mStateManager.onServiceDisconnected(mTileServiceComponentName); + mStateManager.onBindingDied(mTileServiceComponentName); + mExecutor.runAllReady(); mClock.advanceTime(5000); + mExecutor.runAllReady(); // Two calls: one for the first bind, one for the restart. verifyBind(2); @@ -318,20 +321,66 @@ public class TileLifecycleManagerTest extends SysuiTestCase { mStateManager.onStartListening(); mStateManager.executeSetBindService(true); mExecutor.runAllReady(); - mStateManager.onServiceDisconnected(mTileServiceComponentName); + verify(mMockTileService, times(1)).onStartListening(); + mStateManager.onBindingDied(mTileServiceComponentName); + mExecutor.runAllReady(); // Longer delay than a regular one mClock.advanceTime(5000); - verifyBind(1); - verify(mMockTileService, times(1)).onStartListening(); + mExecutor.runAllReady(); + + assertFalse(mContext.isBound(mTileServiceComponentName)); mClock.advanceTime(20000); + mExecutor.runAllReady(); // Two calls: one for the first bind, one for the restart. verifyBind(2); verify(mMockTileService, times(2)).onStartListening(); } @Test + public void testOnServiceDisconnectedDoesnUnbind_doesntForwardToBinder() throws Exception { + mStateManager.executeSetBindService(true); + mExecutor.runAllReady(); + + mStateManager.onStartListening(); + verify(mMockTileService).onStartListening(); + + clearInvocations(mMockTileService); + mStateManager.onServiceDisconnected(mTileServiceComponentName); + mExecutor.runAllReady(); + + mStateManager.onStartListening(); + verify(mMockTileService, never()).onStartListening(); + } + + @Test + public void testKillProcessLowMemory_unbound_doesntBindAgain() throws Exception { + doAnswer(invocation -> { + ActivityManager.MemoryInfo memoryInfo = invocation.getArgument(0); + memoryInfo.lowMemory = true; + return null; + }).when(mActivityManager).getMemoryInfo(any()); + mStateManager.onStartListening(); + mStateManager.executeSetBindService(true); + mExecutor.runAllReady(); + verifyBind(1); + verify(mMockTileService, times(1)).onStartListening(); + + mStateManager.onBindingDied(mTileServiceComponentName); + mExecutor.runAllReady(); + + clearInvocations(mMockTileService); + mStateManager.executeSetBindService(false); + mExecutor.runAllReady(); + mClock.advanceTime(30000); + mExecutor.runAllReady(); + + verifyBind(0); + verify(mMockTileService, never()).onStartListening(); + } + + @Test public void testToggleableTile() throws Exception { assertTrue(mStateManager.isToggleableTile()); } diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java index b5846b555747..a40dd7919402 100644 --- a/services/core/java/com/android/server/compat/CompatChange.java +++ b/services/core/java/com/android/server/compat/CompatChange.java @@ -252,9 +252,6 @@ public final class CompatChange extends CompatibilityChangeInfo { // If the change is gated by a platform version newer than the one currently installed // on the device, disregard the app's target sdk version. int compareSdk = Math.min(app.targetSdkVersion, buildClassifier.platformTargetSdk()); - if (compareSdk != app.targetSdkVersion) { - compareSdk = app.targetSdkVersion; - } return compareSdk >= getEnableSinceTargetSdk(); } return true; diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index b54289321e89..2314bb772494 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -16,6 +16,8 @@ package com.android.server.display; +import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityTaskManager; import android.app.ActivityTaskManager.RootTaskInfo; @@ -40,6 +42,7 @@ import android.os.Trace; import android.util.EventLog; import android.util.MathUtils; import android.util.Slog; +import android.util.SparseArray; import android.util.TimeUtils; import com.android.internal.annotations.VisibleForTesting; @@ -49,6 +52,8 @@ import com.android.server.EventLogTags; import com.android.server.display.brightness.BrightnessEvent; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * Manages the associated display brightness when in auto-brightness mode. This is also @@ -64,6 +69,16 @@ public class AutomaticBrightnessController { public static final int AUTO_BRIGHTNESS_DISABLED = 2; public static final int AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE = 3; + @IntDef(prefix = { "AUTO_BRIGHTNESS_MODE_" }, value = { + AUTO_BRIGHTNESS_MODE_DEFAULT, + AUTO_BRIGHTNESS_MODE_IDLE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AutomaticBrightnessMode{} + + public static final int AUTO_BRIGHTNESS_MODE_DEFAULT = 0; + public static final int AUTO_BRIGHTNESS_MODE_IDLE = 1; + // How long the current sensor reading is assumed to be valid beyond the current time. // This provides a bit of prediction, as well as ensures that the weight for the last sample is // non-zero, which in turn ensures that the total weight is non-zero. @@ -91,10 +106,11 @@ public class AutomaticBrightnessController { private final Sensor mLightSensor; // The mapper to translate ambient lux to screen brightness in the range [0, 1.0]. - @Nullable + @NonNull private BrightnessMappingStrategy mCurrentBrightnessMapper; - private final BrightnessMappingStrategy mInteractiveModeBrightnessMapper; - private final BrightnessMappingStrategy mIdleModeBrightnessMapper; + + // A map of Brightness Mapping Strategies indexed by AutomaticBrightnessMode + private final SparseArray<BrightnessMappingStrategy> mBrightnessMappingStrategyMap; // The minimum and maximum screen brightnesses. private final float mScreenBrightnessRangeMinimum; @@ -251,7 +267,7 @@ public class AutomaticBrightnessController { AutomaticBrightnessController(Callbacks callbacks, Looper looper, SensorManager sensorManager, Sensor lightSensor, - BrightnessMappingStrategy interactiveModeBrightnessMapper, + SparseArray<BrightnessMappingStrategy> brightnessMappingStrategyMap, int lightSensorWarmUpTime, float brightnessMin, float brightnessMax, float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, @@ -261,26 +277,25 @@ public class AutomaticBrightnessController { HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels screenBrightnessThresholdsIdle, Context context, BrightnessRangeController brightnessModeController, - BrightnessThrottler brightnessThrottler, - BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort, - int ambientLightHorizonLong, float userLux, float userBrightness) { + BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort, + int ambientLightHorizonLong, float userLux, float userNits) { this(new Injector(), callbacks, looper, sensorManager, lightSensor, - interactiveModeBrightnessMapper, - lightSensorWarmUpTime, brightnessMin, brightnessMax, dozeScaleFactor, - lightSensorRate, initialLightSensorRate, brighteningLightDebounceConfig, - darkeningLightDebounceConfig, brighteningLightDebounceConfigIdle, - darkeningLightDebounceConfigIdle, resetAmbientLuxAfterWarmUpConfig, - ambientBrightnessThresholds, screenBrightnessThresholds, - ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, context, - brightnessModeController, brightnessThrottler, idleModeBrightnessMapper, - ambientLightHorizonShort, ambientLightHorizonLong, userLux, userBrightness + brightnessMappingStrategyMap, lightSensorWarmUpTime, brightnessMin, brightnessMax, + dozeScaleFactor, lightSensorRate, initialLightSensorRate, + brighteningLightDebounceConfig, darkeningLightDebounceConfig, + brighteningLightDebounceConfigIdle, darkeningLightDebounceConfigIdle, + resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds, + screenBrightnessThresholds, ambientBrightnessThresholdsIdle, + screenBrightnessThresholdsIdle, context, brightnessModeController, + brightnessThrottler, ambientLightHorizonShort, ambientLightHorizonLong, userLux, + userNits ); } @VisibleForTesting AutomaticBrightnessController(Injector injector, Callbacks callbacks, Looper looper, SensorManager sensorManager, Sensor lightSensor, - BrightnessMappingStrategy interactiveModeBrightnessMapper, + SparseArray<BrightnessMappingStrategy> brightnessMappingStrategyMap, int lightSensorWarmUpTime, float brightnessMin, float brightnessMax, float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, @@ -290,15 +305,14 @@ public class AutomaticBrightnessController { HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels screenBrightnessThresholdsIdle, Context context, BrightnessRangeController brightnessModeController, - BrightnessThrottler brightnessThrottler, - BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort, - int ambientLightHorizonLong, float userLux, float userBrightness) { + BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort, + int ambientLightHorizonLong, float userLux, float userNits) { mInjector = injector; mClock = injector.createClock(); mContext = context; mCallbacks = callbacks; mSensorManager = sensorManager; - mCurrentBrightnessMapper = interactiveModeBrightnessMapper; + mCurrentBrightnessMapper = brightnessMappingStrategyMap.get(AUTO_BRIGHTNESS_MODE_DEFAULT); mScreenBrightnessRangeMinimum = brightnessMin; mScreenBrightnessRangeMaximum = brightnessMax; mLightSensorWarmUpTimeConfig = lightSensorWarmUpTime; @@ -337,13 +351,12 @@ public class AutomaticBrightnessController { mPendingForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED; mBrightnessRangeController = brightnessModeController; mBrightnessThrottler = brightnessThrottler; - mInteractiveModeBrightnessMapper = interactiveModeBrightnessMapper; - mIdleModeBrightnessMapper = idleModeBrightnessMapper; - // Initialize to active (normal) screen brightness mode - switchToInteractiveScreenBrightnessMode(); + mBrightnessMappingStrategyMap = brightnessMappingStrategyMap; // Use the given short-term model - setScreenBrightnessByUser(userLux, userBrightness); + if (userNits != BrightnessMappingStrategy.INVALID_NITS) { + setScreenBrightnessByUser(userLux, getBrightnessFromNits(userNits)); + } } /** @@ -358,11 +371,8 @@ public class AutomaticBrightnessController { if (mLoggingEnabled == loggingEnabled) { return false; } - if (mInteractiveModeBrightnessMapper != null) { - mInteractiveModeBrightnessMapper.setLoggingEnabled(loggingEnabled); - } - if (mIdleModeBrightnessMapper != null) { - mIdleModeBrightnessMapper.setLoggingEnabled(loggingEnabled); + for (int i = 0; i < mBrightnessMappingStrategyMap.size(); i++) { + mBrightnessMappingStrategyMap.valueAt(i).setLoggingEnabled(loggingEnabled); } mLoggingEnabled = loggingEnabled; return true; @@ -389,8 +399,7 @@ public class AutomaticBrightnessController { | (!mAmbientLuxValid ? BrightnessEvent.FLAG_INVALID_LUX : 0) | (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE ? BrightnessEvent.FLAG_DOZE_SCALE : 0) - | (mCurrentBrightnessMapper.isForIdleMode() - ? BrightnessEvent.FLAG_IDLE_CURVE : 0)); + | (isInIdleMode() ? BrightnessEvent.FLAG_IDLE_CURVE : 0)); } if (!mAmbientLuxValid) { @@ -464,15 +473,13 @@ public class AutomaticBrightnessController { // Used internally to establish whether we have deviated from the default config. public boolean isDefaultConfig() { - if (isInIdleMode()) { - return false; - } - return mInteractiveModeBrightnessMapper.isDefaultConfig(); + return mCurrentBrightnessMapper.getMode() == AUTO_BRIGHTNESS_MODE_DEFAULT + && mCurrentBrightnessMapper.isDefaultConfig(); } // Called from APIs to get the configuration. public BrightnessConfiguration getDefaultConfig() { - return mInteractiveModeBrightnessMapper.getDefaultConfig(); + return mBrightnessMappingStrategyMap.get(AUTO_BRIGHTNESS_MODE_DEFAULT).getDefaultConfig(); } /** @@ -527,8 +534,7 @@ public class AutomaticBrightnessController { } private boolean setScreenBrightnessByUser(float lux, float brightness) { - if (lux == BrightnessMappingStrategy.NO_USER_LUX - || brightness == BrightnessMappingStrategy.NO_USER_BRIGHTNESS) { + if (lux == BrightnessMappingStrategy.INVALID_LUX || Float.isNaN(brightness)) { return false; } mCurrentBrightnessMapper.addUserDataPoint(lux, brightness); @@ -543,7 +549,8 @@ public class AutomaticBrightnessController { public boolean setBrightnessConfiguration(BrightnessConfiguration configuration, boolean shouldResetShortTermModel) { - if (mInteractiveModeBrightnessMapper.setBrightnessConfiguration(configuration)) { + if (mBrightnessMappingStrategyMap.get(AUTO_BRIGHTNESS_MODE_DEFAULT) + .setBrightnessConfiguration(configuration)) { if (!isInIdleMode() && shouldResetShortTermModel) { resetShortTermModel(); } @@ -553,7 +560,7 @@ public class AutomaticBrightnessController { } public boolean isInIdleMode() { - return mCurrentBrightnessMapper.isForIdleMode(); + return mCurrentBrightnessMapper.getMode() == AUTO_BRIGHTNESS_MODE_IDLE; } public void dump(PrintWriter pw) { @@ -595,12 +602,6 @@ public class AutomaticBrightnessController { pw.println(" mAmbientLightRingBuffer=" + mAmbientLightRingBuffer); pw.println(" mScreenAutoBrightness=" + mScreenAutoBrightness); pw.println(" mDisplayPolicy=" + DisplayPowerRequest.policyToString(mDisplayPolicy)); - pw.println(" mShortTermModelTimeout(active)=" - + mInteractiveModeBrightnessMapper.getShortTermModelTimeout()); - if (mIdleModeBrightnessMapper != null) { - pw.println(" mShortTermModelTimeout(idle)=" - + mIdleModeBrightnessMapper.getShortTermModelTimeout()); - } pw.println(" mShortTermModel="); mShortTermModel.dump(pw); pw.println(" mPausedShortTermModel="); @@ -615,15 +616,14 @@ public class AutomaticBrightnessController { pw.println(" mPendingForegroundAppPackageName=" + mPendingForegroundAppPackageName); pw.println(" mForegroundAppCategory=" + mForegroundAppCategory); pw.println(" mPendingForegroundAppCategory=" + mPendingForegroundAppCategory); - pw.println(" Idle mode active=" + mCurrentBrightnessMapper.isForIdleMode()); + pw.println(" Current mode=" + mCurrentBrightnessMapper.getMode()); pw.println(); - pw.println(" mInteractiveMapper="); - mInteractiveModeBrightnessMapper.dump(pw, - mBrightnessRangeController.getNormalBrightnessMax()); - if (mIdleModeBrightnessMapper != null) { - pw.println(" mIdleMapper="); - mIdleModeBrightnessMapper.dump(pw, mBrightnessRangeController.getNormalBrightnessMax()); + for (int i = 0; i < mBrightnessMappingStrategyMap.size(); i++) { + pw.println(" Mapper for mode " + modeToString(mBrightnessMappingStrategyMap.keyAt(i)) + + "="); + mBrightnessMappingStrategyMap.valueAt(i).dump(pw, + mBrightnessRangeController.getNormalBrightnessMax()); } pw.println(); @@ -1117,68 +1117,58 @@ public class AutomaticBrightnessController { updateAutoBrightness(true /* sendUpdate */, false /* isManuallySet */); } - void switchToIdleMode() { - if (mIdleModeBrightnessMapper == null) { - return; - } - if (mCurrentBrightnessMapper.isForIdleMode()) { - return; - } - Slog.i(TAG, "Switching to Idle Screen Brightness Mode"); + private void switchModeAndShortTermModels(@AutomaticBrightnessMode int mode) { // Stash short term model ShortTermModel tempShortTermModel = new ShortTermModel(); tempShortTermModel.set(mCurrentBrightnessMapper.getUserLux(), mCurrentBrightnessMapper.getUserBrightness(), /* valid= */ true); - + mHandler.removeMessages(MSG_INVALIDATE_PAUSED_SHORT_TERM_MODEL); // Send delayed timeout mHandler.sendEmptyMessageAtTime(MSG_INVALIDATE_PAUSED_SHORT_TERM_MODEL, mClock.uptimeMillis() + mCurrentBrightnessMapper.getShortTermModelTimeout()); - Slog.i(TAG, "mPreviousShortTermModel" + mPausedShortTermModel); + Slog.i(TAG, "mPreviousShortTermModel: " + mPausedShortTermModel); // new brightness mapper - mCurrentBrightnessMapper = mIdleModeBrightnessMapper; + mCurrentBrightnessMapper = mBrightnessMappingStrategyMap.get(mode); // if previous stm has been invalidated, and lux has drastically changed, just use // the new, reset stm. // if previous stm is still valid then revalidate it - if (mPausedShortTermModel != null && !mPausedShortTermModel.maybeReset(mAmbientLux)) { - setScreenBrightnessByUser(mPausedShortTermModel.mAnchor, - mPausedShortTermModel.mBrightness); + if (mPausedShortTermModel != null) { + if (!mPausedShortTermModel.maybeReset(mAmbientLux)) { + setScreenBrightnessByUser(mPausedShortTermModel.mAnchor, + mPausedShortTermModel.mBrightness); + } + mPausedShortTermModel.copyFrom(tempShortTermModel); } - mPausedShortTermModel.copyFrom(tempShortTermModel); update(); } - void switchToInteractiveScreenBrightnessMode() { - if (!mCurrentBrightnessMapper.isForIdleMode()) { + void switchMode(@AutomaticBrightnessMode int mode) { + if (!mBrightnessMappingStrategyMap.contains(mode)) { return; } - Slog.i(TAG, "Switching to Interactive Screen Brightness Mode"); - ShortTermModel tempShortTermModel = new ShortTermModel(); - tempShortTermModel.set(mCurrentBrightnessMapper.getUserLux(), - mCurrentBrightnessMapper.getUserBrightness(), /* valid= */ true); - mHandler.removeMessages(MSG_INVALIDATE_PAUSED_SHORT_TERM_MODEL); - // Send delayed timeout - mHandler.sendEmptyMessageAtTime(MSG_INVALIDATE_PAUSED_SHORT_TERM_MODEL, - mClock.uptimeMillis() - + mCurrentBrightnessMapper.getShortTermModelTimeout()); - Slog.i(TAG, "mPreviousShortTermModel" + mPausedShortTermModel.toString()); - - // restore interactive mapper. - mCurrentBrightnessMapper = mInteractiveModeBrightnessMapper; - - // if previous stm has been invalidated, and lux has drastically changed, just use - // the new, reset stm. - // if previous stm is still valid then revalidate it - if (!mPausedShortTermModel.maybeReset(mAmbientLux)) { - setScreenBrightnessByUser(mPausedShortTermModel.mAnchor, - mPausedShortTermModel.mBrightness); + if (mCurrentBrightnessMapper.getMode() == mode) { + return; + } + Slog.i(TAG, "Switching to mode " + mode); + if (mode == AUTO_BRIGHTNESS_MODE_IDLE + || mCurrentBrightnessMapper.getMode() == AUTO_BRIGHTNESS_MODE_IDLE) { + switchModeAndShortTermModels(mode); + } else { + resetShortTermModel(); + mCurrentBrightnessMapper = mBrightnessMappingStrategyMap.get(mode); } - mPausedShortTermModel.copyFrom(tempShortTermModel); + } - update(); + float getUserLux() { + return mCurrentBrightnessMapper.getUserLux(); + } + + float getUserNits() { + return convertToNits(mCurrentBrightnessMapper.getUserBrightness()); } /** @@ -1187,14 +1177,11 @@ public class AutomaticBrightnessController { * passing the brightness value to follower displays. * * @param brightness The float scale value - * @return The nit value or -1f if no conversion is possible. + * @return The nit value or {@link BrightnessMappingStrategy.INVALID_NITS} if no conversion is + * possible. */ public float convertToNits(float brightness) { - if (mCurrentBrightnessMapper != null) { - return mCurrentBrightnessMapper.convertToNits(brightness); - } else { - return -1.0f; - } + return mCurrentBrightnessMapper.convertToNits(brightness); } /** @@ -1203,14 +1190,11 @@ public class AutomaticBrightnessController { * {@link com.android.server.display.BrightnessTracker}. * * @param brightness The float scale value - * @return The nit value or -1f if no conversion is possible. + * @return The nit value or {@link BrightnessMappingStrategy.INVALID_NITS} if no conversion is + * possible. */ public float convertToAdjustedNits(float brightness) { - if (mCurrentBrightnessMapper != null) { - return mCurrentBrightnessMapper.convertToAdjustedNits(brightness); - } else { - return -1.0f; - } + return mCurrentBrightnessMapper.convertToAdjustedNits(brightness); } /** @@ -1221,12 +1205,8 @@ public class AutomaticBrightnessController { * @return The float scale value or {@link PowerManager.BRIGHTNESS_INVALID_FLOAT} if no * conversion is possible. */ - public float convertToFloatScale(float nits) { - if (mCurrentBrightnessMapper != null) { - return mCurrentBrightnessMapper.convertToFloatScale(nits); - } else { - return PowerManager.BRIGHTNESS_INVALID_FLOAT; - } + public float getBrightnessFromNits(float nits) { + return mCurrentBrightnessMapper.getBrightnessFromNits(nits); } public void recalculateSplines(boolean applyAdjustment, float[] adjustment) { @@ -1244,19 +1224,27 @@ public class AutomaticBrightnessController { } } + private String modeToString(@AutomaticBrightnessMode int mode) { + return switch (mode) { + case AUTO_BRIGHTNESS_MODE_DEFAULT -> "default"; + case AUTO_BRIGHTNESS_MODE_IDLE -> "idle"; + default -> Integer.toString(mode); + }; + } + private class ShortTermModel { // When the short term model is invalidated, we don't necessarily reset it (i.e. clear the // user's adjustment) immediately, but wait for a drastic enough change in the ambient // light. // The anchor determines what were the light levels when the user has set their preference, // and we use a relative threshold to determine when to revert to the OEM curve. - private float mAnchor = BrightnessMappingStrategy.NO_USER_LUX; - private float mBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS; + private float mAnchor = BrightnessMappingStrategy.INVALID_LUX; + private float mBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; private boolean mIsValid = false; private void reset() { - mAnchor = BrightnessMappingStrategy.NO_USER_LUX; - mBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS; + mAnchor = BrightnessMappingStrategy.INVALID_LUX; + mBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; mIsValid = false; } @@ -1279,10 +1267,8 @@ public class AutomaticBrightnessController { private boolean maybeReset(float currentLux) { // If the short term model was invalidated and the change is drastic enough, reset it. // Otherwise, we revalidate it. - if (!mIsValid && mAnchor != -1) { - if (mCurrentBrightnessMapper != null - && mCurrentBrightnessMapper.shouldResetShortTermModel( - currentLux, mAnchor)) { + if (!mIsValid && mAnchor != BrightnessMappingStrategy.INVALID_LUX) { + if (mCurrentBrightnessMapper.shouldResetShortTermModel(currentLux, mAnchor)) { resetShortTermModel(); } else { mIsValid = true; @@ -1304,7 +1290,7 @@ public class AutomaticBrightnessController { } public String toString() { - return " mAnchor: " + mAnchor + return "mAnchor: " + mAnchor + "\n mBrightness: " + mBrightness + "\n mIsValid: " + mIsValid; } diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java index d848f4b6cce5..acd253b38b3d 100644 --- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java +++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java @@ -18,6 +18,9 @@ package com.android.server.display; import static android.text.TextUtils.formatSimple; +import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT; +import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE; + import android.annotation.Nullable; import android.content.pm.ApplicationInfo; import android.content.res.Resources; @@ -57,8 +60,8 @@ import java.util.Objects; public abstract class BrightnessMappingStrategy { private static final String TAG = "BrightnessMappingStrategy"; - public static final float NO_USER_LUX = -1; - public static final float NO_USER_BRIGHTNESS = -1; + public static final float INVALID_LUX = -1; + public static final float INVALID_NITS = -1; private static final float LUX_GRAD_SMOOTHING = 0.25f; private static final float MAX_GRAD = 1.0f; @@ -74,75 +77,48 @@ public abstract class BrightnessMappingStrategy { private static final Plog PLOG = Plog.createSystemPlog(TAG); /** - * Creates a BrightnessMappingStrategy for active (normal) mode. - * @param resources - * @param displayDeviceConfig - * @param displayWhiteBalanceController - * @return the BrightnessMappingStrategy - */ - @Nullable - public static BrightnessMappingStrategy create(Resources resources, - DisplayDeviceConfig displayDeviceConfig, - DisplayWhiteBalanceController displayWhiteBalanceController) { - return create(resources, displayDeviceConfig, /* isForIdleMode= */ false, - displayWhiteBalanceController); - } - - /** - * Creates a BrightnessMappingStrategy for idle screen brightness mode. - * @param resources - * @param displayDeviceConfig - * @param displayWhiteBalanceController - * @return the BrightnessMappingStrategy - */ - @Nullable - public static BrightnessMappingStrategy createForIdleMode(Resources resources, - DisplayDeviceConfig displayDeviceConfig, DisplayWhiteBalanceController - displayWhiteBalanceController) { - return create(resources, displayDeviceConfig, /* isForIdleMode= */ true, - displayWhiteBalanceController); - } - - /** - * Creates a BrightnessMapping strategy for either active or idle screen brightness mode. - * We do not create a simple mapping strategy for idle mode. + * Creates a BrightnessMapping strategy. We do not create a simple mapping strategy for idle + * mode. * * @param resources * @param displayDeviceConfig - * @param isForIdleMode determines whether the configurations loaded are for idle screen - * brightness mode or active screen brightness mode. + * @param mode The auto-brightness mode. Different modes use different brightness curves * @param displayWhiteBalanceController * @return the BrightnessMappingStrategy */ @Nullable - private static BrightnessMappingStrategy create(Resources resources, - DisplayDeviceConfig displayDeviceConfig, boolean isForIdleMode, + static BrightnessMappingStrategy create(Resources resources, + DisplayDeviceConfig displayDeviceConfig, + @AutomaticBrightnessController.AutomaticBrightnessMode int mode, DisplayWhiteBalanceController displayWhiteBalanceController) { // Display independent, mode dependent values - float[] brightnessLevelsNits; + float[] brightnessLevelsNits = null; float[] brightnessLevels = null; - float[] luxLevels; - if (isForIdleMode) { - brightnessLevelsNits = getFloatArray(resources.obtainTypedArray( - com.android.internal.R.array.config_autoBrightnessDisplayValuesNitsIdle)); - luxLevels = getLuxLevels(resources.getIntArray( - com.android.internal.R.array.config_autoBrightnessLevelsIdle)); - } else { - brightnessLevelsNits = displayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(); - luxLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(); - - brightnessLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevels(); - if (brightnessLevels == null || brightnessLevels.length == 0) { - // Load the old configuration in the range [0, 255]. The values need to be - // normalized to the range [0, 1]. - int[] brightnessLevelsInt = resources.getIntArray( - com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); - brightnessLevels = new float[brightnessLevelsInt.length]; - for (int i = 0; i < brightnessLevels.length; i++) { - brightnessLevels[i] = normalizeAbsoluteBrightness(brightnessLevelsInt[i]); + float[] luxLevels = null; + switch (mode) { + case AUTO_BRIGHTNESS_MODE_DEFAULT: + brightnessLevelsNits = displayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(); + luxLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(); + + brightnessLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevels(); + if (brightnessLevels == null || brightnessLevels.length == 0) { + // Load the old configuration in the range [0, 255]. The values need to be + // normalized to the range [0, 1]. + int[] brightnessLevelsInt = resources.getIntArray( + com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); + brightnessLevels = new float[brightnessLevelsInt.length]; + for (int i = 0; i < brightnessLevels.length; i++) { + brightnessLevels[i] = normalizeAbsoluteBrightness(brightnessLevelsInt[i]); + } } - } + break; + case AUTO_BRIGHTNESS_MODE_IDLE: + brightnessLevelsNits = getFloatArray(resources.obtainTypedArray( + com.android.internal.R.array.config_autoBrightnessDisplayValuesNitsIdle)); + luxLevels = getLuxLevels(resources.getIntArray( + com.android.internal.R.array.config_autoBrightnessLevelsIdle)); + break; } // Display independent, mode independent values @@ -158,17 +134,16 @@ public abstract class BrightnessMappingStrategy { if (isValidMapping(nitsRange, brightnessRange) && isValidMapping(luxLevels, brightnessLevelsNits)) { - BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder( luxLevels, brightnessLevelsNits); builder.setShortTermModelTimeoutMillis(shortTermModelTimeout); builder.setShortTermModelLowerLuxMultiplier(SHORT_TERM_MODEL_THRESHOLD_RATIO); builder.setShortTermModelUpperLuxMultiplier(SHORT_TERM_MODEL_THRESHOLD_RATIO); return new PhysicalMappingStrategy(builder.build(), nitsRange, brightnessRange, - autoBrightnessAdjustmentMaxGamma, isForIdleMode, displayWhiteBalanceController); + autoBrightnessAdjustmentMaxGamma, mode, displayWhiteBalanceController); } else if (isValidMapping(luxLevels, brightnessLevels)) { return new SimpleMappingStrategy(luxLevels, brightnessLevels, - autoBrightnessAdjustmentMaxGamma, shortTermModelTimeout); + autoBrightnessAdjustmentMaxGamma, shortTermModelTimeout, mode); } else { return null; } @@ -334,7 +309,7 @@ public abstract class BrightnessMappingStrategy { /** * Converts the provided brightness value to nits if possible. * - * Returns -1.0f if there's no available mapping for the brightness to nits. + * Returns {@link INVALID_NITS} if there's no available mapping for the brightness to nits. */ public abstract float convertToNits(float brightness); @@ -342,7 +317,7 @@ public abstract class BrightnessMappingStrategy { * Converts the provided brightness value to nits if possible. Adjustments, such as RBC are * applied. * - * Returns -1.0f if there's no available mapping for the brightness to nits. + * Returns {@link INVALID_NITS} if there's no available mapping for the brightness to nits. */ public abstract float convertToAdjustedNits(float brightness); @@ -352,7 +327,7 @@ public abstract class BrightnessMappingStrategy { * Returns {@link PowerManager.BRIGHTNESS_INVALID_FLOAT} if there's no available mapping for * the nits to float scale. */ - public abstract float convertToFloatScale(float nits); + public abstract float getBrightnessFromNits(float nits); /** * Adds a user interaction data point to the brightness mapping. @@ -407,17 +382,18 @@ public abstract class BrightnessMappingStrategy { */ public abstract void dump(PrintWriter pw, float hbmTransition); - /** - * We can designate a mapping strategy to be used for idle screen brightness mode. - * @return whether this mapping strategy is to be used for idle screen brightness mode. - */ - public abstract boolean isForIdleMode(); - abstract float getUserLux(); abstract float getUserBrightness(); /** + * @return The auto-brightness mode of this mapping strategy. Different modes use different + * brightness curves. + */ + @AutomaticBrightnessController.AutomaticBrightnessMode + abstract int getMode(); + + /** * Check if the short term model should be reset given the anchor lux the last * brightness change was made at and the current ambient lux. */ @@ -596,7 +572,7 @@ public abstract class BrightnessMappingStrategy { if (mLoggingEnabled) { PLOG.logCurve("gamma adjusted curve", newLux, newBrightness); } - if (userLux != -1) { + if (userLux != INVALID_LUX) { Pair<float[], float[]> curve = insertControlPoint(newLux, newBrightness, userLux, userBrightness); newLux = curve.first; @@ -624,6 +600,9 @@ public abstract class BrightnessMappingStrategy { // Brightness control points normalized to [0, 1] private final float[] mBrightness; + @AutomaticBrightnessController.AutomaticBrightnessMode + private final int mMode; + private Spline mSpline; private float mMaxGamma; private float mAutoBrightnessAdjustment; @@ -632,7 +611,7 @@ public abstract class BrightnessMappingStrategy { private long mShortTermModelTimeout; private SimpleMappingStrategy(float[] lux, float[] brightness, float maxGamma, - long timeout) { + long timeout, @AutomaticBrightnessController.AutomaticBrightnessMode int mode) { Preconditions.checkArgument(lux.length != 0 && brightness.length != 0, "Lux and brightness arrays must not be empty!"); Preconditions.checkArgument(lux.length == brightness.length, @@ -651,13 +630,14 @@ public abstract class BrightnessMappingStrategy { mMaxGamma = maxGamma; mAutoBrightnessAdjustment = 0; - mUserLux = NO_USER_LUX; - mUserBrightness = NO_USER_BRIGHTNESS; + mUserLux = INVALID_LUX; + mUserBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; if (mLoggingEnabled) { PLOG.start("simple mapping strategy"); } computeSpline(); mShortTermModelTimeout = timeout; + mMode = mode; } @Override @@ -704,16 +684,16 @@ public abstract class BrightnessMappingStrategy { @Override public float convertToNits(float brightness) { - return -1.0f; + return INVALID_NITS; } @Override public float convertToAdjustedNits(float brightness) { - return -1.0f; + return INVALID_NITS; } @Override - public float convertToFloatScale(float nits) { + public float getBrightnessFromNits(float nits) { return PowerManager.BRIGHTNESS_INVALID_FLOAT; } @@ -741,22 +721,22 @@ public abstract class BrightnessMappingStrategy { @Override public void clearUserDataPoints() { - if (mUserLux != -1) { + if (mUserLux != INVALID_LUX) { if (mLoggingEnabled) { Slog.d(TAG, "clearUserDataPoints: " + mAutoBrightnessAdjustment + " => 0"); PLOG.start("clear user data points") .logPoint("user data point", mUserLux, mUserBrightness); } mAutoBrightnessAdjustment = 0; - mUserLux = -1; - mUserBrightness = -1; + mUserLux = INVALID_LUX; + mUserBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; computeSpline(); } } @Override public boolean hasUserDataPoints() { - return mUserLux != -1; + return mUserLux != INVALID_LUX; } @Override @@ -782,11 +762,12 @@ public abstract class BrightnessMappingStrategy { pw.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment); pw.println(" mUserLux=" + mUserLux); pw.println(" mUserBrightness=" + mUserBrightness); + pw.println(" mShortTermModelTimeout=" + mShortTermModelTimeout); } @Override - public boolean isForIdleMode() { - return false; + int getMode() { + return mMode; } @Override @@ -854,9 +835,11 @@ public abstract class BrightnessMappingStrategy { private float mAutoBrightnessAdjustment; private float mUserLux; private float mUserBrightness; - private final boolean mIsForIdleMode; private final DisplayWhiteBalanceController mDisplayWhiteBalanceController; + @AutomaticBrightnessController.AutomaticBrightnessMode + private final int mMode; + // Previous short-term models and the times that they were computed stored for debugging // purposes private List<Spline> mPreviousBrightnessSplines = new ArrayList<>(); @@ -865,7 +848,8 @@ public abstract class BrightnessMappingStrategy { private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); public PhysicalMappingStrategy(BrightnessConfiguration config, float[] nits, - float[] brightness, float maxGamma, boolean isForIdleMode, + float[] brightness, float maxGamma, + @AutomaticBrightnessController.AutomaticBrightnessMode int mode, DisplayWhiteBalanceController displayWhiteBalanceController) { Preconditions.checkArgument(nits.length != 0 && brightness.length != 0, @@ -878,11 +862,11 @@ public abstract class BrightnessMappingStrategy { Preconditions.checkArrayElementsInRange(brightness, PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, "brightness"); - mIsForIdleMode = isForIdleMode; + mMode = mode; mMaxGamma = maxGamma; mAutoBrightnessAdjustment = 0; - mUserLux = NO_USER_LUX; - mUserBrightness = NO_USER_BRIGHTNESS; + mUserLux = INVALID_LUX; + mUserBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; mDisplayWhiteBalanceController = displayWhiteBalanceController; mNits = nits; @@ -982,7 +966,7 @@ public abstract class BrightnessMappingStrategy { } @Override - public float convertToFloatScale(float nits) { + public float getBrightnessFromNits(float nits) { return mNitsToBrightnessSpline.interpolate(nits); } @@ -1024,15 +1008,15 @@ public abstract class BrightnessMappingStrategy { .logPoint("user data point", mUserLux, mUserBrightness); } mAutoBrightnessAdjustment = 0; - mUserLux = -1; - mUserBrightness = -1; + mUserLux = INVALID_LUX; + mUserBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; computeSpline(); } } @Override public boolean hasUserDataPoints() { - return mUserLux != -1; + return mUserLux != INVALID_LUX; } @Override @@ -1072,6 +1056,7 @@ public abstract class BrightnessMappingStrategy { pw.println(" mUserBrightness=" + mUserBrightness); pw.println(" mDefaultConfig=" + mDefaultConfig); pw.println(" mBrightnessRangeAdjustmentApplied=" + mBrightnessRangeAdjustmentApplied); + pw.println(" shortTermModelTimeout=" + getShortTermModelTimeout()); pw.println(" Previous short-term models (oldest to newest): "); for (int i = 0; i < mPreviousBrightnessSplines.size(); i++) { @@ -1086,8 +1071,8 @@ public abstract class BrightnessMappingStrategy { } @Override - public boolean isForIdleMode() { - return mIsForIdleMode; + int getMode() { + return mMode; } @Override diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 2ab15e639d68..e38d08ff2a1a 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -2880,7 +2880,9 @@ public final class DisplayManagerService extends SystemService { final DisplayPowerControllerInterface displayPowerController = mDisplayPowerControllers.get(displayId); if (displayPowerController != null) { - displayPowerController.setAutomaticScreenBrightnessMode(enabled); + displayPowerController.setAutomaticScreenBrightnessMode(enabled + ? AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE + : AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT); } } } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 2cca72e4c883..2685efecd6a1 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -16,6 +16,9 @@ package com.android.server.display; +import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT; +import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE; + import android.animation.Animator; import android.animation.ObjectAnimator; import android.annotation.NonNull; @@ -53,7 +56,6 @@ import android.os.Trace; import android.os.UserHandle; import android.provider.Settings; import android.util.FloatProperty; -import android.util.Log; import android.util.MathUtils; import android.util.MutableFloat; import android.util.MutableInt; @@ -498,15 +500,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private Sensor mLightSensor; private Sensor mScreenOffBrightnessSensor; - // The mappers between ambient lux, display backlight values, and display brightness. - // We will switch between the idle mapper and active mapper in AutomaticBrightnessController. - // Mapper used for active (normal) screen brightness mode - @Nullable - private BrightnessMappingStrategy mInteractiveModeBrightnessMapper; - // Mapper used for idle screen brightness mode - @Nullable - private BrightnessMappingStrategy mIdleModeBrightnessMapper; - // The current brightness configuration. @Nullable private BrightnessConfiguration mBrightnessConfiguration; @@ -609,7 +602,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata, boolean bootCompleted, DisplayManagerFlags flags) { - + mFlags = flags; mInjector = injector != null ? injector : new Injector(); mClock = mInjector.getClock(); mLogicalDisplay = logicalDisplay; @@ -767,8 +760,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT; mBootCompleted = bootCompleted; - - mFlags = flags; } private void applyReduceBrightColorsSplineAdjustment() { @@ -780,13 +771,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (mAutomaticBrightnessController == null) { return; } - if ((!mAutomaticBrightnessController.isInIdleMode() - && mInteractiveModeBrightnessMapper == null) - || (mAutomaticBrightnessController.isInIdleMode() - && mIdleModeBrightnessMapper == null)) { - Log.w(mTag, "No brightness mapping available to recalculate splines for this mode"); - return; - } float[] adjustedNits = new float[mNitsRange.length]; for (int i = 0; i < mNitsRange.length; i++) { @@ -848,10 +832,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux, boolean slowChange) { mBrightnessRangeController.onAmbientLuxChange(ambientLux); - if (nits < 0) { + if (nits == BrightnessMappingStrategy.INVALID_NITS) { mBrightnessToFollow = leadDisplayBrightness; } else { - float brightness = convertToFloatScale(nits); + float brightness = getBrightnessFromNits(nits); if (isValidBrightnessValue(brightness)) { mBrightnessToFollow = brightness; } else { @@ -876,7 +860,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call synchronized (mLock) { mDisplayBrightnessFollowers.remove(follower.getDisplayId()); mHandler.postAtTime(() -> follower.setBrightnessToFollow( - PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1, + PowerManager.BRIGHTNESS_INVALID_FLOAT, BrightnessMappingStrategy.INVALID_NITS, /* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis()); } } @@ -886,7 +870,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call for (int i = 0; i < mDisplayBrightnessFollowers.size(); i++) { DisplayPowerControllerInterface follower = mDisplayBrightnessFollowers.valueAt(i); mHandler.postAtTime(() -> follower.setBrightnessToFollow( - PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1, + PowerManager.BRIGHTNESS_INVALID_FLOAT, BrightnessMappingStrategy.INVALID_NITS, /* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis()); } mDisplayBrightnessFollowers.clear(); @@ -1168,24 +1152,35 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call return; } - float userLux = BrightnessMappingStrategy.NO_USER_LUX; - float userNits = -1; - if (mInteractiveModeBrightnessMapper != null) { - userLux = mInteractiveModeBrightnessMapper.getUserLux(); - float userBrightness = mInteractiveModeBrightnessMapper.getUserBrightness(); - userNits = mInteractiveModeBrightnessMapper.convertToNits(userBrightness); - } + SparseArray<BrightnessMappingStrategy> brightnessMappers = new SparseArray<>(); + + BrightnessMappingStrategy defaultModeBrightnessMapper = + mInjector.getDefaultModeBrightnessMapper(resources, mDisplayDeviceConfig, + mDisplayWhiteBalanceController); + brightnessMappers.append(AUTO_BRIGHTNESS_MODE_DEFAULT, + defaultModeBrightnessMapper); final boolean isIdleScreenBrightnessEnabled = resources.getBoolean( R.bool.config_enableIdleScreenBrightnessMode); - mInteractiveModeBrightnessMapper = mInjector.getInteractiveModeBrightnessMapper(resources, - mDisplayDeviceConfig, mDisplayWhiteBalanceController); if (isIdleScreenBrightnessEnabled) { - mIdleModeBrightnessMapper = BrightnessMappingStrategy.createForIdleMode(resources, - mDisplayDeviceConfig, mDisplayWhiteBalanceController); + BrightnessMappingStrategy idleModeBrightnessMapper = + BrightnessMappingStrategy.create(resources, mDisplayDeviceConfig, + AUTO_BRIGHTNESS_MODE_IDLE, + mDisplayWhiteBalanceController); + if (idleModeBrightnessMapper != null) { + brightnessMappers.append(AUTO_BRIGHTNESS_MODE_IDLE, + idleModeBrightnessMapper); + } + } + + float userLux = BrightnessMappingStrategy.INVALID_LUX; + float userNits = BrightnessMappingStrategy.INVALID_NITS; + if (mAutomaticBrightnessController != null) { + userLux = mAutomaticBrightnessController.getUserLux(); + userNits = mAutomaticBrightnessController.getUserNits(); } - if (mInteractiveModeBrightnessMapper != null) { + if (defaultModeBrightnessMapper != null) { final float dozeScaleFactor = resources.getFraction( com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor, 1, 1); @@ -1297,25 +1292,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (mAutomaticBrightnessController != null) { mAutomaticBrightnessController.stop(); } - float userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS; - if (userNits >= 0) { - userBrightness = mInteractiveModeBrightnessMapper.convertToFloatScale(userNits); - if (Float.isNaN(userBrightness)) { - userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS; - } - } mAutomaticBrightnessController = mInjector.getAutomaticBrightnessController( this, handler.getLooper(), mSensorManager, mLightSensor, - mInteractiveModeBrightnessMapper, lightSensorWarmUpTimeConfig, - PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, dozeScaleFactor, - lightSensorRate, initialLightSensorRate, brighteningLightDebounce, - darkeningLightDebounce, brighteningLightDebounceIdle, - darkeningLightDebounceIdle, autoBrightnessResetAmbientLuxAfterWarmUp, - ambientBrightnessThresholds, screenBrightnessThresholds, - ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, mContext, - mBrightnessRangeController, mBrightnessThrottler, mIdleModeBrightnessMapper, - mDisplayDeviceConfig.getAmbientHorizonShort(), - mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userBrightness); + brightnessMappers, lightSensorWarmUpTimeConfig, PowerManager.BRIGHTNESS_MIN, + PowerManager.BRIGHTNESS_MAX, dozeScaleFactor, lightSensorRate, + initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce, + brighteningLightDebounceIdle, darkeningLightDebounceIdle, + autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds, + screenBrightnessThresholds, ambientBrightnessThresholdsIdle, + screenBrightnessThresholdsIdle, mContext, mBrightnessRangeController, + mBrightnessThrottler, mDisplayDeviceConfig.getAmbientHorizonShort(), + mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userNits); mBrightnessEventRingBuffer = new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX); @@ -1334,7 +1321,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mHandler, SystemClock::uptimeMillis, sensorValueToLux, - mInteractiveModeBrightnessMapper); + defaultModeBrightnessMapper); } } else { mUseSoftwareAutoBrightnessConfig = false; @@ -1377,13 +1364,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } @Override - public void setAutomaticScreenBrightnessMode(boolean isIdle) { + public void setAutomaticScreenBrightnessMode( + @AutomaticBrightnessController.AutomaticBrightnessMode int mode) { + boolean isIdle = mode == AUTO_BRIGHTNESS_MODE_IDLE; if (mAutomaticBrightnessController != null) { - if (isIdle) { - mAutomaticBrightnessController.switchToIdleMode(); - } else { - mAutomaticBrightnessController.switchToInteractiveScreenBrightnessMode(); - } + mAutomaticBrightnessController.switchMode(mode); setAnimatorRampSpeeds(isIdle); } @@ -2810,7 +2795,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call float brightnessNitsForDefaultDisplay = mBrightnessSetting.getBrightnessNitsForDefaultDisplay(); if (brightnessNitsForDefaultDisplay >= 0) { - float brightnessForDefaultDisplay = convertToFloatScale( + float brightnessForDefaultDisplay = getBrightnessFromNits( brightnessNitsForDefaultDisplay); if (isValidBrightnessValue(brightnessForDefaultDisplay)) { mBrightnessSetting.setBrightness(brightnessForDefaultDisplay); @@ -2944,23 +2929,23 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private float convertToNits(float brightness) { if (mAutomaticBrightnessController == null) { - return -1f; + return BrightnessMappingStrategy.INVALID_NITS; } return mAutomaticBrightnessController.convertToNits(brightness); } private float convertToAdjustedNits(float brightness) { if (mAutomaticBrightnessController == null) { - return -1f; + return BrightnessMappingStrategy.INVALID_NITS; } return mAutomaticBrightnessController.convertToAdjustedNits(brightness); } - private float convertToFloatScale(float nits) { + private float getBrightnessFromNits(float nits) { if (mAutomaticBrightnessController == null) { return PowerManager.BRIGHTNESS_INVALID_FLOAT; } - return mAutomaticBrightnessController.convertToFloatScale(nits); + return mAutomaticBrightnessController.getBrightnessFromNits(nits); } @GuardedBy("mLock") @@ -3635,7 +3620,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call AutomaticBrightnessController getAutomaticBrightnessController( AutomaticBrightnessController.Callbacks callbacks, Looper looper, SensorManager sensorManager, Sensor lightSensor, - BrightnessMappingStrategy interactiveModeBrightnessMapper, + SparseArray<BrightnessMappingStrategy> brightnessMappingStrategyMap, int lightSensorWarmUpTime, float brightnessMin, float brightnessMax, float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, @@ -3645,27 +3630,27 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call HysteresisLevels screenBrightnessThresholds, HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels screenBrightnessThresholdsIdle, Context context, - BrightnessRangeController brightnessRangeController, - BrightnessThrottler brightnessThrottler, - BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort, - int ambientLightHorizonLong, float userLux, float userBrightness) { + BrightnessRangeController brightnessModeController, + BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort, + int ambientLightHorizonLong, float userLux, float userNits) { return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor, - interactiveModeBrightnessMapper, lightSensorWarmUpTime, brightnessMin, + brightnessMappingStrategyMap, lightSensorWarmUpTime, brightnessMin, brightnessMax, dozeScaleFactor, lightSensorRate, initialLightSensorRate, brighteningLightDebounceConfig, darkeningLightDebounceConfig, brighteningLightDebounceConfigIdle, darkeningLightDebounceConfigIdle, resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds, screenBrightnessThresholds, ambientBrightnessThresholdsIdle, - screenBrightnessThresholdsIdle, context, brightnessRangeController, - brightnessThrottler, idleModeBrightnessMapper, ambientLightHorizonShort, - ambientLightHorizonLong, userLux, userBrightness); + screenBrightnessThresholdsIdle, context, brightnessModeController, + brightnessThrottler, ambientLightHorizonShort, ambientLightHorizonLong, userLux, + userNits); } - BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources, + BrightnessMappingStrategy getDefaultModeBrightnessMapper(Resources resources, DisplayDeviceConfig displayDeviceConfig, DisplayWhiteBalanceController displayWhiteBalanceController) { return BrightnessMappingStrategy.create(resources, - displayDeviceConfig, displayWhiteBalanceController); + displayDeviceConfig, AUTO_BRIGHTNESS_MODE_DEFAULT, + displayWhiteBalanceController); } HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages, diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java index 810ac08e32c1..52c53f3d658e 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController2.java +++ b/services/core/java/com/android/server/display/DisplayPowerController2.java @@ -16,6 +16,9 @@ package com.android.server.display; +import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT; +import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE; + import android.animation.Animator; import android.animation.ObjectAnimator; import android.annotation.Nullable; @@ -52,7 +55,6 @@ import android.os.UserHandle; import android.provider.Settings; import android.util.FloatProperty; import android.util.IndentingPrintWriter; -import android.util.Log; import android.util.MathUtils; import android.util.MutableFloat; import android.util.MutableInt; @@ -442,15 +444,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal private Sensor mLightSensor; private Sensor mScreenOffBrightnessSensor; - // The mappers between ambient lux, display backlight values, and display brightness. - // We will switch between the idle mapper and active mapper in AutomaticBrightnessController. - // Mapper used for active (normal) screen brightness mode - @Nullable - private BrightnessMappingStrategy mInteractiveModeBrightnessMapper; - // Mapper used for idle screen brightness mode - @Nullable - private BrightnessMappingStrategy mIdleModeBrightnessMapper; - private boolean mIsRbcActive; // Animators. @@ -490,7 +483,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal BrightnessTracker brightnessTracker, BrightnessSetting brightnessSetting, Runnable onBrightnessChangeRunnable, HighBrightnessModeMetadata hbmMetadata, boolean bootCompleted, DisplayManagerFlags flags) { - + mFlags = flags; mInjector = injector != null ? injector : new Injector(); mClock = mInjector.getClock(); mLogicalDisplay = logicalDisplay; @@ -636,7 +629,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal R.bool.config_displayBrightnessBucketsInDoze); mBootCompleted = bootCompleted; - mFlags = flags; } private void applyReduceBrightColorsSplineAdjustment() { @@ -648,13 +640,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal if (mAutomaticBrightnessController == null) { return; } - if ((!mAutomaticBrightnessController.isInIdleMode() - && mInteractiveModeBrightnessMapper == null) - || (mAutomaticBrightnessController.isInIdleMode() - && mIdleModeBrightnessMapper == null)) { - Log.w(mTag, "No brightness mapping available to recalculate splines for this mode"); - return; - } float[] adjustedNits = new float[mNitsRange.length]; for (int i = 0; i < mNitsRange.length; i++) { @@ -987,24 +972,35 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal return; } - float userLux = BrightnessMappingStrategy.NO_USER_LUX; - float userNits = -1; - if (mInteractiveModeBrightnessMapper != null) { - userLux = mInteractiveModeBrightnessMapper.getUserLux(); - float userBrightness = mInteractiveModeBrightnessMapper.getUserBrightness(); - userNits = mInteractiveModeBrightnessMapper.convertToNits(userBrightness); - } + SparseArray<BrightnessMappingStrategy> brightnessMappers = new SparseArray<>(); + + BrightnessMappingStrategy defaultModeBrightnessMapper = + mInjector.getDefaultModeBrightnessMapper(resources, mDisplayDeviceConfig, + mDisplayWhiteBalanceController); + brightnessMappers.append(AUTO_BRIGHTNESS_MODE_DEFAULT, + defaultModeBrightnessMapper); final boolean isIdleScreenBrightnessEnabled = resources.getBoolean( R.bool.config_enableIdleScreenBrightnessMode); - mInteractiveModeBrightnessMapper = mInjector.getInteractiveModeBrightnessMapper(resources, - mDisplayDeviceConfig, mDisplayWhiteBalanceController); if (isIdleScreenBrightnessEnabled) { - mIdleModeBrightnessMapper = BrightnessMappingStrategy.createForIdleMode(resources, - mDisplayDeviceConfig, mDisplayWhiteBalanceController); + BrightnessMappingStrategy idleModeBrightnessMapper = + BrightnessMappingStrategy.create(resources, mDisplayDeviceConfig, + AUTO_BRIGHTNESS_MODE_IDLE, + mDisplayWhiteBalanceController); + if (idleModeBrightnessMapper != null) { + brightnessMappers.append(AUTO_BRIGHTNESS_MODE_IDLE, + idleModeBrightnessMapper); + } + } + + float userLux = BrightnessMappingStrategy.INVALID_LUX; + float userNits = BrightnessMappingStrategy.INVALID_NITS; + if (mAutomaticBrightnessController != null) { + userLux = mAutomaticBrightnessController.getUserLux(); + userNits = mAutomaticBrightnessController.getUserNits(); } - if (mInteractiveModeBrightnessMapper != null) { + if (defaultModeBrightnessMapper != null) { final float dozeScaleFactor = resources.getFraction( R.fraction.config_screenAutoBrightnessDozeScaleFactor, 1, 1); @@ -1116,25 +1112,17 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal if (mAutomaticBrightnessController != null) { mAutomaticBrightnessController.stop(); } - float userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS; - if (userNits >= 0) { - userBrightness = mInteractiveModeBrightnessMapper.convertToFloatScale(userNits); - if (Float.isNaN(userBrightness)) { - userBrightness = BrightnessMappingStrategy.NO_USER_BRIGHTNESS; - } - } mAutomaticBrightnessController = mInjector.getAutomaticBrightnessController( this, handler.getLooper(), mSensorManager, mLightSensor, - mInteractiveModeBrightnessMapper, lightSensorWarmUpTimeConfig, - PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, dozeScaleFactor, - lightSensorRate, initialLightSensorRate, brighteningLightDebounce, - darkeningLightDebounce, brighteningLightDebounceIdle, - darkeningLightDebounceIdle, autoBrightnessResetAmbientLuxAfterWarmUp, - ambientBrightnessThresholds, screenBrightnessThresholds, - ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, mContext, - mBrightnessRangeController, mBrightnessThrottler, mIdleModeBrightnessMapper, - mDisplayDeviceConfig.getAmbientHorizonShort(), - mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userBrightness); + brightnessMappers, lightSensorWarmUpTimeConfig, PowerManager.BRIGHTNESS_MIN, + PowerManager.BRIGHTNESS_MAX, dozeScaleFactor, lightSensorRate, + initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce, + brighteningLightDebounceIdle, darkeningLightDebounceIdle, + autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds, + screenBrightnessThresholds, ambientBrightnessThresholdsIdle, + screenBrightnessThresholdsIdle, mContext, mBrightnessRangeController, + mBrightnessThrottler, mDisplayDeviceConfig.getAmbientHorizonShort(), + mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userNits); mDisplayBrightnessController.setAutomaticBrightnessController( mAutomaticBrightnessController); @@ -1157,7 +1145,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mHandler, SystemClock::uptimeMillis, sensorValueToLux, - mInteractiveModeBrightnessMapper); + defaultModeBrightnessMapper); } } else { mUseSoftwareAutoBrightnessConfig = false; @@ -1200,13 +1188,11 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } @Override - public void setAutomaticScreenBrightnessMode(boolean isIdle) { + public void setAutomaticScreenBrightnessMode( + @AutomaticBrightnessController.AutomaticBrightnessMode int mode) { + boolean isIdle = mode == AUTO_BRIGHTNESS_MODE_IDLE; if (mAutomaticBrightnessController != null) { - if (isIdle) { - mAutomaticBrightnessController.switchToIdleMode(); - } else { - mAutomaticBrightnessController.switchToInteractiveScreenBrightnessMode(); - } + mAutomaticBrightnessController.switchMode(mode); setAnimatorRampSpeeds(isIdle); } Message msg = mHandler.obtainMessage(); @@ -2351,10 +2337,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux, boolean slowChange) { mBrightnessRangeController.onAmbientLuxChange(ambientLux); - if (nits < 0) { + if (nits == BrightnessMappingStrategy.INVALID_NITS) { mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness, slowChange); } else { - float brightness = mDisplayBrightnessController.convertToFloatScale(nits); + float brightness = mDisplayBrightnessController.getBrightnessFromNits(nits); if (BrightnessUtils.isValidBrightnessValue(brightness)) { mDisplayBrightnessController.setBrightnessToFollow(brightness, slowChange); } else { @@ -2421,7 +2407,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal synchronized (mLock) { mDisplayBrightnessFollowers.remove(follower.getDisplayId()); mHandler.postAtTime(() -> follower.setBrightnessToFollow( - PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1, + PowerManager.BRIGHTNESS_INVALID_FLOAT, BrightnessMappingStrategy.INVALID_NITS, /* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis()); } } @@ -2431,7 +2417,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal for (int i = 0; i < mDisplayBrightnessFollowers.size(); i++) { DisplayPowerControllerInterface follower = mDisplayBrightnessFollowers.valueAt(i); mHandler.postAtTime(() -> follower.setBrightnessToFollow( - PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1, + PowerManager.BRIGHTNESS_INVALID_FLOAT, BrightnessMappingStrategy.INVALID_NITS, /* ambientLux= */ 0, /* slowChange= */ false), mClock.uptimeMillis()); } mDisplayBrightnessFollowers.clear(); @@ -3012,7 +2998,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal AutomaticBrightnessController getAutomaticBrightnessController( AutomaticBrightnessController.Callbacks callbacks, Looper looper, SensorManager sensorManager, Sensor lightSensor, - BrightnessMappingStrategy interactiveModeBrightnessMapper, + SparseArray<BrightnessMappingStrategy> brightnessMappingStrategyMap, int lightSensorWarmUpTime, float brightnessMin, float brightnessMax, float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, @@ -3023,26 +3009,26 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels screenBrightnessThresholdsIdle, Context context, BrightnessRangeController brightnessModeController, - BrightnessThrottler brightnessThrottler, - BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort, - int ambientLightHorizonLong, float userLux, float userBrightness) { + BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort, + int ambientLightHorizonLong, float userLux, float userNits) { return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor, - interactiveModeBrightnessMapper, lightSensorWarmUpTime, brightnessMin, + brightnessMappingStrategyMap, lightSensorWarmUpTime, brightnessMin, brightnessMax, dozeScaleFactor, lightSensorRate, initialLightSensorRate, brighteningLightDebounceConfig, darkeningLightDebounceConfig, brighteningLightDebounceConfigIdle, darkeningLightDebounceConfigIdle, resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds, screenBrightnessThresholds, ambientBrightnessThresholdsIdle, screenBrightnessThresholdsIdle, context, brightnessModeController, - brightnessThrottler, idleModeBrightnessMapper, ambientLightHorizonShort, - ambientLightHorizonLong, userLux, userBrightness); + brightnessThrottler, ambientLightHorizonShort, ambientLightHorizonLong, userLux, + userNits); } - BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources, + BrightnessMappingStrategy getDefaultModeBrightnessMapper(Resources resources, DisplayDeviceConfig displayDeviceConfig, DisplayWhiteBalanceController displayWhiteBalanceController) { return BrightnessMappingStrategy.create(resources, - displayDeviceConfig, displayWhiteBalanceController); + displayDeviceConfig, AUTO_BRIGHTNESS_MODE_DEFAULT, + displayWhiteBalanceController); } HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages, diff --git a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java index 72079a4c82fe..c27918430254 100644 --- a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java +++ b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java @@ -69,9 +69,10 @@ public interface DisplayPowerControllerInterface { /** * Used to decide the associated AutomaticBrightnessController's BrightnessMode - * @param isIdle Flag which represents if the Idle BrightnessMode is to be set + * @param mode The auto-brightness mode */ - void setAutomaticScreenBrightnessMode(boolean isIdle); + void setAutomaticScreenBrightnessMode( + @AutomaticBrightnessController.AutomaticBrightnessMode int mode); /** * Used to enable/disable the logging of the WhileBalance associated entities diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java index 617befbbd17d..3bb798689ea6 100644 --- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java +++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java @@ -27,6 +27,7 @@ import android.view.Display; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.display.AutomaticBrightnessController; +import com.android.server.display.BrightnessMappingStrategy; import com.android.server.display.BrightnessSetting; import com.android.server.display.DisplayBrightnessState; import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy; @@ -359,11 +360,12 @@ public final class DisplayBrightnessController { * passing the brightness value to follower displays. * * @param brightness The float scale value - * @return The nit value or -1f if no conversion is possible. + * @return The nit value or {@link BrightnessMappingStrategy.INVALID_NITS} if no conversion is + * possible. */ public float convertToNits(float brightness) { if (mAutomaticBrightnessController == null) { - return -1f; + return BrightnessMappingStrategy.INVALID_NITS; } return mAutomaticBrightnessController.convertToNits(brightness); } @@ -374,11 +376,12 @@ public final class DisplayBrightnessController { * {@link com.android.server.display.BrightnessTracker}. * * @param brightness The float scale value - * @return The nit value or -1f if no conversion is possible. + * @return The nit value or {@link BrightnessMappingStrategy.INVALID_NITS} if no conversion is + * possible. */ public float convertToAdjustedNits(float brightness) { if (mAutomaticBrightnessController == null) { - return -1f; + return BrightnessMappingStrategy.INVALID_NITS; } return mAutomaticBrightnessController.convertToAdjustedNits(brightness); } @@ -391,11 +394,11 @@ public final class DisplayBrightnessController { * @return The float scale value or {@link PowerManager.BRIGHTNESS_INVALID_FLOAT} if no * conversion is possible. */ - public float convertToFloatScale(float nits) { + public float getBrightnessFromNits(float nits) { if (mAutomaticBrightnessController == null) { return PowerManager.BRIGHTNESS_INVALID_FLOAT; } - return mAutomaticBrightnessController.convertToFloatScale(nits); + return mAutomaticBrightnessController.getBrightnessFromNits(nits); } /** @@ -497,7 +500,7 @@ public final class DisplayBrightnessController { float brightnessNitsForDefaultDisplay = mBrightnessSetting.getBrightnessNitsForDefaultDisplay(); if (brightnessNitsForDefaultDisplay >= 0) { - float brightnessForDefaultDisplay = convertToFloatScale( + float brightnessForDefaultDisplay = getBrightnessFromNits( brightnessNitsForDefaultDisplay); if (BrightnessUtils.isValidBrightnessValue(brightnessForDefaultDisplay)) { mBrightnessSetting.setBrightness(brightnessForDefaultDisplay); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 2df965c5a83f..f3922f9917ba 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -182,6 +182,7 @@ import static com.android.server.wm.ActivityRecordProto.PROVIDES_MAX_BOUNDS; import static com.android.server.wm.ActivityRecordProto.REPORTED_DRAWN; import static com.android.server.wm.ActivityRecordProto.REPORTED_VISIBLE; import static com.android.server.wm.ActivityRecordProto.SHOULD_FORCE_ROTATE_FOR_CAMERA_COMPAT; +import static com.android.server.wm.ActivityRecordProto.SHOULD_OVERRIDE_MIN_ASPECT_RATIO; import static com.android.server.wm.ActivityRecordProto.SHOULD_REFRESH_ACTIVITY_FOR_CAMERA_COMPAT; import static com.android.server.wm.ActivityRecordProto.SHOULD_REFRESH_ACTIVITY_VIA_PAUSE_FOR_CAMERA_COMPAT; import static com.android.server.wm.ActivityRecordProto.SHOULD_SEND_COMPAT_FAKE_FOCUS; @@ -10357,6 +10358,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mLetterboxUiController.shouldRefreshActivityForCameraCompat()); proto.write(SHOULD_REFRESH_ACTIVITY_VIA_PAUSE_FOR_CAMERA_COMPAT, mLetterboxUiController.shouldRefreshActivityViaPauseForCameraCompat()); + proto.write(SHOULD_OVERRIDE_MIN_ASPECT_RATIO, + mLetterboxUiController.shouldOverrideMinAspectRatio()); } @Override diff --git a/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java index 2bdebe26e551..418b78cd696b 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java @@ -17,6 +17,8 @@ package com.android.server.display; import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED; +import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT; +import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -39,7 +41,9 @@ import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; import android.os.Handler; +import android.os.PowerManager; import android.os.test.TestLooper; +import android.util.SparseArray; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -98,8 +102,8 @@ public class AutomaticBrightnessControllerTest { mLightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, "Light Sensor"); mContext = InstrumentationRegistry.getContext(); - setupController(BrightnessMappingStrategy.NO_USER_LUX, - BrightnessMappingStrategy.NO_USER_BRIGHTNESS, /* applyDebounce= */ false, + setupController(BrightnessMappingStrategy.INVALID_LUX, + BrightnessMappingStrategy.INVALID_NITS, /* applyDebounce= */ false, /* useHorizon= */ true); } @@ -112,11 +116,19 @@ public class AutomaticBrightnessControllerTest { } } - private void setupController(float userLux, float userBrightness, boolean applyDebounce, + private void setupController(float userLux, float userNits, boolean applyDebounce, boolean useHorizon) { mClock = new OffsettableClock.Stopped(); mTestLooper = new TestLooper(mClock::now); + when(mBrightnessMappingStrategy.getMode()).thenReturn(AUTO_BRIGHTNESS_MODE_DEFAULT); + when(mIdleBrightnessMappingStrategy.getMode()).thenReturn(AUTO_BRIGHTNESS_MODE_IDLE); + + SparseArray<BrightnessMappingStrategy> brightnessMappingStrategyMap = new SparseArray<>(); + brightnessMappingStrategyMap.append(AUTO_BRIGHTNESS_MODE_DEFAULT, + mBrightnessMappingStrategy); + brightnessMappingStrategyMap.append(AUTO_BRIGHTNESS_MODE_IDLE, + mIdleBrightnessMappingStrategy); mController = new AutomaticBrightnessController( new AutomaticBrightnessController.Injector() { @Override @@ -131,7 +143,7 @@ public class AutomaticBrightnessControllerTest { }, // pass in test looper instead, pass in offsettable clock () -> { }, mTestLooper.getLooper(), mSensorManager, mLightSensor, - mBrightnessMappingStrategy, LIGHT_SENSOR_WARMUP_TIME, BRIGHTNESS_MIN_FLOAT, + brightnessMappingStrategyMap, LIGHT_SENSOR_WARMUP_TIME, BRIGHTNESS_MIN_FLOAT, BRIGHTNESS_MAX_FLOAT, DOZE_SCALE_FACTOR, LIGHT_SENSOR_RATE, INITIAL_LIGHT_SENSOR_RATE, applyDebounce ? BRIGHTENING_LIGHT_DEBOUNCE_CONFIG : 0, applyDebounce ? DARKENING_LIGHT_DEBOUNCE_CONFIG : 0, @@ -141,8 +153,8 @@ public class AutomaticBrightnessControllerTest { mAmbientBrightnessThresholds, mScreenBrightnessThresholds, mAmbientBrightnessThresholdsIdle, mScreenBrightnessThresholdsIdle, mContext, mBrightnessRangeController, mBrightnessThrottler, - mIdleBrightnessMappingStrategy, useHorizon ? AMBIENT_LIGHT_HORIZON_SHORT : 1, - useHorizon ? AMBIENT_LIGHT_HORIZON_LONG : 10000, userLux, userBrightness + useHorizon ? AMBIENT_LIGHT_HORIZON_SHORT : 1, + useHorizon ? AMBIENT_LIGHT_HORIZON_LONG : 10000, userLux, userNits ); when(mBrightnessRangeController.getCurrentBrightnessMax()).thenReturn( @@ -326,8 +338,7 @@ public class AutomaticBrightnessControllerTest { when(mBrightnessMappingStrategy.getShortTermModelTimeout()).thenReturn(2000L); - mController.switchToIdleMode(); - when(mIdleBrightnessMappingStrategy.isForIdleMode()).thenReturn(true); + mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE); when(mBrightnessMappingStrategy.shouldResetShortTermModel( 123f, 0.5f)).thenReturn(true); @@ -337,7 +348,7 @@ public class AutomaticBrightnessControllerTest { mBrightnessMappingStrategy.getShortTermModelTimeout() + 1000); mTestLooper.dispatchAll(); - mController.switchToInteractiveScreenBrightnessMode(); + mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT); mTestLooper.moveTimeForward(4000); mTestLooper.dispatchAll(); @@ -371,15 +382,14 @@ public class AutomaticBrightnessControllerTest { when(mBrightnessMappingStrategy.getUserBrightness()).thenReturn(0.51f); when(mBrightnessMappingStrategy.getUserLux()).thenReturn(123.0f); - mController.switchToIdleMode(); - when(mIdleBrightnessMappingStrategy.isForIdleMode()).thenReturn(true); + mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE); // Time does not move forward, since clock is doesn't increment naturally. mTestLooper.dispatchAll(); // Sensor reads 100000 lux, listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 678910)); - mController.switchToInteractiveScreenBrightnessMode(); + mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT); // Verify short term model is not reset. verify(mBrightnessMappingStrategy, never()).clearUserDataPoints(); @@ -410,10 +420,11 @@ public class AutomaticBrightnessControllerTest { when(mBrightnessMappingStrategy.getUserBrightness()).thenReturn(0.5f); when(mBrightnessMappingStrategy.getUserLux()).thenReturn(123f); - mController.switchToIdleMode(); - when(mIdleBrightnessMappingStrategy.isForIdleMode()).thenReturn(true); - when(mIdleBrightnessMappingStrategy.getUserBrightness()).thenReturn(-1f); - when(mIdleBrightnessMappingStrategy.getUserLux()).thenReturn(-1f); + mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE); + when(mIdleBrightnessMappingStrategy.getUserBrightness()).thenReturn( + PowerManager.BRIGHTNESS_INVALID_FLOAT); + when(mIdleBrightnessMappingStrategy.getUserLux()).thenReturn( + BrightnessMappingStrategy.INVALID_LUX); when(mBrightnessMappingStrategy.shouldResetShortTermModel( 123f, 0.5f)).thenReturn(true); @@ -423,7 +434,7 @@ public class AutomaticBrightnessControllerTest { mBrightnessMappingStrategy.getShortTermModelTimeout() + 1000); mTestLooper.dispatchAll(); - mController.switchToInteractiveScreenBrightnessMode(); + mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT); mTestLooper.moveTimeForward(4000); mTestLooper.dispatchAll(); @@ -456,10 +467,11 @@ public class AutomaticBrightnessControllerTest { when(mBrightnessMappingStrategy.getUserBrightness()).thenReturn(0.5f); when(mBrightnessMappingStrategy.getUserLux()).thenReturn(123f); - mController.switchToIdleMode(); - when(mIdleBrightnessMappingStrategy.isForIdleMode()).thenReturn(true); - when(mIdleBrightnessMappingStrategy.getUserBrightness()).thenReturn(-1f); - when(mIdleBrightnessMappingStrategy.getUserLux()).thenReturn(-1f); + mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE); + when(mIdleBrightnessMappingStrategy.getUserBrightness()).thenReturn( + PowerManager.BRIGHTNESS_INVALID_FLOAT); + when(mIdleBrightnessMappingStrategy.getUserLux()).thenReturn( + BrightnessMappingStrategy.INVALID_LUX); when(mBrightnessMappingStrategy.shouldResetShortTermModel( 123f, 0.5f)).thenReturn(true); @@ -469,7 +481,7 @@ public class AutomaticBrightnessControllerTest { // Do not fast-forward time. mTestLooper.dispatchAll(); - mController.switchToInteractiveScreenBrightnessMode(); + mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT); // Do not fast-forward time mTestLooper.dispatchAll(); @@ -492,22 +504,25 @@ public class AutomaticBrightnessControllerTest { // Sensor reads 123 lux, listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 123)); when(mBrightnessMappingStrategy.getShortTermModelTimeout()).thenReturn(2000L); - when(mBrightnessMappingStrategy.getUserBrightness()).thenReturn(-1.0f); - when(mBrightnessMappingStrategy.getUserLux()).thenReturn(-1.0f); + when(mBrightnessMappingStrategy.getUserBrightness()).thenReturn( + PowerManager.BRIGHTNESS_INVALID_FLOAT); + when(mBrightnessMappingStrategy.getUserLux()).thenReturn( + BrightnessMappingStrategy.INVALID_LUX); // No user brightness interaction. - mController.switchToIdleMode(); - when(mIdleBrightnessMappingStrategy.isForIdleMode()).thenReturn(true); - when(mIdleBrightnessMappingStrategy.getUserBrightness()).thenReturn(-1.0f); - when(mIdleBrightnessMappingStrategy.getUserLux()).thenReturn(-1.0f); + mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE); + when(mIdleBrightnessMappingStrategy.getUserBrightness()).thenReturn( + PowerManager.BRIGHTNESS_INVALID_FLOAT); + when(mIdleBrightnessMappingStrategy.getUserLux()).thenReturn( + BrightnessMappingStrategy.INVALID_LUX); // Sensor reads 1000 lux, listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 1000)); // Do not fast-forward time. mTestLooper.dispatchAll(); - mController.switchToInteractiveScreenBrightnessMode(); + mController.switchMode(AUTO_BRIGHTNESS_MODE_DEFAULT); // Do not fast-forward time mTestLooper.dispatchAll(); @@ -541,12 +556,12 @@ public class AutomaticBrightnessControllerTest { verify(mBrightnessMappingStrategy, times(3)).getBrightness(anyFloat(), any(), anyInt()); // Now let's do the same for idle mode - mController.switchToIdleMode(); - // Called once for init, and once when switching, + mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE); + // Called once when switching, // setAmbientLux() is called twice and once in updateAutoBrightness(), // nextAmbientLightBrighteningTransition() and nextAmbientLightDarkeningTransition() are // called twice each. - verify(mBrightnessMappingStrategy, times(9)).isForIdleMode(); + verify(mBrightnessMappingStrategy, times(8)).getMode(); // Called when switching. verify(mBrightnessMappingStrategy, times(1)).getShortTermModelTimeout(); verify(mBrightnessMappingStrategy, times(1)).getUserBrightness(); @@ -826,7 +841,6 @@ public class AutomaticBrightnessControllerTest { @Test public void testResetShortTermModelWhenConfigChanges() { - when(mBrightnessMappingStrategy.isForIdleMode()).thenReturn(false); when(mBrightnessMappingStrategy.setBrightnessConfiguration(any())).thenReturn(true); mController.configure(AUTO_BRIGHTNESS_ENABLED, null /* configuration= */, @@ -847,8 +861,10 @@ public class AutomaticBrightnessControllerTest { verify(mBrightnessMappingStrategy, never()).addUserDataPoint(anyFloat(), anyFloat()); float userLux = 1000; + float userNits = 500; float userBrightness = 0.3f; - setupController(userLux, userBrightness, /* applyDebounce= */ true, + when(mBrightnessMappingStrategy.getBrightnessFromNits(userNits)).thenReturn(userBrightness); + setupController(userLux, userNits, /* applyDebounce= */ true, /* useHorizon= */ false); verify(mBrightnessMappingStrategy).addUserDataPoint(userLux, userBrightness); } @@ -856,8 +872,8 @@ public class AutomaticBrightnessControllerTest { @Test public void testBrighteningLightDebounce() throws Exception { clearInvocations(mSensorManager); - setupController(BrightnessMappingStrategy.NO_USER_LUX, - BrightnessMappingStrategy.NO_USER_BRIGHTNESS, /* applyDebounce= */ true, + setupController(BrightnessMappingStrategy.INVALID_LUX, + BrightnessMappingStrategy.INVALID_NITS, /* applyDebounce= */ true, /* useHorizon= */ false); ArgumentCaptor<SensorEventListener> listenerCaptor = @@ -897,8 +913,8 @@ public class AutomaticBrightnessControllerTest { .thenReturn(10000f); when(mAmbientBrightnessThresholds.getDarkeningThreshold(anyFloat())) .thenReturn(10000f); - setupController(BrightnessMappingStrategy.NO_USER_LUX, - BrightnessMappingStrategy.NO_USER_BRIGHTNESS, /* applyDebounce= */ true, + setupController(BrightnessMappingStrategy.INVALID_LUX, + BrightnessMappingStrategy.INVALID_NITS, /* applyDebounce= */ true, /* useHorizon= */ false); ArgumentCaptor<SensorEventListener> listenerCaptor = @@ -934,12 +950,11 @@ public class AutomaticBrightnessControllerTest { @Test public void testBrighteningLightDebounceIdle() throws Exception { clearInvocations(mSensorManager); - setupController(BrightnessMappingStrategy.NO_USER_LUX, - BrightnessMappingStrategy.NO_USER_BRIGHTNESS, /* applyDebounce= */ true, + setupController(BrightnessMappingStrategy.INVALID_LUX, + BrightnessMappingStrategy.INVALID_NITS, /* applyDebounce= */ true, /* useHorizon= */ false); - mController.switchToIdleMode(); - when(mIdleBrightnessMappingStrategy.isForIdleMode()).thenReturn(true); + mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE); ArgumentCaptor<SensorEventListener> listenerCaptor = ArgumentCaptor.forClass(SensorEventListener.class); @@ -972,12 +987,11 @@ public class AutomaticBrightnessControllerTest { .thenReturn(10000f); when(mAmbientBrightnessThresholdsIdle.getDarkeningThreshold(anyFloat())) .thenReturn(10000f); - setupController(BrightnessMappingStrategy.NO_USER_LUX, - BrightnessMappingStrategy.NO_USER_BRIGHTNESS, /* applyDebounce= */ true, + setupController(BrightnessMappingStrategy.INVALID_LUX, + BrightnessMappingStrategy.INVALID_NITS, /* applyDebounce= */ true, /* useHorizon= */ false); - mController.switchToIdleMode(); - when(mIdleBrightnessMappingStrategy.isForIdleMode()).thenReturn(true); + mController.switchMode(AUTO_BRIGHTNESS_MODE_IDLE); ArgumentCaptor<SensorEventListener> listenerCaptor = ArgumentCaptor.forClass(SensorEventListener.class); diff --git a/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java index a2e80f0d9b9b..189d9bbfe806 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java @@ -16,6 +16,9 @@ package com.android.server.display; +import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT; +import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; @@ -172,7 +175,9 @@ public class BrightnessMappingStrategyTest { public void testSimpleStrategyMappingAtControlPoints_IntConfig() { Resources res = createResources(DISPLAY_LEVELS_INT); DisplayDeviceConfig ddc = createDdc(); - BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, + mMockDwbc); assertNotNull("BrightnessMappingStrategy should not be null", simple); for (int i = 0; i < LUX_LEVELS.length; i++) { final float expectedLevel = MathUtils.map(PowerManager.BRIGHTNESS_OFF + 1, @@ -187,7 +192,9 @@ public class BrightnessMappingStrategyTest { public void testSimpleStrategyMappingBetweenControlPoints_IntConfig() { Resources res = createResources(DISPLAY_LEVELS_INT); DisplayDeviceConfig ddc = createDdc(); - BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, + mMockDwbc); assertNotNull("BrightnessMappingStrategy should not be null", simple); for (int i = 1; i < LUX_LEVELS.length; i++) { final float lux = (LUX_LEVELS[i - 1] + LUX_LEVELS[i]) / 2; @@ -203,7 +210,9 @@ public class BrightnessMappingStrategyTest { Resources res = createResources(EMPTY_INT_ARRAY); DisplayDeviceConfig ddc = createDdc(EMPTY_FLOAT_ARRAY, EMPTY_FLOAT_ARRAY, LUX_LEVELS, EMPTY_FLOAT_ARRAY, DISPLAY_LEVELS); - BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, + mMockDwbc); assertNotNull("BrightnessMappingStrategy should not be null", simple); for (int i = 0; i < LUX_LEVELS.length; i++) { assertEquals(DISPLAY_LEVELS[i], simple.getBrightness(LUX_LEVELS[i]), @@ -216,7 +225,9 @@ public class BrightnessMappingStrategyTest { Resources res = createResources(EMPTY_INT_ARRAY); DisplayDeviceConfig ddc = createDdc(EMPTY_FLOAT_ARRAY, EMPTY_FLOAT_ARRAY, LUX_LEVELS, EMPTY_FLOAT_ARRAY, DISPLAY_LEVELS); - BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, + mMockDwbc); assertNotNull("BrightnessMappingStrategy should not be null", simple); for (int i = 1; i < LUX_LEVELS.length; i++) { final float lux = (LUX_LEVELS[i - 1] + LUX_LEVELS[i]) / 2; @@ -230,7 +241,8 @@ public class BrightnessMappingStrategyTest { public void testSimpleStrategyIgnoresNewConfiguration() { Resources res = createResources(DISPLAY_LEVELS_INT); DisplayDeviceConfig ddc = createDdc(); - BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); final float[] lux = { 0f, 1f }; final float[] nits = { 0, PowerManager.BRIGHTNESS_ON }; @@ -245,7 +257,8 @@ public class BrightnessMappingStrategyTest { public void testSimpleStrategyIgnoresNullConfiguration() { Resources res = createResources(DISPLAY_LEVELS_INT); DisplayDeviceConfig ddc = createDdc(); - BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); strategy.setBrightnessConfiguration(null); final int n = DISPLAY_LEVELS_INT.length; @@ -261,7 +274,8 @@ public class BrightnessMappingStrategyTest { DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, DISPLAY_LEVELS_NITS); - BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); assertNotNull("BrightnessMappingStrategy should not be null", physical); for (int i = 0; i < LUX_LEVELS.length; i++) { final float expectedLevel = MathUtils.map(DISPLAY_RANGE_NITS[0], DISPLAY_RANGE_NITS[1], @@ -279,7 +293,8 @@ public class BrightnessMappingStrategyTest { Resources res = createResources(EMPTY_INT_ARRAY); DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE, LUX_LEVELS, DISPLAY_LEVELS_NITS); - BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); assertNotNull("BrightnessMappingStrategy should not be null", physical); Spline brightnessToNits = Spline.createSpline(BACKLIGHT_RANGE_ZERO_TO_ONE, DISPLAY_RANGE_NITS); @@ -297,7 +312,8 @@ public class BrightnessMappingStrategyTest { Resources res = createResources(EMPTY_INT_ARRAY); DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, DISPLAY_LEVELS_NITS); - BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); final float[] lux = {0f, 1f}; final float[] nits = { @@ -323,7 +339,8 @@ public class BrightnessMappingStrategyTest { Resources res = createResources(EMPTY_INT_ARRAY); DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, DISPLAY_LEVELS_NITS); - BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); float[] adjustedNits50p = new float[DISPLAY_RANGE_NITS.length]; for (int i = 0; i < DISPLAY_RANGE_NITS.length; i++) { adjustedNits50p[i] = DISPLAY_RANGE_NITS[i] * 0.5f; @@ -367,7 +384,8 @@ public class BrightnessMappingStrategyTest { Resources res = createResources(DISPLAY_LEVELS_INT); DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, DISPLAY_LEVELS_NITS); - BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); assertTrue(strategy instanceof BrightnessMappingStrategy.PhysicalMappingStrategy); } @@ -381,14 +399,16 @@ public class BrightnessMappingStrategyTest { Resources res = createResources(EMPTY_INT_ARRAY); DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, lux, DISPLAY_LEVELS_NITS); - BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); assertNull(strategy); // And make sure we get the same result even if it's monotone but not increasing. lux[idx] = lux[idx + 1]; ddc = createDdc(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, lux, DISPLAY_LEVELS_NITS); - strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + strategy = BrightnessMappingStrategy.create(res, ddc, AUTO_BRIGHTNESS_MODE_DEFAULT, + mMockDwbc); assertNull(strategy); } @@ -402,11 +422,13 @@ public class BrightnessMappingStrategyTest { Resources res = createResources(EMPTY_INT_ARRAY); DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, lux, DISPLAY_LEVELS_NITS); - BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); assertNull(strategy); res = createResources(DISPLAY_LEVELS_INT); - strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + strategy = BrightnessMappingStrategy.create(res, ddc, AUTO_BRIGHTNESS_MODE_DEFAULT, + mMockDwbc); assertNull(strategy); // Extra backlight level @@ -416,7 +438,8 @@ public class BrightnessMappingStrategyTest { res = createResources(backlight); ddc = createDdc(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, EMPTY_FLOAT_ARRAY); - strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + strategy = BrightnessMappingStrategy.create(res, ddc, AUTO_BRIGHTNESS_MODE_DEFAULT, + mMockDwbc); assertNull(strategy); // Extra nits level @@ -425,7 +448,8 @@ public class BrightnessMappingStrategyTest { res = createResources(EMPTY_INT_ARRAY); ddc = createDdc(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, nits); - strategy = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + strategy = BrightnessMappingStrategy.create(res, ddc, AUTO_BRIGHTNESS_MODE_DEFAULT, + mMockDwbc); assertNull(strategy); } @@ -433,15 +457,18 @@ public class BrightnessMappingStrategyTest { public void testPhysicalStrategyRequiresNitsMapping() { Resources res = createResources(EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/); DisplayDeviceConfig ddc = createDdc(EMPTY_FLOAT_ARRAY /*nitsRange*/); - BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); assertNull(physical); res = createResources(EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/); - physical = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + physical = BrightnessMappingStrategy.create(res, ddc, AUTO_BRIGHTNESS_MODE_DEFAULT, + mMockDwbc); assertNull(physical); res = createResources(EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/); - physical = BrightnessMappingStrategy.create(res, ddc, mMockDwbc); + physical = BrightnessMappingStrategy.create(res, ddc, AUTO_BRIGHTNESS_MODE_DEFAULT, + mMockDwbc); assertNull(physical); } @@ -450,10 +477,12 @@ public class BrightnessMappingStrategyTest { Resources res = createResources(EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/); DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE, LUX_LEVELS, DISPLAY_LEVELS_NITS); - assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc, mMockDwbc)); + assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc)); ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE); res = createResources(DISPLAY_LEVELS_INT); - assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc, mMockDwbc)); + assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc)); } @Test @@ -463,7 +492,8 @@ public class BrightnessMappingStrategyTest { // Create an idle mode bms // This will fail if it tries to fetch the wrong configuration. - BrightnessMappingStrategy bms = BrightnessMappingStrategy.createForIdleMode(res, ddc, + BrightnessMappingStrategy bms = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_IDLE, mMockDwbc); assertNotNull("BrightnessMappingStrategy should not be null", bms); @@ -652,7 +682,7 @@ public class BrightnessMappingStrategyTest { DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, GAMMA_CORRECTION_LUX, GAMMA_CORRECTION_NITS); BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(resources, ddc, - mMockDwbc); + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); // Let's start with a validity check: assertEquals(y1, strategy.getBrightness(x1), 0.0001f /* tolerance */); assertEquals(y2, strategy.getBrightness(x2), 0.0001f /* tolerance */); @@ -683,7 +713,7 @@ public class BrightnessMappingStrategyTest { DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, GAMMA_CORRECTION_LUX, GAMMA_CORRECTION_NITS); BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(resources, ddc, - mMockDwbc); + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); // Validity check: assertEquals(y1, strategy.getBrightness(x1), 0.0001f /* tolerance */); assertEquals(y2, strategy.getBrightness(x2), 0.0001f /* tolerance */); @@ -711,7 +741,7 @@ public class BrightnessMappingStrategyTest { DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, GAMMA_CORRECTION_LUX, GAMMA_CORRECTION_NITS); BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(resources, ddc, - mMockDwbc); + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); assertEquals(0.0f, strategy.getAutoBrightnessAdjustment(), /* delta= */ 0.0001f); strategy.addUserDataPoint(/* lux= */ 2500, /* brightness= */ 1.0f); assertEquals(+1.0f, strategy.getAutoBrightnessAdjustment(), /* delta= */ 0.0001f); @@ -735,7 +765,7 @@ public class BrightnessMappingStrategyTest { DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, GAMMA_CORRECTION_LUX, GAMMA_CORRECTION_NITS); BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(resources, ddc, - mMockDwbc); + AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc); // Validity, as per tradition: assertEquals(y0, strategy.getBrightness(x0), 0.0001f /* tolerance */); assertEquals(y2, strategy.getBrightness(x2), 0.0001f /* tolerance */); @@ -757,4 +787,14 @@ public class BrightnessMappingStrategyTest { assertEquals(1.0f, strategy.getBrightness(x4), 0.0001f /* tolerance */); assertEquals(adjustment, strategy.getAutoBrightnessAdjustment(), 0.0001f /* tolerance */); } + + @Test + public void testGetMode() { + Resources res = createResourcesIdle(LUX_LEVELS_IDLE, DISPLAY_LEVELS_NITS_IDLE); + DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc, + AUTO_BRIGHTNESS_MODE_IDLE, + mMockDwbc); + assertEquals(AUTO_BRIGHTNESS_MODE_IDLE, strategy.getMode()); + } } diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java index acd9dceb16d5..02bd35a5b17f 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java @@ -18,6 +18,7 @@ package com.android.server.display; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; +import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE; import static org.junit.Assert.assertNotNull; import static org.mockito.ArgumentMatchers.any; @@ -28,7 +29,6 @@ import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; @@ -62,6 +62,7 @@ import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; import android.testing.TestableContext; import android.util.FloatProperty; +import android.util.SparseArray; import android.view.Display; import android.view.DisplayInfo; @@ -357,7 +358,7 @@ public final class DisplayPowerController2Test { float followerBrightness = 0.4f; float nits = 300; when(mHolder.automaticBrightnessController.convertToNits(leadBrightness)).thenReturn(nits); - when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(followerBrightness); when(mHolder.brightnessSetting.getBrightness()).thenReturn(leadBrightness); listener.onBrightnessChanged(leadBrightness); @@ -372,7 +373,7 @@ public final class DisplayPowerController2Test { float brightness = 0.6f; nits = 600; when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); - when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); listener.onBrightnessChanged(brightness); @@ -404,7 +405,7 @@ public final class DisplayPowerController2Test { float brightness = 0.3f; when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(300f); - when(followerDpc.automaticBrightnessController.convertToFloatScale(anyFloat())) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(anyFloat())) .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT); when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); listener.onBrightnessChanged(brightness); @@ -466,7 +467,7 @@ public final class DisplayPowerController2Test { float brightness = 0.3f; when(mHolder.automaticBrightnessController.convertToNits(anyFloat())).thenReturn(-1f); - when(followerDpc.automaticBrightnessController.convertToFloatScale(anyFloat())) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(anyFloat())) .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT); when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); listener.onBrightnessChanged(brightness); @@ -500,7 +501,7 @@ public final class DisplayPowerController2Test { when(mHolder.automaticBrightnessController.convertToNits(rawLeadBrightness)) .thenReturn(nits); when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux); - when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(followerBrightness); mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc); @@ -534,7 +535,7 @@ public final class DisplayPowerController2Test { when(mHolder.automaticBrightnessController.convertToNits(rawLeadBrightness)) .thenReturn(nits); when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux); - when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(followerBrightness); mHolder.dpc.updateBrightness(); @@ -592,9 +593,9 @@ public final class DisplayPowerController2Test { float brightness = 0.6f; float nits = 600; when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); - when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); - when(secondFollowerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(secondFollowerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); listener.onBrightnessChanged(brightness); @@ -625,9 +626,9 @@ public final class DisplayPowerController2Test { brightness = 0.7f; nits = 700; when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); - when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); - when(secondFollowerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(secondFollowerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); listener.onBrightnessChanged(brightness); @@ -697,9 +698,9 @@ public final class DisplayPowerController2Test { float brightness = 0.6f; float nits = 600; when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); - when(followerHolder.automaticBrightnessController.convertToFloatScale(nits)) + when(followerHolder.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); - when(secondFollowerHolder.automaticBrightnessController.convertToFloatScale(nits)) + when(secondFollowerHolder.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); listener.onBrightnessChanged(brightness); @@ -1124,7 +1125,7 @@ public final class DisplayPowerController2Test { float newBrightness = 0.4f; when(mHolder.brightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits); - when(mHolder.automaticBrightnessController.convertToFloatScale(nits)) + when(mHolder.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(newBrightness); // New display device setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), @@ -1141,12 +1142,9 @@ public final class DisplayPowerController2Test { @Test public void testShortTermModelPersistsWhenDisplayDeviceChanges() { float lux = 2000; - float brightness = 0.4f; float nits = 500; - when(mHolder.brightnessMappingStrategy.getUserLux()).thenReturn(lux); - when(mHolder.brightnessMappingStrategy.getUserBrightness()).thenReturn(brightness); - when(mHolder.brightnessMappingStrategy.convertToNits(brightness)).thenReturn(nits); - when(mHolder.brightnessMappingStrategy.convertToFloatScale(nits)).thenReturn(brightness); + when(mHolder.automaticBrightnessController.getUserLux()).thenReturn(lux); + when(mHolder.automaticBrightnessController.getUserNits()).thenReturn(nits); DisplayPowerRequest dpr = new DisplayPowerRequest(); mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); advanceTime(1); @@ -1163,7 +1161,7 @@ public final class DisplayPowerController2Test { any(Looper.class), eq(mSensorManagerMock), /* lightSensor= */ any(), - eq(mHolder.brightnessMappingStrategy), + /* brightnessMappingStrategyMap= */ any(SparseArray.class), /* lightSensorWarmUpTime= */ anyInt(), /* brightnessMin= */ anyFloat(), /* brightnessMax= */ anyFloat(), @@ -1182,11 +1180,10 @@ public final class DisplayPowerController2Test { eq(mContext), any(BrightnessRangeController.class), any(BrightnessThrottler.class), - /* idleModeBrightnessMapper= */ isNull(), /* ambientLightHorizonShort= */ anyInt(), /* ambientLightHorizonLong= */ anyInt(), eq(lux), - eq(brightness) + eq(nits) ); } @@ -1219,7 +1216,7 @@ public final class DisplayPowerController2Test { public void testDwbcCallsHappenOnHandler() { mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID); - mHolder.dpc.setAutomaticScreenBrightnessMode(true); + mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE); verify(mDisplayWhiteBalanceControllerMock, never()).setStrongModeEnabled(true); // dispatch handler looper @@ -1382,7 +1379,7 @@ public final class DisplayPowerController2Test { BRIGHTNESS_RAMP_DECREASE_MAX); // switch to idle mode - mHolder.dpc.setAutomaticScreenBrightnessMode(/* idle= */ true); + mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE); advanceTime(1); // A second time, when switching to idle mode. @@ -1411,7 +1408,7 @@ public final class DisplayPowerController2Test { BRIGHTNESS_RAMP_DECREASE_MAX); // switch to idle mode - mHolder.dpc.setAutomaticScreenBrightnessMode(/* idle= */ true); + mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE); advanceTime(1); // A second time, when switching to idle mode. @@ -1437,7 +1434,7 @@ public final class DisplayPowerController2Test { mHolder.config, /* isEnabled= */ true); // switch to idle mode - mHolder.dpc.setAutomaticScreenBrightnessMode(true); + mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE); // A second time when switching to idle mode. verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, @@ -1463,7 +1460,7 @@ public final class DisplayPowerController2Test { mHolder.config, /* isEnabled= */ true); // switch to idle mode - mHolder.dpc.setAutomaticScreenBrightnessMode(true); + mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE); verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE, BRIGHTNESS_RAMP_DECREASE_MAX_IDLE); @@ -1839,7 +1836,7 @@ public final class DisplayPowerController2Test { AutomaticBrightnessController getAutomaticBrightnessController( AutomaticBrightnessController.Callbacks callbacks, Looper looper, SensorManager sensorManager, Sensor lightSensor, - BrightnessMappingStrategy interactiveModeBrightnessMapper, + SparseArray<BrightnessMappingStrategy> brightnessMappingStrategyMap, int lightSensorWarmUpTime, float brightnessMin, float brightnessMax, float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, @@ -1850,15 +1847,13 @@ public final class DisplayPowerController2Test { HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels screenBrightnessThresholdsIdle, Context context, BrightnessRangeController brightnessRangeController, - BrightnessThrottler brightnessThrottler, - BrightnessMappingStrategy idleModeBrightnessMapper, - int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux, - float userBrightness) { + BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort, + int ambientLightHorizonLong, float userLux, float userNits) { return mAutomaticBrightnessController; } @Override - BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources, + BrightnessMappingStrategy getDefaultModeBrightnessMapper(Resources resources, DisplayDeviceConfig displayDeviceConfig, DisplayWhiteBalanceController displayWhiteBalanceController) { return mBrightnessMappingStrategy; diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java index 50b0e167ef99..64cdac464720 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java @@ -18,6 +18,7 @@ package com.android.server.display; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; +import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE; import static org.junit.Assert.assertNotNull; import static org.mockito.ArgumentMatchers.any; @@ -28,7 +29,6 @@ import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; @@ -62,6 +62,7 @@ import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; import android.testing.TestableContext; import android.util.FloatProperty; +import android.util.SparseArray; import android.view.Display; import android.view.DisplayInfo; @@ -357,7 +358,7 @@ public final class DisplayPowerControllerTest { float followerBrightness = 0.4f; float nits = 300; when(mHolder.automaticBrightnessController.convertToNits(leadBrightness)).thenReturn(nits); - when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(followerBrightness); when(mHolder.brightnessSetting.getBrightness()).thenReturn(leadBrightness); listener.onBrightnessChanged(leadBrightness); @@ -375,7 +376,7 @@ public final class DisplayPowerControllerTest { float brightness = 0.6f; nits = 600; when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); - when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); listener.onBrightnessChanged(brightness); @@ -408,7 +409,7 @@ public final class DisplayPowerControllerTest { float brightness = 0.3f; when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(300f); - when(followerDpc.automaticBrightnessController.convertToFloatScale(anyFloat())) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(anyFloat())) .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT); when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); listener.onBrightnessChanged(brightness); @@ -472,7 +473,7 @@ public final class DisplayPowerControllerTest { float brightness = 0.3f; when(mHolder.automaticBrightnessController.convertToNits(anyFloat())).thenReturn(-1f); - when(followerDpc.automaticBrightnessController.convertToFloatScale(anyFloat())) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(anyFloat())) .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT); when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); listener.onBrightnessChanged(brightness); @@ -507,7 +508,7 @@ public final class DisplayPowerControllerTest { when(mHolder.automaticBrightnessController.convertToNits(rawLeadBrightness)) .thenReturn(nits); when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux); - when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(followerBrightness); mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc); @@ -541,7 +542,7 @@ public final class DisplayPowerControllerTest { when(mHolder.automaticBrightnessController.convertToNits(rawLeadBrightness)) .thenReturn(nits); when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux); - when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(followerBrightness); mHolder.dpc.updateBrightness(); @@ -600,9 +601,9 @@ public final class DisplayPowerControllerTest { float brightness = 0.6f; float nits = 600; when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); - when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); - when(secondFollowerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(secondFollowerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); listener.onBrightnessChanged(brightness); @@ -633,9 +634,9 @@ public final class DisplayPowerControllerTest { brightness = 0.7f; nits = 700; when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); - when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(followerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); - when(secondFollowerDpc.automaticBrightnessController.convertToFloatScale(nits)) + when(secondFollowerDpc.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); listener.onBrightnessChanged(brightness); @@ -706,9 +707,9 @@ public final class DisplayPowerControllerTest { float brightness = 0.6f; float nits = 600; when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); - when(followerHolder.automaticBrightnessController.convertToFloatScale(nits)) + when(followerHolder.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); - when(secondFollowerHolder.automaticBrightnessController.convertToFloatScale(nits)) + when(secondFollowerHolder.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(brightness); when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); listener.onBrightnessChanged(brightness); @@ -1056,7 +1057,7 @@ public final class DisplayPowerControllerTest { float newBrightness = 0.4f; when(mHolder.brightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits); - when(mHolder.automaticBrightnessController.convertToFloatScale(nits)) + when(mHolder.automaticBrightnessController.getBrightnessFromNits(nits)) .thenReturn(newBrightness); // New display device setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), @@ -1073,12 +1074,9 @@ public final class DisplayPowerControllerTest { @Test public void testShortTermModelPersistsWhenDisplayDeviceChanges() { float lux = 2000; - float brightness = 0.4f; float nits = 500; - when(mHolder.brightnessMappingStrategy.getUserLux()).thenReturn(lux); - when(mHolder.brightnessMappingStrategy.getUserBrightness()).thenReturn(brightness); - when(mHolder.brightnessMappingStrategy.convertToNits(brightness)).thenReturn(nits); - when(mHolder.brightnessMappingStrategy.convertToFloatScale(nits)).thenReturn(brightness); + when(mHolder.automaticBrightnessController.getUserLux()).thenReturn(lux); + when(mHolder.automaticBrightnessController.getUserNits()).thenReturn(nits); DisplayPowerRequest dpr = new DisplayPowerRequest(); mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); advanceTime(1); @@ -1095,7 +1093,7 @@ public final class DisplayPowerControllerTest { any(Looper.class), eq(mSensorManagerMock), /* lightSensor= */ any(), - eq(mHolder.brightnessMappingStrategy), + /* brightnessMappingStrategyMap= */ any(SparseArray.class), /* lightSensorWarmUpTime= */ anyInt(), /* brightnessMin= */ anyFloat(), /* brightnessMax= */ anyFloat(), @@ -1114,11 +1112,10 @@ public final class DisplayPowerControllerTest { eq(mContext), any(BrightnessRangeController.class), any(BrightnessThrottler.class), - /* idleModeBrightnessMapper= */ isNull(), /* ambientLightHorizonShort= */ anyInt(), /* ambientLightHorizonLong= */ anyInt(), eq(lux), - eq(brightness) + eq(nits) ); } @@ -1151,7 +1148,7 @@ public final class DisplayPowerControllerTest { public void testDwbcCallsHappenOnHandler() { mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID); - mHolder.dpc.setAutomaticScreenBrightnessMode(true); + mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE); verify(mDisplayWhiteBalanceControllerMock, never()).setStrongModeEnabled(true); // dispatch handler looper @@ -1293,7 +1290,7 @@ public final class DisplayPowerControllerTest { BRIGHTNESS_RAMP_DECREASE_MAX); // switch to idle - mHolder.dpc.setAutomaticScreenBrightnessMode(/* idle= */ true); + mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE); advanceTime(1); verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, @@ -1320,7 +1317,7 @@ public final class DisplayPowerControllerTest { BRIGHTNESS_RAMP_DECREASE_MAX); // switch to idle - mHolder.dpc.setAutomaticScreenBrightnessMode(/* idle= */ true); + mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE); advanceTime(1); verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE, @@ -1347,7 +1344,7 @@ public final class DisplayPowerControllerTest { mHolder.config, /* isEnabled= */ true); // switch to idle mode - mHolder.dpc.setAutomaticScreenBrightnessMode(true); + mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE); // second time when switching to idle screen brightness mode verify(mHolder.animator, times(2)).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX, @@ -1372,7 +1369,7 @@ public final class DisplayPowerControllerTest { mHolder.config, /* isEnabled= */ true); // switch to idle mode - mHolder.dpc.setAutomaticScreenBrightnessMode(true); + mHolder.dpc.setAutomaticScreenBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE); verify(mHolder.animator).setAnimationTimeLimits(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE, BRIGHTNESS_RAMP_DECREASE_MAX_IDLE); @@ -1655,7 +1652,7 @@ public final class DisplayPowerControllerTest { AutomaticBrightnessController getAutomaticBrightnessController( AutomaticBrightnessController.Callbacks callbacks, Looper looper, SensorManager sensorManager, Sensor lightSensor, - BrightnessMappingStrategy interactiveModeBrightnessMapper, + SparseArray<BrightnessMappingStrategy> brightnessMappingStrategyMap, int lightSensorWarmUpTime, float brightnessMin, float brightnessMax, float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, @@ -1666,15 +1663,13 @@ public final class DisplayPowerControllerTest { HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels screenBrightnessThresholdsIdle, Context context, BrightnessRangeController brightnessRangeController, - BrightnessThrottler brightnessThrottler, - BrightnessMappingStrategy idleModeBrightnessMapper, - int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux, - float userBrightness) { + BrightnessThrottler brightnessThrottler, int ambientLightHorizonShort, + int ambientLightHorizonLong, float userLux, float userNits) { return mAutomaticBrightnessController; } @Override - BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources, + BrightnessMappingStrategy getDefaultModeBrightnessMapper(Resources resources, DisplayDeviceConfig displayDeviceConfig, DisplayWhiteBalanceController displayWhiteBalanceController) { return mBrightnessMappingStrategy; diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java index 52fa91f5fe0e..2d0c3fdb6352 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java @@ -293,21 +293,21 @@ public final class DisplayBrightnessControllerTest { } @Test - public void testConvertToFloatScale() { + public void testGetBrightnessFromNits() { float brightness = 0.5f; float nits = 300; // ABC is null assertEquals(PowerManager.BRIGHTNESS_INVALID_FLOAT, - mDisplayBrightnessController.convertToFloatScale(nits), /* delta= */ 0); + mDisplayBrightnessController.getBrightnessFromNits(nits), /* delta= */ 0); AutomaticBrightnessController automaticBrightnessController = mock(AutomaticBrightnessController.class); - when(automaticBrightnessController.convertToFloatScale(nits)).thenReturn(brightness); + when(automaticBrightnessController.getBrightnessFromNits(nits)).thenReturn(brightness); mDisplayBrightnessController.setAutomaticBrightnessController( automaticBrightnessController); - assertEquals(brightness, mDisplayBrightnessController.convertToFloatScale(nits), + assertEquals(brightness, mDisplayBrightnessController.getBrightnessFromNits(nits), /* delta= */ 0); } @@ -329,7 +329,7 @@ public final class DisplayBrightnessControllerTest { float brightness = 0.3f; AutomaticBrightnessController automaticBrightnessController = mock(AutomaticBrightnessController.class); - when(automaticBrightnessController.convertToFloatScale(nits)).thenReturn(brightness); + when(automaticBrightnessController.getBrightnessFromNits(nits)).thenReturn(brightness); when(mBrightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits); mDisplayBrightnessController.setAutomaticBrightnessController( automaticBrightnessController); @@ -340,7 +340,7 @@ public final class DisplayBrightnessControllerTest { // When the nits value is invalid, the brightness is resumed from where it was last set nits = -1; brightness = 0.4f; - when(automaticBrightnessController.convertToFloatScale(nits)).thenReturn(brightness); + when(automaticBrightnessController.getBrightnessFromNits(nits)).thenReturn(brightness); when(mBrightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits); when(mBrightnessSetting.getBrightness()).thenReturn(brightness); mDisplayBrightnessController.setAutomaticBrightnessController( diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java index b2854ceb1017..ef15f60101d4 100644 --- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java @@ -868,6 +868,7 @@ public class CompatConfigTest { + "<compat-change id=\"1234\" name=\"MY_CHANGE1\" enableAfterTargetSdk=\"2\" />" + "<compat-change id=\"1235\" name=\"MY_CHANGE2\" disabled=\"true\" />" + "<compat-change id=\"1236\" name=\"MY_CHANGE3\" />" + + "<compat-change id=\"1237\" name=\"MY_CHANGE4\" enableSinceTargetSdk=\"31\" />" + "</config>"; File dir = createTempDir(); @@ -885,32 +886,12 @@ public class CompatConfigTest { ApplicationInfoBuilder.create().withTargetSdk(5).build())).isFalse(); assertThat(compatConfig.isChangeEnabled(1236L, ApplicationInfoBuilder.create().withTargetSdk(1).build())).isTrue(); - } - - @Test - public void testReadApexConfig() throws IOException { - String configXml = "<config>" - + "<compat-change id=\"1234\" name=\"MY_CHANGE1\" enableAfterTargetSdk=\"2\" />" - + "<compat-change id=\"1235\" name=\"MY_CHANGE2\" disabled=\"true\" />" - + "<compat-change id=\"1236\" name=\"MY_CHANGE3\" />" - + "<compat-change id=\"1237\" name=\"MY_CHANGE4\" enableSinceTargetSdk=\"31\" />" - + "</config>"; - - File dir = createTempDir(); - writeToFile(dir, "platform_compat_config.xml", configXml); - CompatConfig compatConfig = new CompatConfig(mBuildClassifier, mContext); - compatConfig.forceNonDebuggableFinalForTest(false); + assertThat(compatConfig.isChangeEnabled(1237L, + ApplicationInfoBuilder.create().withTargetSdk(31).build())).isFalse(); - compatConfig.initConfigFromLib(dir); + // Force the platform sdk version to be same as enabled target sdk + when(mBuildClassifier.platformTargetSdk()).thenReturn(31); - assertThat(compatConfig.isChangeEnabled(1234L, - ApplicationInfoBuilder.create().withTargetSdk(1).build())).isFalse(); - assertThat(compatConfig.isChangeEnabled(1234L, - ApplicationInfoBuilder.create().withTargetSdk(3).build())).isTrue(); - assertThat(compatConfig.isChangeEnabled(1235L, - ApplicationInfoBuilder.create().withTargetSdk(5).build())).isFalse(); - assertThat(compatConfig.isChangeEnabled(1236L, - ApplicationInfoBuilder.create().withTargetSdk(1).build())).isTrue(); assertThat(compatConfig.isChangeEnabled(1237L, ApplicationInfoBuilder.create().withTargetSdk(31).build())).isTrue(); } |