diff options
624 files changed, 17720 insertions, 9922 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index ad849002cca1..6393fdb910e3 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -72,6 +72,7 @@ aconfig_declarations_group { "android.service.dreams.flags-aconfig-java", "android.service.notification.flags-aconfig-java", "android.service.appprediction.flags-aconfig-java", + "android.service.quickaccesswallet.flags-aconfig-java", "android.service.voice.flags-aconfig-java", "android.speech.flags-aconfig-java", "android.systemserver.flags-aconfig-java", @@ -111,6 +112,7 @@ aconfig_declarations_group { "framework_graphics_flags_java_lib", "hwui_flags_java_lib", "interaction_jank_monitor_flags_lib", + "keystore2_flags_java-framework", "libcore_exported_aconfig_flags_lib", "libcore_readonly_aconfig_flags_lib", "libgui_flags_java_lib", @@ -1774,3 +1776,18 @@ java_aconfig_library { aconfig_declarations: "aconfig_settingslib_flags", defaults: ["framework-minus-apex-aconfig-java-defaults"], } + +// Quick Access Wallet +aconfig_declarations { + name: "android.service.quickaccesswallet.flags-aconfig", + package: "android.service.quickaccesswallet", + exportable: true, + container: "system", + srcs: ["core/java/android/service/quickaccesswallet/flags.aconfig"], +} + +java_aconfig_library { + name: "android.service.quickaccesswallet.flags-aconfig-java", + aconfig_declarations: "android.service.quickaccesswallet.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} diff --git a/apct-tests/perftests/windowmanager/Android.bp b/apct-tests/perftests/windowmanager/Android.bp index e9357f4a9d3c..1175677bbb04 100644 --- a/apct-tests/perftests/windowmanager/Android.bp +++ b/apct-tests/perftests/windowmanager/Android.bp @@ -13,7 +13,7 @@ // limitations under the License. package { - default_team: "trendy_team_input_framework", + default_team: "trendy_team_windowing_animations_transitions", // See: http://go/android-license-faq // A large-scale-change added 'default_applicable_licenses' to import // all of the 'license_kinds' from "frameworks_base_license" diff --git a/core/api/current.txt b/core/api/current.txt index 4961a6192d90..f1fbab001822 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -1276,6 +1276,7 @@ package android { field public static final int paddingStart = 16843699; // 0x10103b3 field public static final int paddingTop = 16842967; // 0x10100d7 field public static final int paddingVertical = 16844094; // 0x101053e + field @FlaggedApi("android.content.pm.app_compat_option_16kb") public static final int pageSizeCompat; field public static final int panelBackground = 16842846; // 0x101005e field public static final int panelColorBackground = 16842849; // 0x1010061 field public static final int panelColorForeground = 16842848; // 0x1010060 @@ -2043,12 +2044,6 @@ package android { field public static final int system_error_container_light = 17170554; // 0x106007a field public static final int system_error_dark = 17170595; // 0x10600a3 field public static final int system_error_light = 17170552; // 0x1060078 - field @FlaggedApi("com.android.systemui.material_colors_10_2024") public static final int system_inverse_on_surface_dark; - field @FlaggedApi("com.android.systemui.material_colors_10_2024") public static final int system_inverse_on_surface_light; - field @FlaggedApi("com.android.systemui.material_colors_10_2024") public static final int system_inverse_primary_dark; - field @FlaggedApi("com.android.systemui.material_colors_10_2024") public static final int system_inverse_primary_light; - field @FlaggedApi("com.android.systemui.material_colors_10_2024") public static final int system_inverse_surface_dark; - field @FlaggedApi("com.android.systemui.material_colors_10_2024") public static final int system_inverse_surface_light; field public static final int system_neutral1_0 = 17170461; // 0x106001d field public static final int system_neutral1_10 = 17170462; // 0x106001e field public static final int system_neutral1_100 = 17170464; // 0x1060020 @@ -2125,16 +2120,12 @@ package android { field public static final int system_primary_fixed = 17170612; // 0x10600b4 field public static final int system_primary_fixed_dim = 17170613; // 0x10600b5 field public static final int system_primary_light = 17170528; // 0x1060060 - field @FlaggedApi("com.android.systemui.material_colors_10_2024") public static final int system_scrim_dark; - field @FlaggedApi("com.android.systemui.material_colors_10_2024") public static final int system_scrim_light; field public static final int system_secondary_container_dark = 17170573; // 0x106008d field public static final int system_secondary_container_light = 17170530; // 0x1060062 field public static final int system_secondary_dark = 17170575; // 0x106008f field public static final int system_secondary_fixed = 17170616; // 0x10600b8 field public static final int system_secondary_fixed_dim = 17170617; // 0x10600b9 field public static final int system_secondary_light = 17170532; // 0x1060064 - field @FlaggedApi("com.android.systemui.material_colors_10_2024") public static final int system_shadow_dark; - field @FlaggedApi("com.android.systemui.material_colors_10_2024") public static final int system_shadow_light; field public static final int system_surface_bright_dark = 17170590; // 0x106009e field public static final int system_surface_bright_light = 17170547; // 0x1060073 field public static final int system_surface_container_dark = 17170587; // 0x106009b @@ -2152,8 +2143,6 @@ package android { field public static final int system_surface_dim_light = 17170548; // 0x1060074 field public static final int system_surface_disabled = 17170626; // 0x10600c2 field public static final int system_surface_light = 17170540; // 0x106006c - field @FlaggedApi("com.android.systemui.material_colors_10_2024") public static final int system_surface_tint_dark; - field @FlaggedApi("com.android.systemui.material_colors_10_2024") public static final int system_surface_tint_light; field public static final int system_surface_variant_dark = 17170592; // 0x10600a0 field public static final int system_surface_variant_light = 17170549; // 0x1060075 field public static final int system_tertiary_container_dark = 17170577; // 0x1060091 @@ -8087,8 +8076,10 @@ package android.app.admin { method @NonNull @WorkerThread public android.os.Bundle getApplicationRestrictions(@Nullable android.content.ComponentName, String); method @Deprecated @Nullable public String getApplicationRestrictionsManagingPackage(@NonNull android.content.ComponentName); method @RequiresPermission(anyOf={android.Manifest.permission.SET_TIME, "android.permission.QUERY_ADMIN_POLICY"}, conditional=true) public boolean getAutoTimeEnabled(@Nullable android.content.ComponentName); + method @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") @RequiresPermission(anyOf={android.Manifest.permission.SET_TIME, "android.permission.QUERY_ADMIN_POLICY"}, conditional=true) public int getAutoTimePolicy(); method @Deprecated public boolean getAutoTimeRequired(); method @RequiresPermission(anyOf={android.Manifest.permission.SET_TIME_ZONE, "android.permission.QUERY_ADMIN_POLICY"}, conditional=true) public boolean getAutoTimeZoneEnabled(@Nullable android.content.ComponentName); + method @FlaggedApi("android.app.admin.flags.set_auto_time_zone_enabled_coexistence") @RequiresPermission(anyOf={android.Manifest.permission.SET_TIME_ZONE, "android.permission.QUERY_ADMIN_POLICY"}, conditional=true) public int getAutoTimeZonePolicy(); method @NonNull public java.util.List<android.os.UserHandle> getBindDeviceAdminTargetUsers(@NonNull android.content.ComponentName); method public boolean getBluetoothContactSharingDisabled(@NonNull android.content.ComponentName); method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_CAMERA, conditional=true) public boolean getCameraDisabled(@Nullable android.content.ComponentName); @@ -8244,8 +8235,10 @@ package android.app.admin { method @WorkerThread public void setApplicationRestrictions(@Nullable android.content.ComponentName, String, android.os.Bundle); method @Deprecated public void setApplicationRestrictionsManagingPackage(@NonNull android.content.ComponentName, @Nullable String) throws android.content.pm.PackageManager.NameNotFoundException; method @RequiresPermission(value=android.Manifest.permission.SET_TIME, conditional=true) public void setAutoTimeEnabled(@Nullable android.content.ComponentName, boolean); + method @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") @RequiresPermission(value=android.Manifest.permission.SET_TIME, conditional=true) public void setAutoTimePolicy(int); method @Deprecated public void setAutoTimeRequired(@NonNull android.content.ComponentName, boolean); method @RequiresPermission(value=android.Manifest.permission.SET_TIME_ZONE, conditional=true) public void setAutoTimeZoneEnabled(@Nullable android.content.ComponentName, boolean); + method @FlaggedApi("android.app.admin.flags.set_auto_time_zone_enabled_coexistence") @RequiresPermission(value=android.Manifest.permission.SET_TIME_ZONE, conditional=true) public void setAutoTimeZonePolicy(int); method public void setBackupServiceEnabled(@NonNull android.content.ComponentName, boolean); method public void setBluetoothContactSharingDisabled(@NonNull android.content.ComponentName, boolean); method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_CAMERA, conditional=true) public void setCameraDisabled(@Nullable android.content.ComponentName, boolean); @@ -8364,6 +8357,12 @@ package android.app.admin { field public static final String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD"; field public static final String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION"; field public static final String ACTION_SYSTEM_UPDATE_POLICY_CHANGED = "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED"; + field @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") public static final int AUTO_TIME_DISABLED = 1; // 0x1 + field @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") public static final int AUTO_TIME_ENABLED = 2; // 0x2 + field @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") public static final int AUTO_TIME_NOT_CONTROLLED_BY_POLICY = 0; // 0x0 + field @FlaggedApi("android.app.admin.flags.set_auto_time_zone_enabled_coexistence") public static final int AUTO_TIME_ZONE_DISABLED = 1; // 0x1 + field @FlaggedApi("android.app.admin.flags.set_auto_time_zone_enabled_coexistence") public static final int AUTO_TIME_ZONE_ENABLED = 2; // 0x2 + field @FlaggedApi("android.app.admin.flags.set_auto_time_zone_enabled_coexistence") public static final int AUTO_TIME_ZONE_NOT_CONTROLLED_BY_POLICY = 0; // 0x0 field @FlaggedApi("android.view.contentprotection.flags.manage_device_policy_enabled") public static final int CONTENT_PROTECTION_DISABLED = 1; // 0x1 field @FlaggedApi("android.view.contentprotection.flags.manage_device_policy_enabled") public static final int CONTENT_PROTECTION_ENABLED = 2; // 0x2 field @FlaggedApi("android.view.contentprotection.flags.manage_device_policy_enabled") public static final int CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY = 0; // 0x0 @@ -18828,6 +18827,19 @@ package android.hardware { field public static final int TRANSFER_UNSPECIFIED = 0; // 0x0 } + @FlaggedApi("android.hardware.flags.luts_api") public final class DisplayLuts { + ctor @FlaggedApi("android.hardware.flags.luts_api") public DisplayLuts(); + method @FlaggedApi("android.hardware.flags.luts_api") public void set(@NonNull android.hardware.DisplayLuts.Entry); + method @FlaggedApi("android.hardware.flags.luts_api") public void set(@NonNull android.hardware.DisplayLuts.Entry, @NonNull android.hardware.DisplayLuts.Entry); + } + + @FlaggedApi("android.hardware.flags.luts_api") public static class DisplayLuts.Entry { + ctor @FlaggedApi("android.hardware.flags.luts_api") public DisplayLuts.Entry(@NonNull float[], int, int); + method @FlaggedApi("android.hardware.flags.luts_api") @NonNull public float[] getBuffer(); + method @FlaggedApi("android.hardware.flags.luts_api") public int getDimension(); + method @FlaggedApi("android.hardware.flags.luts_api") public int getSamplingKey(); + } + public class GeomagneticField { ctor public GeomagneticField(float, float, float, long); method public float getDeclination(); @@ -18889,8 +18901,19 @@ package android.hardware { field @FlaggedApi("android.media.codec.p210_format_support") public static final int YCBCR_P210 = 60; // 0x3c } + @FlaggedApi("android.hardware.flags.luts_api") public final class LutProperties { + method @FlaggedApi("android.hardware.flags.luts_api") public int getDimension(); + method @FlaggedApi("android.hardware.flags.luts_api") @NonNull public int[] getSamplingKeys(); + method @FlaggedApi("android.hardware.flags.luts_api") public int getSize(); + field @FlaggedApi("android.hardware.flags.luts_api") public static final int ONE_DIMENSION = 1; // 0x1 + field @FlaggedApi("android.hardware.flags.luts_api") public static final int SAMPLING_KEY_MAX_RGB = 1; // 0x1 + field @FlaggedApi("android.hardware.flags.luts_api") public static final int SAMPLING_KEY_RGB = 0; // 0x0 + field @FlaggedApi("android.hardware.flags.luts_api") public static final int THREE_DIMENSION = 3; // 0x3 + } + @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public final class OverlayProperties implements android.os.Parcelable { method @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public int describeContents(); + method @FlaggedApi("android.hardware.flags.luts_api") @NonNull public android.hardware.LutProperties[] getLutProperties(); method @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public boolean isCombinationSupported(int, int); method @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public boolean isMixedColorSpacesSupported(); method @FlaggedApi("android.hardware.flags.overlayproperties_class_api") public void writeToParcel(@NonNull android.os.Parcel, int); @@ -20630,8 +20653,14 @@ package android.hardware.display { method @NonNull public android.hardware.display.HdrConversionMode getHdrConversionMode(); method public int getMatchContentFrameRateUserPreference(); method public void registerDisplayListener(android.hardware.display.DisplayManager.DisplayListener, android.os.Handler); + method @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public void registerDisplayListener(@NonNull java.util.concurrent.Executor, long, @NonNull android.hardware.display.DisplayManager.DisplayListener); method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener); field public static final String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION"; + field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_FLAG_DISPLAY_ADDED = 1L; // 0x1L + field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_FLAG_DISPLAY_CHANGED = 4L; // 0x4L + field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_FLAG_DISPLAY_REFRESH_RATE = 8L; // 0x8L + field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_FLAG_DISPLAY_REMOVED = 2L; // 0x2L + field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_FLAG_DISPLAY_STATE = 16L; // 0x10L field public static final int MATCH_CONTENT_FRAMERATE_ALWAYS = 2; // 0x2 field public static final int MATCH_CONTENT_FRAMERATE_NEVER = 0; // 0x0 field public static final int MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY = 1; // 0x1 @@ -21021,6 +21050,7 @@ package android.inputmethodservice { method public abstract android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodImpl onCreateInputMethodInterface(); method public abstract android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface(); method public boolean onGenericMotionEvent(android.view.MotionEvent); + method @FlaggedApi("android.view.inputmethod.verify_key_event") public boolean onShouldVerifyKeyEvent(@NonNull android.view.KeyEvent); method public boolean onTrackballEvent(android.view.MotionEvent); } @@ -21038,6 +21068,7 @@ package android.inputmethodservice { method public void dispatchTrackballEvent(int, android.view.MotionEvent, android.view.inputmethod.InputMethodSession.EventCallback); method public boolean isEnabled(); method public boolean isRevoked(); + method @FlaggedApi("android.view.inputmethod.verify_key_event") public boolean onShouldVerifyKeyEvent(@NonNull android.view.KeyEvent); method public void revokeSelf(); method public void setEnabled(boolean); } @@ -21088,6 +21119,7 @@ package android.inputmethodservice { method @Deprecated public android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface(); method public android.view.View onCreateInputView(); method protected void onCurrentInputMethodSubtypeChanged(android.view.inputmethod.InputMethodSubtype); + method @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") public void onCustomImeSwitcherButtonRequestedVisible(boolean); method public void onDisplayCompletions(android.view.inputmethod.CompletionInfo[]); method public boolean onEvaluateFullscreenMode(); method @CallSuper public boolean onEvaluateInputViewShown(); @@ -21977,7 +22009,7 @@ package android.media { public final class AudioPlaybackConfiguration implements android.os.Parcelable { method public int describeContents(); method public android.media.AudioAttributes getAudioAttributes(); - method @Nullable public android.media.AudioDeviceInfo getAudioDeviceInfo(); + method @Deprecated @FlaggedApi("android.media.audio.routed_device_ids") @Nullable public android.media.AudioDeviceInfo getAudioDeviceInfo(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.media.AudioPlaybackConfiguration> CREATOR; } @@ -22060,6 +22092,7 @@ package android.media { method public android.media.AudioDeviceInfo getPreferredDevice(); method public int getRecordingState(); method public android.media.AudioDeviceInfo getRoutedDevice(); + method @FlaggedApi("android.media.audio.routed_device_ids") @NonNull public java.util.List<android.media.AudioDeviceInfo> getRoutedDevices(); method public int getSampleRate(); method public int getState(); method public int getTimestamp(@NonNull android.media.AudioTimestamp, int); @@ -22154,6 +22187,7 @@ package android.media { method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler); method public android.media.AudioDeviceInfo getPreferredDevice(); method public android.media.AudioDeviceInfo getRoutedDevice(); + method @FlaggedApi("android.media.audio.routed_device_ids") @NonNull public default java.util.List<android.media.AudioDeviceInfo> getRoutedDevices(); method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener); method public boolean setPreferredDevice(android.media.AudioDeviceInfo); } @@ -22212,6 +22246,7 @@ package android.media { method public int getPositionNotificationPeriod(); method public android.media.AudioDeviceInfo getPreferredDevice(); method public android.media.AudioDeviceInfo getRoutedDevice(); + method @FlaggedApi("android.media.audio.routed_device_ids") @NonNull public java.util.List<android.media.AudioDeviceInfo> getRoutedDevices(); method public int getSampleRate(); method @IntRange(from=1) public int getStartThresholdInFrames(); method public int getState(); @@ -24380,6 +24415,7 @@ package android.media { method @NonNull public android.media.PlaybackParams getPlaybackParams(); method public android.media.AudioDeviceInfo getPreferredDevice(); method public android.media.AudioDeviceInfo getRoutedDevice(); + method @FlaggedApi("android.media.audio.routed_device_ids") @NonNull public java.util.List<android.media.AudioDeviceInfo> getRoutedDevices(); method public int getSelectedTrack(int) throws java.lang.IllegalStateException; method @NonNull public android.media.SyncParams getSyncParams(); method @Nullable public android.media.MediaTimestamp getTimestamp(); @@ -24593,6 +24629,7 @@ package android.media { method public android.os.PersistableBundle getMetrics(); method public android.media.AudioDeviceInfo getPreferredDevice(); method public android.media.AudioDeviceInfo getRoutedDevice(); + method @FlaggedApi("android.media.audio.routed_device_ids") @NonNull public java.util.List<android.media.AudioDeviceInfo> getRoutedDevices(); method public android.view.Surface getSurface(); method public boolean isPrivacySensitive(); method public void pause() throws java.lang.IllegalStateException; @@ -33308,6 +33345,14 @@ package android.os { method public final android.os.CountDownTimer start(); } + @FlaggedApi("android.os.cpu_gpu_headrooms") public final class CpuHeadroomParams { + ctor public CpuHeadroomParams(); + method public int getCalculationType(); + method public void setCalculationType(int); + field public static final int CPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1; // 0x1 + field public static final int CPU_HEADROOM_CALCULATION_TYPE_MIN = 0; // 0x0 + } + public final class CpuUsageInfo implements android.os.Parcelable { method public int describeContents(); method public long getActive(); @@ -33555,6 +33600,14 @@ package android.os { method public void onProgress(long); } + @FlaggedApi("android.os.cpu_gpu_headrooms") public final class GpuHeadroomParams { + ctor public GpuHeadroomParams(); + method public int getCalculationType(); + method public void setCalculationType(int); + field public static final int GPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1; // 0x1 + field public static final int GPU_HEADROOM_CALCULATION_TYPE_MIN = 0; // 0x0 + } + public class Handler { ctor @Deprecated public Handler(); ctor @Deprecated public Handler(@Nullable android.os.Handler.Callback); @@ -34669,7 +34722,10 @@ package android.os { method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int); method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float); method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float, @IntRange(from=0) int); + method @FlaggedApi("android.os.vibrator.primitive_composition_absolute_delay") @NonNull public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float, @IntRange(from=0) int, int); method @NonNull public android.os.VibrationEffect compose(); + field @FlaggedApi("android.os.vibrator.primitive_composition_absolute_delay") public static final int DELAY_TYPE_PAUSE = 0; // 0x0 + field @FlaggedApi("android.os.vibrator.primitive_composition_absolute_delay") public static final int DELAY_TYPE_RELATIVE_START_OFFSET = 1; // 0x1 field public static final int PRIMITIVE_CLICK = 1; // 0x1 field public static final int PRIMITIVE_LOW_TICK = 8; // 0x8 field public static final int PRIMITIVE_QUICK_FALL = 6; // 0x6 @@ -34692,12 +34748,9 @@ package android.os { method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public boolean areEnvelopeEffectsSupported(); method @NonNull public boolean[] arePrimitivesSupported(@NonNull int...); method @RequiresPermission(android.Manifest.permission.VIBRATE) public abstract void cancel(); + method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.os.vibrator.VibratorEnvelopeEffectInfo getEnvelopeEffectInfo(); method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @Nullable public android.os.vibrator.VibratorFrequencyProfile getFrequencyProfile(); method public int getId(); - method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public int getMaxEnvelopeEffectControlPointDurationMillis(); - method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public int getMaxEnvelopeEffectDurationMillis(); - method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public int getMaxEnvelopeEffectSize(); - method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public int getMinEnvelopeEffectControlPointDurationMillis(); method @NonNull public int[] getPrimitiveDurations(@NonNull int...); method public float getQFactor(); method public float getResonantFrequency(); @@ -34805,6 +34858,10 @@ package android.os.health { } public class SystemHealthManager { + method @FlaggedApi("android.os.cpu_gpu_headrooms") @FloatRange(from=0.0f, to=100.0f) public float getCpuHeadroom(@Nullable android.os.CpuHeadroomParams); + method @FlaggedApi("android.os.cpu_gpu_headrooms") public long getCpuHeadroomMinIntervalMillis(); + method @FlaggedApi("android.os.cpu_gpu_headrooms") @FloatRange(from=0.0f, to=100.0f) public float getGpuHeadroom(@Nullable android.os.GpuHeadroomParams); + method @FlaggedApi("android.os.cpu_gpu_headrooms") public long getGpuHeadroomMinIntervalMillis(); method @FlaggedApi("com.android.server.power.optimization.power_monitor_api") public void getPowerMonitorReadings(@NonNull java.util.List<android.os.PowerMonitor>, @Nullable java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.os.PowerMonitorReadings,java.lang.RuntimeException>); method @FlaggedApi("com.android.server.power.optimization.power_monitor_api") public void getSupportedPowerMonitors(@Nullable java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<android.os.PowerMonitor>>); method public android.os.health.HealthStats takeMyUidSnapshot(); @@ -35048,6 +35105,16 @@ package android.os.strictmode { package android.os.vibrator { + @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public final class VibratorEnvelopeEffectInfo implements android.os.Parcelable { + method public int describeContents(); + method public long getMaxControlPointDurationMillis(); + method public long getMaxDurationMillis(); + method public int getMaxSize(); + method public long getMinControlPointDurationMillis(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.VibratorEnvelopeEffectInfo> CREATOR; + } + @FlaggedApi("android.os.vibrator.normalized_pwle_effects") public final class VibratorFrequencyProfile { method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @NonNull public android.util.SparseArray<java.lang.Float> getFrequenciesOutputAcceleration(); method @FlaggedApi("android.os.vibrator.normalized_pwle_effects") @Nullable public android.util.Range<java.lang.Float> getFrequencyRange(float); @@ -40714,7 +40781,7 @@ package android.service.autofill { field @NonNull public static final android.os.Parcelable.Creator<android.service.autofill.FillRequest> CREATOR; field public static final int FLAG_COMPATIBILITY_MODE_REQUEST = 2; // 0x2 field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1 - field public static final int FLAG_SUPPORTS_FILL_DIALOG = 64; // 0x40 + field @Deprecated @FlaggedApi("android.service.autofill.fill_dialog_improvements") public static final int FLAG_SUPPORTS_FILL_DIALOG = 64; // 0x40 } public final class FillResponse implements android.os.Parcelable { @@ -46657,6 +46724,8 @@ package android.telephony { method public long getDataUsageBytes(); method public long getDataUsageTime(); method @NonNull public int[] getNetworkTypes(); + method @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") @Nullable public java.time.ZonedDateTime getPlanEndDate(); + method @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public int getSubscriptionStatus(); method @Nullable public CharSequence getSummary(); method @Nullable public CharSequence getTitle(); method public void writeToParcel(android.os.Parcel, int); @@ -46667,6 +46736,11 @@ package android.telephony { field public static final int LIMIT_BEHAVIOR_DISABLED = 0; // 0x0 field public static final int LIMIT_BEHAVIOR_THROTTLED = 2; // 0x2 field public static final int LIMIT_BEHAVIOR_UNKNOWN = -1; // 0xffffffff + field @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public static final int SUBSCRIPTION_STATUS_ACTIVE = 1; // 0x1 + field @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public static final int SUBSCRIPTION_STATUS_INACTIVE = 2; // 0x2 + field @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public static final int SUBSCRIPTION_STATUS_SUSPENDED = 4; // 0x4 + field @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public static final int SUBSCRIPTION_STATUS_TRIAL = 3; // 0x3 + field @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public static final int SUBSCRIPTION_STATUS_UNKNOWN = 0; // 0x0 field public static final long TIME_UNKNOWN = -1L; // 0xffffffffffffffffL } @@ -46678,6 +46752,7 @@ package android.telephony { method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int); method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long); method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@NonNull int[]); + method @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") @NonNull public android.telephony.SubscriptionPlan.Builder setSubscriptionStatus(int); method public android.telephony.SubscriptionPlan.Builder setSummary(@Nullable CharSequence); method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence); } @@ -51408,6 +51483,7 @@ package android.view { method @Nullable public android.view.SurfaceControl.Transaction buildReparentTransaction(@NonNull android.view.SurfaceControl); method public default int getBufferTransformHint(); method @FlaggedApi("com.android.window.flags.surface_control_input_receiver") @NonNull public default android.window.InputTransferToken getInputTransferToken(); + method @FlaggedApi("com.android.window.flags.jank_api") @NonNull public default android.view.SurfaceControl.OnJankDataListenerRegistration registerOnJankDataListener(@NonNull java.util.concurrent.Executor, @NonNull android.view.SurfaceControl.OnJankDataListener); method public default void removeOnBufferTransformHintChangedListener(@NonNull android.view.AttachedSurfaceControl.OnBufferTransformHintChangedListener); method public default void setChildBoundingInsets(@NonNull android.graphics.Rect); method public default void setTouchableRegion(@Nullable android.graphics.Region); @@ -51665,6 +51741,7 @@ package android.view { field public static final int DEADLINE = 13; // 0xd field public static final int DRAW_DURATION = 4; // 0x4 field public static final int FIRST_DRAW_FRAME = 9; // 0x9 + field @FlaggedApi("com.android.window.flags.jank_api") public static final int FRAME_TIMELINE_VSYNC_ID = 14; // 0xe field public static final int GPU_DURATION = 12; // 0xc field public static final int INPUT_HANDLING_DURATION = 1; // 0x1 field public static final int INTENDED_VSYNC_TIMESTAMP = 10; // 0xa @@ -53102,6 +53179,26 @@ package android.view { method @NonNull public android.view.SurfaceControl.Builder setParent(@Nullable android.view.SurfaceControl); } + @FlaggedApi("com.android.window.flags.jank_api") public static class SurfaceControl.JankData { + method public long getActualAppFrameTimeNanos(); + method public int getJankType(); + method public long getScheduledAppFrameTimeNanos(); + method public long getVsyncId(); + field public static final int JANK_APPLICATION = 2; // 0x2 + field public static final int JANK_COMPOSER = 1; // 0x1 + field public static final int JANK_NONE = 0; // 0x0 + field public static final int JANK_OTHER = 4; // 0x4 + } + + @FlaggedApi("com.android.window.flags.jank_api") public static interface SurfaceControl.OnJankDataListener { + method public void onJankDataAvailable(@NonNull java.util.List<android.view.SurfaceControl.JankData>); + } + + @FlaggedApi("com.android.window.flags.jank_api") public static class SurfaceControl.OnJankDataListenerRegistration { + method public void flush(); + method public void removeAfter(long); + } + public static class SurfaceControl.Transaction implements java.io.Closeable android.os.Parcelable { ctor public SurfaceControl.Transaction(); method @NonNull public android.view.SurfaceControl.Transaction addTransactionCommittedListener(@NonNull java.util.concurrent.Executor, @NonNull android.view.SurfaceControl.TransactionCommittedListener); @@ -53131,6 +53228,7 @@ package android.view { method @FlaggedApi("com.android.window.flags.sdk_desired_present_time") @NonNull public android.view.SurfaceControl.Transaction setFrameTimeline(long); method @Deprecated @NonNull public android.view.SurfaceControl.Transaction setGeometry(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, int); method @NonNull public android.view.SurfaceControl.Transaction setLayer(@NonNull android.view.SurfaceControl, @IntRange(from=java.lang.Integer.MIN_VALUE, to=java.lang.Integer.MAX_VALUE) int); + method @FlaggedApi("android.hardware.flags.luts_api") @NonNull public android.view.SurfaceControl.Transaction setLuts(@NonNull android.view.SurfaceControl, @Nullable android.hardware.DisplayLuts); method @NonNull public android.view.SurfaceControl.Transaction setOpaque(@NonNull android.view.SurfaceControl, boolean); method @NonNull public android.view.SurfaceControl.Transaction setPosition(@NonNull android.view.SurfaceControl, float, float); method @NonNull public android.view.SurfaceControl.Transaction setScale(@NonNull android.view.SurfaceControl, float, float); @@ -56555,13 +56653,13 @@ package android.view.autofill { method public void notifyViewExited(@NonNull android.view.View, int); method public void notifyViewVisibilityChanged(@NonNull android.view.View, boolean); method public void notifyViewVisibilityChanged(@NonNull android.view.View, int, boolean); - method public void notifyVirtualViewsReady(@NonNull android.view.View, @NonNull android.util.SparseArray<android.view.autofill.VirtualViewFillInfo>); + method @Deprecated @FlaggedApi("android.service.autofill.fill_dialog_improvements") public void notifyVirtualViewsReady(@NonNull android.view.View, @NonNull android.util.SparseArray<android.view.autofill.VirtualViewFillInfo>); method public void registerCallback(@Nullable android.view.autofill.AutofillManager.AutofillCallback); method public void requestAutofill(@NonNull android.view.View); method public void requestAutofill(@NonNull android.view.View, int, @NonNull android.graphics.Rect); method public void setUserData(@Nullable android.service.autofill.UserData); - method public boolean showAutofillDialog(@NonNull android.view.View); - method public boolean showAutofillDialog(@NonNull android.view.View, int); + method @Deprecated @FlaggedApi("android.service.autofill.fill_dialog_improvements") public boolean showAutofillDialog(@NonNull android.view.View); + method @Deprecated @FlaggedApi("android.service.autofill.fill_dialog_improvements") public boolean showAutofillDialog(@NonNull android.view.View, int); method public void unregisterCallback(@Nullable android.view.autofill.AutofillManager.AutofillCallback); field public static final String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE"; field public static final String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT"; @@ -56914,6 +57012,7 @@ package android.view.inputmethod { ctor public EditorInfo(); method public int describeContents(); method public void dump(android.util.Printer, String); + method @FlaggedApi("android.view.inputmethod.public_autofill_id_in_editorinfo") @Nullable public android.view.autofill.AutofillId getAutofillId(); method @Nullable public CharSequence getInitialSelectedText(int); method @Nullable public android.view.inputmethod.SurroundingText getInitialSurroundingText(@IntRange(from=0) int, @IntRange(from=0) int, int); method @Nullable public CharSequence getInitialTextAfterCursor(@IntRange(from=0) int, int); @@ -56922,13 +57021,16 @@ package android.view.inputmethod { method @NonNull public java.util.Set<java.lang.Class<? extends android.view.inputmethod.PreviewableHandwritingGesture>> getSupportedHandwritingGesturePreviews(); method @NonNull public java.util.List<java.lang.Class<? extends android.view.inputmethod.HandwritingGesture>> getSupportedHandwritingGestures(); method @FlaggedApi("android.view.inputmethod.editorinfo_handwriting_enabled") public boolean isStylusHandwritingEnabled(); + method @FlaggedApi("android.view.inputmethod.writing_tools") public boolean isWritingToolsEnabled(); method public final void makeCompatible(int); + method @FlaggedApi("android.view.inputmethod.public_autofill_id_in_editorinfo") public void setAutofillId(@Nullable android.view.autofill.AutofillId); method public void setInitialSurroundingSubText(@NonNull CharSequence, int); method public void setInitialSurroundingText(@NonNull CharSequence); method public void setInitialToolType(int); method @FlaggedApi("android.view.inputmethod.editorinfo_handwriting_enabled") public void setStylusHandwritingEnabled(boolean); method public void setSupportedHandwritingGesturePreviews(@NonNull java.util.Set<java.lang.Class<? extends android.view.inputmethod.PreviewableHandwritingGesture>>); method public void setSupportedHandwritingGestures(@NonNull java.util.List<java.lang.Class<? extends android.view.inputmethod.HandwritingGesture>>); + method @FlaggedApi("android.view.inputmethod.writing_tools") public void setWritingToolsEnabled(boolean); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.view.inputmethod.EditorInfo> CREATOR; field public static final int IME_ACTION_DONE = 6; // 0x6 diff --git a/core/api/system-current.txt b/core/api/system-current.txt index f9ef62f6b2e8..fee53d60691b 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -1378,7 +1378,8 @@ package android.app.admin { method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void setDpcDownloaded(boolean); method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void setMaxPolicyStorageLimit(int); method @Deprecated @RequiresPermission(value=android.Manifest.permission.GRANT_PROFILE_OWNER_DEVICE_IDS_ACCESS, conditional=true) public void setProfileOwnerCanAccessDeviceIds(@NonNull android.content.ComponentName); - method public void setSecondaryLockscreenEnabled(@NonNull android.content.ComponentName, boolean); + method @Deprecated @FlaggedApi("android.app.admin.flags.secondary_lockscreen_api_enabled") public void setSecondaryLockscreenEnabled(@NonNull android.content.ComponentName, boolean); + method @FlaggedApi("android.app.admin.flags.secondary_lockscreen_api_enabled") public void setSecondaryLockscreenEnabled(boolean, @Nullable android.os.PersistableBundle); method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void setUserProvisioningState(int, @NonNull android.os.UserHandle); method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public boolean shouldAllowBypassingDevicePolicyManagementRoleQualification(); field public static final String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_ALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_ALLOWED"; @@ -7463,6 +7464,7 @@ package android.media { } public final class AudioPlaybackConfiguration implements android.os.Parcelable { + method @FlaggedApi("android.media.audio.routed_device_ids") @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceInfo> getAudioDeviceInfos(); method public int getChannelMask(); method public int getClientPid(); method public int getClientUid(); @@ -7617,7 +7619,7 @@ package android.media { public final class MediaCas implements java.lang.AutoCloseable { method @FlaggedApi("android.media.tv.flags.set_resource_holder_retain") @RequiresPermission("android.permission.TUNER_RESOURCE_ACCESS") public void setResourceHolderRetain(boolean); - method @FlaggedApi("com.android.media.flags.update_client_profile_priority") @RequiresPermission("android.permission.TUNER_RESOURCE_ACCESS") public boolean updateResourcePriority(int, int); + method @FlaggedApi("android.media.tv.flags.mediacas_update_client_profile_priority") @RequiresPermission("android.permission.TUNER_RESOURCE_ACCESS") public boolean updateResourcePriority(int, int); } public final class MediaCodec { @@ -8246,6 +8248,26 @@ package android.media.tv { method public void onSetMain(boolean); } + @FlaggedApi("android.media.tv.flags.tif_extension_standardization") public final class TvInputServiceExtensionManager { + method @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE) public int registerExtensionIBinder(@NonNull String, @NonNull android.os.IBinder); + field public static final String IBROADCAST_TIME = "android.media.tv.extension.time.BroadcastTime"; + field public static final String ICAM_APP_INFO_SERVICE = "android.media.tv.extension.cam.ICamAppInfoService"; + field public static final String ICLIENT_TOKEN = "android.media.tv.extension.clienttoken.IClientToken"; + field public static final String IDATA_SERVICE_SIGNAL_INFO = "android.media.tv.extension.teletext.IDataServiceSignalInfo"; + field public static final String IEVENT_MONITOR = "android.media.tv.extension.event.IEventMonitor"; + field public static final String IHDMI_SIGNAL_INTERFACE = "android.media.tv.extension.signal.IHdmiSignalInterface"; + field public static final String IOAD_UPDATE_INTERFACE = "android.media.tv.extension.oad.IOadUpdateInterface"; + field public static final String IRATING_INTERFACE = "android.media.tv.extension.rating.IRatingInterface"; + field public static final String IRECORDED_CONTENTS = "android.media.tv.extension.pvr.IRecordedContents"; + field public static final String ISCAN_INTERFACE = "android.media.tv.extension.scan.IScanInterface"; + field public static final String ISCREEN_MODE_SETTINGS = "android.media.tv.extension.screenmode.IScreenModeSettings"; + field public static final String ISERVICE_LIST_EDIT_LISTENER = "android.media.tv.extension.servicedb.IServiceListEditListener"; + field public static final int REGISTER_FAIL_IMPLEMENTATION_NOT_STANDARDIZED = 2; // 0x2 + field public static final int REGISTER_FAIL_NAME_NOT_STANDARDIZED = 1; // 0x1 + field public static final int REGISTER_FAIL_REMOTE_EXCEPTION = 3; // 0x3 + field public static final int REGISTER_SUCCESS = 0; // 0x0 + } + public abstract static class TvRecordingClient.RecordingCallback { method public void onEvent(String, String, android.os.Bundle); } @@ -12532,8 +12554,19 @@ package android.security.advancedprotection { } @FlaggedApi("android.security.aapm_api") public final class AdvancedProtectionManager { + method @NonNull public android.content.Intent createSupportIntent(@NonNull String, @Nullable String); method @NonNull @RequiresPermission(android.Manifest.permission.SET_ADVANCED_PROTECTION_MODE) public java.util.List<android.security.advancedprotection.AdvancedProtectionFeature> getAdvancedProtectionFeatures(); method @RequiresPermission(android.Manifest.permission.SET_ADVANCED_PROTECTION_MODE) public void setAdvancedProtectionEnabled(boolean); + field @FlaggedApi("android.security.aapm_api") public static final String ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG = "android.security.advancedprotection.action.SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG"; + field public static final String EXTRA_SUPPORT_DIALOG_FEATURE = "android.security.advancedprotection.extra.SUPPORT_DIALOG_FEATURE"; + field public static final String EXTRA_SUPPORT_DIALOG_TYPE = "android.security.advancedprotection.extra.SUPPORT_DIALOG_TYPE"; + field public static final String FEATURE_ID_DISALLOW_CELLULAR_2G = "android.security.advancedprotection.feature_disallow_2g"; + field public static final String FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES = "android.security.advancedprotection.feature_disallow_install_unknown_sources"; + field public static final String FEATURE_ID_DISALLOW_USB = "android.security.advancedprotection.feature_disallow_usb"; + field public static final String FEATURE_ID_DISALLOW_WEP = "android.security.advancedprotection.feature_disallow_wep"; + field public static final String FEATURE_ID_ENABLE_MTE = "android.security.advancedprotection.feature_enable_mte"; + field public static final String SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION = "android.security.advancedprotection.type_blocked_interaction"; + field public static final String SUPPORT_DIALOG_TYPE_DISABLED_SETTING = "android.security.advancedprotection.type_disabled_setting"; } } diff --git a/core/api/test-current.txt b/core/api/test-current.txt index c8ecfa94ec87..119271390b94 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2065,6 +2065,29 @@ package android.media { method public boolean isAidlHal(); } + public final class MediaCodec { + method @FlaggedApi("android.media.codec.codec_availability") @NonNull public static java.util.List<android.media.MediaCodec.GlobalResourceInfo> getGloballyAvailableResources(); + method @FlaggedApi("android.media.codec.codec_availability") @NonNull public java.util.List<android.media.MediaCodec.InstanceResourceInfo> getRequiredResources(); + } + + public abstract static class MediaCodec.Callback { + method @FlaggedApi("android.media.codec.codec_availability") public void onRequiredResourcesChanged(@NonNull android.media.MediaCodec); + } + + @FlaggedApi("android.media.codec.codec_availability") public static final class MediaCodec.GlobalResourceInfo { + ctor public MediaCodec.GlobalResourceInfo(); + method public long getAvailable(); + method public long getCapacity(); + method @NonNull public String getName(); + } + + @FlaggedApi("android.media.codec.codec_availability") public static final class MediaCodec.InstanceResourceInfo { + ctor public MediaCodec.InstanceResourceInfo(); + method @NonNull public String getName(); + method public long getPerFrameCount(); + method public long getStaticCount(); + } + public static final class MediaCodecInfo.VideoCapabilities.PerformancePoint { ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(int, int, int, int, @NonNull android.util.Size); ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(@NonNull android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint, @NonNull android.util.Size); diff --git a/core/java/Android.bp b/core/java/Android.bp index cf5ebbaa37b4..bc38294279a8 100644 --- a/core/java/Android.bp +++ b/core/java/Android.bp @@ -232,6 +232,8 @@ aidl_interface { "android.hardware.power-aidl", ], srcs: [ + "android/os/CpuHeadroomParamsInternal.aidl", + "android/os/GpuHeadroomParamsInternal.aidl", "android/os/IHintManager.aidl", "android/os/IHintSession.aidl", ], diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index b447897733e1..ab75069cc5d8 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -1017,6 +1017,12 @@ public class ActivityManager { public static final int PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL = 1 << 6; /** + * @hide + * Process is guaranteed cpu time (IE. it will not be frozen). + */ + public static final int PROCESS_CAPABILITY_CPU_TIME = 1 << 7; + + /** * @hide all capabilities, the ORing of all flags in {@link ProcessCapability}. * * Don't expose it as TestApi -- we may add new capabilities any time, which could @@ -1028,7 +1034,8 @@ public class ActivityManager { | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK | PROCESS_CAPABILITY_BFSL | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK - | PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; + | PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL + | PROCESS_CAPABILITY_CPU_TIME; /** * All implicit capabilities. This capability set is currently only used for processes under @@ -1053,6 +1060,7 @@ public class ActivityManager { pw.print((caps & PROCESS_CAPABILITY_BFSL) != 0 ? 'F' : '-'); pw.print((caps & PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0 ? 'U' : '-'); pw.print((caps & PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL) != 0 ? 'A' : '-'); + pw.print((caps & PROCESS_CAPABILITY_CPU_TIME) != 0 ? 'T' : '-'); } /** @hide */ @@ -1065,6 +1073,7 @@ public class ActivityManager { sb.append((caps & PROCESS_CAPABILITY_BFSL) != 0 ? 'F' : '-'); sb.append((caps & PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0 ? 'U' : '-'); sb.append((caps & PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL) != 0 ? 'A' : '-'); + sb.append((caps & PROCESS_CAPABILITY_CPU_TIME) != 0 ? 'T' : '-'); } /** @@ -5291,7 +5300,6 @@ public class ActivityManager { if (!exported) { /* RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid, here); */ diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 60b8f80d8f2d..cb7b1153988a 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1961,12 +1961,8 @@ public final class ActivityThread extends ClientTransactionHandler @Override public void dumpCacheInfo(ParcelFileDescriptor pfd, String[] args) { - try { - PropertyInvalidatedCache.dumpCacheInfo(pfd, args); - BroadcastStickyCache.dump(pfd); - } finally { - IoUtils.closeQuietly(pfd); - } + PropertyInvalidatedCache.dumpCacheInfo(pfd, args); + IoUtils.closeQuietly(pfd); } private File getDatabasesDir(Context context) { diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index fb5a12b49921..e247916915d6 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -1835,7 +1835,6 @@ public class ApplicationPackageManager extends PackageManager { if (false) { RuntimeException e = new RuntimeException("here"); - e.fillInStackTrace(); Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resId) + " from package " + packageName + ": app scale=" + r.getCompatibilityInfo().applicationScale diff --git a/core/java/android/app/BroadcastStickyCache.java b/core/java/android/app/BroadcastStickyCache.java deleted file mode 100644 index ea8173191a3f..000000000000 --- a/core/java/android/app/BroadcastStickyCache.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.app; - -import android.annotation.IntRange; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.Intent; -import android.content.IntentFilter; -import android.hardware.usb.UsbManager; -import android.media.AudioManager; -import android.net.ConnectivityManager; -import android.net.TetheringManager; -import android.net.nsd.NsdManager; -import android.net.wifi.WifiManager; -import android.net.wifi.p2p.WifiP2pManager; -import android.os.ParcelFileDescriptor; -import android.os.SystemProperties; -import android.os.UpdateLock; -import android.telephony.TelephonyManager; -import android.util.ArrayMap; -import android.util.IndentingPrintWriter; -import android.view.WindowManagerPolicyConstants; - -import com.android.internal.annotations.GuardedBy; -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.ArrayUtils; -import com.android.internal.util.FastPrintWriter; - -import java.io.FileOutputStream; -import java.io.PrintWriter; -import java.util.ArrayList; - -/** @hide */ -public class BroadcastStickyCache { - - private static final String[] CACHED_BROADCAST_ACTIONS = { - AudioManager.ACTION_HDMI_AUDIO_PLUG, - AudioManager.ACTION_HEADSET_PLUG, - AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED, - AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED, - AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, - AudioManager.RINGER_MODE_CHANGED_ACTION, - ConnectivityManager.CONNECTIVITY_ACTION, - Intent.ACTION_BATTERY_CHANGED, - Intent.ACTION_DEVICE_STORAGE_FULL, - Intent.ACTION_DEVICE_STORAGE_LOW, - Intent.ACTION_SIM_STATE_CHANGED, - NsdManager.ACTION_NSD_STATE_CHANGED, - TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED, - TetheringManager.ACTION_TETHER_STATE_CHANGED, - UpdateLock.UPDATE_LOCK_CHANGED, - UsbManager.ACTION_USB_STATE, - WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED, - WifiManager.NETWORK_STATE_CHANGED_ACTION, - WifiManager.SUPPLICANT_STATE_CHANGED_ACTION, - WifiManager.WIFI_STATE_CHANGED_ACTION, - WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION, - WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED, - "android.net.conn.INET_CONDITION_ACTION" // ConnectivityManager.INET_CONDITION_ACTION - }; - - @GuardedBy("sCachedStickyBroadcasts") - private static final ArrayList<CachedStickyBroadcast> sCachedStickyBroadcasts = - new ArrayList<>(); - - @GuardedBy("sCachedPropertyHandles") - private static final ArrayMap<String, SystemProperties.Handle> sCachedPropertyHandles = - new ArrayMap<>(); - - @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - public static boolean useCache(@Nullable IntentFilter filter) { - if (!shouldCache(filter)) { - return false; - } - synchronized (sCachedStickyBroadcasts) { - final CachedStickyBroadcast cachedStickyBroadcast = getValueUncheckedLocked(filter); - if (cachedStickyBroadcast == null) { - return false; - } - final long version = cachedStickyBroadcast.propertyHandle.getLong(-1 /* def */); - return version > 0 && cachedStickyBroadcast.version == version; - } - } - - @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - public static void add(@Nullable IntentFilter filter, @Nullable Intent intent) { - if (!shouldCache(filter)) { - return; - } - synchronized (sCachedStickyBroadcasts) { - CachedStickyBroadcast cachedStickyBroadcast = getValueUncheckedLocked(filter); - if (cachedStickyBroadcast == null) { - final String key = getKey(filter.getAction(0)); - final SystemProperties.Handle handle = SystemProperties.find(key); - final long version = handle == null ? -1 : handle.getLong(-1 /* def */); - if (version == -1) { - return; - } - cachedStickyBroadcast = new CachedStickyBroadcast(filter, handle); - sCachedStickyBroadcasts.add(cachedStickyBroadcast); - cachedStickyBroadcast.intent = intent; - cachedStickyBroadcast.version = version; - } else { - cachedStickyBroadcast.intent = intent; - cachedStickyBroadcast.version = cachedStickyBroadcast.propertyHandle - .getLong(-1 /* def */); - } - } - } - - private static boolean shouldCache(@Nullable IntentFilter filter) { - if (!Flags.useStickyBcastCache()) { - return false; - } - if (filter == null || filter.safeCountActions() != 1) { - return false; - } - if (!ArrayUtils.contains(CACHED_BROADCAST_ACTIONS, filter.getAction(0))) { - return false; - } - return true; - } - - @VisibleForTesting - @NonNull - public static String getKey(@NonNull String action) { - return "cache_key.system_server.sticky_bcast." + action; - } - - @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - @Nullable - public static Intent getIntentUnchecked(@NonNull IntentFilter filter) { - synchronized (sCachedStickyBroadcasts) { - final CachedStickyBroadcast cachedStickyBroadcast = getValueUncheckedLocked(filter); - return cachedStickyBroadcast.intent; - } - } - - @GuardedBy("sCachedStickyBroadcasts") - @Nullable - private static CachedStickyBroadcast getValueUncheckedLocked(@NonNull IntentFilter filter) { - for (int i = sCachedStickyBroadcasts.size() - 1; i >= 0; --i) { - final CachedStickyBroadcast cachedStickyBroadcast = sCachedStickyBroadcasts.get(i); - if (IntentFilter.filterEquals(filter, cachedStickyBroadcast.filter)) { - return cachedStickyBroadcast; - } - } - return null; - } - - public static void incrementVersion(@NonNull String action) { - if (!shouldIncrementVersion(action)) { - return; - } - final String key = getKey(action); - synchronized (sCachedPropertyHandles) { - SystemProperties.Handle handle = sCachedPropertyHandles.get(key); - final long version; - if (handle == null) { - handle = SystemProperties.find(key); - if (handle != null) { - sCachedPropertyHandles.put(key, handle); - } - } - version = handle == null ? 0 : handle.getLong(0 /* def */); - SystemProperties.set(key, String.valueOf(version + 1)); - if (handle == null) { - sCachedPropertyHandles.put(key, SystemProperties.find(key)); - } - } - } - - public static void incrementVersionIfExists(@NonNull String action) { - if (!shouldIncrementVersion(action)) { - return; - } - final String key = getKey(action); - synchronized (sCachedPropertyHandles) { - final SystemProperties.Handle handle = sCachedPropertyHandles.get(key); - if (handle == null) { - return; - } - final long version = handle.getLong(0 /* def */); - SystemProperties.set(key, String.valueOf(version + 1)); - } - } - - private static boolean shouldIncrementVersion(@NonNull String action) { - if (!Flags.useStickyBcastCache()) { - return false; - } - if (!ArrayUtils.contains(CACHED_BROADCAST_ACTIONS, action)) { - return false; - } - return true; - } - - @VisibleForTesting - public static void clearForTest() { - synchronized (sCachedStickyBroadcasts) { - sCachedStickyBroadcasts.clear(); - } - synchronized (sCachedPropertyHandles) { - sCachedPropertyHandles.clear(); - } - } - - public static void dump(@NonNull ParcelFileDescriptor pfd) { - if (!Flags.useStickyBcastCache()) { - return; - } - final PrintWriter pw = new FastPrintWriter(new FileOutputStream(pfd.getFileDescriptor())); - synchronized (sCachedStickyBroadcasts) { - dumpLocked(pw); - } - pw.flush(); - } - - @GuardedBy("sCachedStickyBroadcasts") - private static void dumpLocked(@NonNull PrintWriter pw) { - final IndentingPrintWriter ipw = new IndentingPrintWriter( - pw, " " /* singleIndent */, " " /* prefix */); - ipw.println("Cached sticky broadcasts:"); - ipw.increaseIndent(); - final int count = sCachedStickyBroadcasts.size(); - if (count == 0) { - ipw.println("<empty>"); - } else { - for (int i = 0; i < count; ++i) { - final CachedStickyBroadcast cachedStickyBroadcast = sCachedStickyBroadcasts.get(i); - ipw.print("Entry #"); ipw.print(i); ipw.println(":"); - ipw.increaseIndent(); - ipw.print("filter="); ipw.println(cachedStickyBroadcast.filter.toLongString()); - ipw.print("intent="); ipw.println(cachedStickyBroadcast.intent); - ipw.print("version="); ipw.println(cachedStickyBroadcast.version); - ipw.print("handle="); ipw.println(cachedStickyBroadcast.propertyHandle); - ipw.decreaseIndent(); - } - } - ipw.decreaseIndent(); - } - - private static final class CachedStickyBroadcast { - @NonNull public final IntentFilter filter; - @Nullable public Intent intent; - @IntRange(from = 0) public long version; - @NonNull public final SystemProperties.Handle propertyHandle; - - CachedStickyBroadcast(@NonNull IntentFilter filter, - @NonNull SystemProperties.Handle propertyHandle) { - this.filter = filter; - this.propertyHandle = propertyHandle; - } - } -} diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 3ae60d71facd..cd56957ed5d1 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1922,19 +1922,10 @@ class ContextImpl extends Context { } } try { - final Intent intent; - if (receiver == null && BroadcastStickyCache.useCache(filter)) { - intent = BroadcastStickyCache.getIntentUnchecked(filter); - } else { - intent = ActivityManager.getService().registerReceiverWithFeature( - mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(), - AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission, - userId, - flags); - if (receiver == null) { - BroadcastStickyCache.add(filter, intent); - } - } + final Intent intent = ActivityManager.getService().registerReceiverWithFeature( + mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(), + AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission, userId, + flags); if (intent != null) { intent.setExtrasClassLoader(getClassLoader()); // TODO: determine at registration time if caller is diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 0654ac2f33ce..9bb16ae7fa02 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -124,7 +124,7 @@ interface INotificationManager boolean onlyHasDefaultChannel(String pkg, int uid); boolean areChannelsBypassingDnd(); ParceledListSlice getNotificationChannelsBypassingDnd(String pkg, int uid); - List<String> getPackagesBypassingDnd(int userId, boolean includeConversationChannels); + ParceledListSlice getPackagesBypassingDnd(int userId); boolean isPackagePaused(String pkg); void deleteNotificationHistoryItem(String pkg, int uid, long postedTime); boolean isPermissionFixed(String pkg, int userId); diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index b8233bc498b8..3d85ea6a1fca 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -1660,7 +1660,6 @@ public final class LoadedApk { } RuntimeException ex = new IllegalArgumentException( "Originally unregistered here:"); - ex.fillInStackTrace(); rd.setUnregisterLocation(ex); holder.put(r, rd); } @@ -1860,7 +1859,6 @@ public final class LoadedApk { mInstrumentation = instrumentation; mRegistered = registered; mLocation = new IntentReceiverLeaked(null); - mLocation.fillInStackTrace(); } void validate(Context context, Handler activityThread) { @@ -2000,7 +1998,6 @@ public final class LoadedApk { } RuntimeException ex = new IllegalArgumentException( "Originally unbound here:"); - ex.fillInStackTrace(); sd.setUnbindLocation(ex); holder.put(c, sd); } @@ -2076,7 +2073,6 @@ public final class LoadedApk { mActivityThread = activityThread; mActivityExecutor = null; mLocation = new ServiceConnectionLeaked(null); - mLocation.fillInStackTrace(); mFlags = flags; } @@ -2088,7 +2084,6 @@ public final class LoadedApk { mActivityThread = null; mActivityExecutor = activityExecutor; mLocation = new ServiceConnectionLeaked(null); - mLocation.fillInStackTrace(); mFlags = flags; } diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java index e2de716d7e74..a70d4937b46c 100644 --- a/core/java/android/app/LoaderManager.java +++ b/core/java/android/app/LoaderManager.java @@ -83,7 +83,7 @@ public abstract class LoaderManager { * transactions while in this call, since it can happen after an * activity's state is saved. See {@link FragmentManager#beginTransaction() * FragmentManager.openTransaction()} for further discussion on this. - * + * * <p>This function is guaranteed to be called prior to the release of * the last data that was supplied for this Loader. At this point * you should remove all use of the old data (since it will be released @@ -127,7 +127,7 @@ public abstract class LoaderManager { */ public void onLoaderReset(Loader<D> loader); } - + /** * Ensures a loader is initialized and active. If the loader doesn't * already exist, one is created and (if the activity/fragment is currently @@ -228,7 +228,7 @@ class LoaderManagerImpl extends LoaderManager { boolean mStarted; boolean mRetaining; boolean mRetainingStarted; - + boolean mCreatingLoader; private FragmentHostCallback mHost; @@ -249,13 +249,13 @@ class LoaderManagerImpl extends LoaderManager { boolean mListenerRegistered; LoaderInfo mPendingLoader; - + public LoaderInfo(int id, Bundle args, LoaderManager.LoaderCallbacks<Object> callbacks) { mId = id; mArgs = args; mCallbacks = callbacks; } - + void start() { if (mRetaining && mRetainingStarted) { // Our owner is started, but we were being retained from a @@ -271,7 +271,7 @@ class LoaderManagerImpl extends LoaderManager { } mStarted = true; - + if (DEBUG) Log.v(TAG, " Starting: " + this); if (mLoader == null && mCallbacks != null) { mLoader = mCallbacks.onCreateLoader(mId, mArgs); @@ -291,7 +291,7 @@ class LoaderManagerImpl extends LoaderManager { mLoader.startLoading(); } } - + void retain() { if (DEBUG) Log.v(TAG, " Retaining: " + this); mRetaining = true; @@ -299,7 +299,7 @@ class LoaderManagerImpl extends LoaderManager { mStarted = false; mCallbacks = null; } - + void finishRetain() { if (mRetaining) { if (DEBUG) Log.v(TAG, " Finished Retaining: " + this); @@ -324,7 +324,7 @@ class LoaderManagerImpl extends LoaderManager { callOnLoadFinished(mLoader, mData); } } - + void reportStart() { if (mStarted) { if (mReportNextStart) { @@ -430,7 +430,7 @@ class LoaderManagerImpl extends LoaderManager { @Override public void onLoadComplete(Loader<Object> loader, Object data) { if (DEBUG) Log.v(TAG, "onLoadComplete: " + this); - + if (mDestroyed) { if (DEBUG) Log.v(TAG, " Ignoring load complete -- destroyed"); return; @@ -442,7 +442,7 @@ class LoaderManagerImpl extends LoaderManager { if (DEBUG) Log.v(TAG, " Ignoring load complete -- not active"); return; } - + LoaderInfo pending = mPendingLoader; if (pending != null) { // There is a new request pending and we were just @@ -455,7 +455,7 @@ class LoaderManagerImpl extends LoaderManager { installLoader(pending); return; } - + // Notify of the new data so the app can switch out the old data before // we try to destroy it. if (mData != data || !mHaveData) { @@ -503,7 +503,7 @@ class LoaderManagerImpl extends LoaderManager { mDeliveredData = true; } } - + @Override public String toString() { StringBuilder sb = new StringBuilder(64); @@ -543,13 +543,13 @@ class LoaderManagerImpl extends LoaderManager { } } } - + LoaderManagerImpl(String who, FragmentHostCallback host, boolean started) { mWho = who; mHost = host; mStarted = started; } - + void updateHostController(FragmentHostCallback host) { mHost = host; } @@ -557,7 +557,7 @@ class LoaderManagerImpl extends LoaderManager { public FragmentHostCallback getFragmentHostCallback() { return mHost; } - + private LoaderInfo createLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<Object> callback) { LoaderInfo info = new LoaderInfo(id, args, (LoaderManager.LoaderCallbacks<Object>)callback); @@ -565,7 +565,7 @@ class LoaderManagerImpl extends LoaderManager { info.mLoader = (Loader<Object>)loader; return info; } - + private LoaderInfo createAndInstallLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<Object> callback) { try { @@ -577,7 +577,7 @@ class LoaderManagerImpl extends LoaderManager { mCreatingLoader = false; } } - + void installLoader(LoaderInfo info) { mLoaders.put(info.mId, info); if (mStarted) { @@ -587,23 +587,23 @@ class LoaderManagerImpl extends LoaderManager { info.start(); } } - + /** * Call to initialize a particular ID with a Loader. If this ID already * has a Loader associated with it, it is left unchanged and any previous * callbacks replaced with the newly provided ones. If there is not currently * a Loader for the ID, a new one is created and started. - * + * * <p>This function should generally be used when a component is initializing, * to ensure that a Loader it relies on is created. This allows it to re-use * an existing Loader's data if there already is one, so that for example * when an {@link Activity} is re-created after a configuration change it * does not need to re-create its loaders. - * + * * <p>Note that in the case where an existing Loader is re-used, the * <var>args</var> given here <em>will be ignored</em> because you will * continue using the previous Loader. - * + * * @param id A unique (to this LoaderManager instance) identifier under * which to manage the new Loader. * @param args Optional arguments that will be propagated to @@ -617,9 +617,9 @@ class LoaderManagerImpl extends LoaderManager { if (mCreatingLoader) { throw new IllegalStateException("Called while creating a loader"); } - + LoaderInfo info = mLoaders.get(id); - + if (DEBUG) Log.v(TAG, "initLoader in " + this + ": args=" + args); if (info == null) { @@ -630,30 +630,30 @@ class LoaderManagerImpl extends LoaderManager { if (DEBUG) Log.v(TAG, " Re-using existing loader " + info); info.mCallbacks = (LoaderManager.LoaderCallbacks<Object>)callback; } - + if (info.mHaveData && mStarted) { // If the loader has already generated its data, report it now. info.callOnLoadFinished(info.mLoader, info.mData); } - + return (Loader<D>)info.mLoader; } - + /** * Call to re-create the Loader associated with a particular ID. If there * is currently a Loader associated with this ID, it will be * canceled/stopped/destroyed as appropriate. A new Loader with the given * arguments will be created and its data delivered to you once available. - * + * * <p>This function does some throttling of Loaders. If too many Loaders * have been created for the given ID but not yet generated their data, * new calls to this function will create and return a new Loader but not * actually start it until some previous loaders have completed. - * + * * <p>After calling this function, any previous Loaders associated with * this ID will be considered invalid, and you will receive no further * data updates from them. - * + * * @param id A unique (to this LoaderManager instance) identifier under * which to manage the new Loader. * @param args Optional arguments that will be propagated to @@ -667,7 +667,7 @@ class LoaderManagerImpl extends LoaderManager { if (mCreatingLoader) { throw new IllegalStateException("Called while creating a loader"); } - + LoaderInfo info = mLoaders.get(id); if (DEBUG) Log.v(TAG, "restartLoader in " + this + ": args=" + args); if (info != null) { @@ -706,7 +706,7 @@ class LoaderManagerImpl extends LoaderManager { info.mPendingLoader = null; } if (DEBUG) Log.v(TAG, " Enqueuing as new pending loader"); - info.mPendingLoader = createLoader(id, args, + info.mPendingLoader = createLoader(id, args, (LoaderManager.LoaderCallbacks<Object>)callback); return (Loader<D>)info.mPendingLoader.mLoader; } @@ -719,11 +719,11 @@ class LoaderManagerImpl extends LoaderManager { mInactiveLoaders.put(id, info); } } - + info = createAndInstallLoader(id, args, (LoaderManager.LoaderCallbacks<Object>)callback); return (Loader<D>)info.mLoader; } - + /** * Rip down, tear apart, shred to pieces a current Loader ID. After returning * from this function, any Loader objects associated with this ID are @@ -735,7 +735,7 @@ class LoaderManagerImpl extends LoaderManager { if (mCreatingLoader) { throw new IllegalStateException("Called while creating a loader"); } - + if (DEBUG) Log.v(TAG, "destroyLoader in " + this + " of " + id); int idx = mLoaders.indexOfKey(id); if (idx >= 0) { @@ -763,7 +763,7 @@ class LoaderManagerImpl extends LoaderManager { if (mCreatingLoader) { throw new IllegalStateException("Called while creating a loader"); } - + LoaderInfo loaderInfo = mLoaders.get(id); if (loaderInfo != null) { if (loaderInfo.mPendingLoader != null) { @@ -773,16 +773,15 @@ class LoaderManagerImpl extends LoaderManager { } return null; } - + void doStart() { if (DEBUG) Log.v(TAG, "Starting in " + this); if (mStarted) { RuntimeException e = new RuntimeException("here"); - e.fillInStackTrace(); Log.w(TAG, "Called doStart when already started: " + this, e); return; } - + mStarted = true; // Call out to sub classes so they can start their loaders @@ -791,12 +790,11 @@ class LoaderManagerImpl extends LoaderManager { mLoaders.valueAt(i).start(); } } - + void doStop() { if (DEBUG) Log.v(TAG, "Stopping in " + this); if (!mStarted) { RuntimeException e = new RuntimeException("here"); - e.fillInStackTrace(); Log.w(TAG, "Called doStop when not started: " + this, e); return; } @@ -806,12 +804,11 @@ class LoaderManagerImpl extends LoaderManager { } mStarted = false; } - + void doRetain() { if (DEBUG) Log.v(TAG, "Retaining in " + this); if (!mStarted) { RuntimeException e = new RuntimeException("here"); - e.fillInStackTrace(); Log.w(TAG, "Called doRetain when not started: " + this, e); return; } @@ -822,7 +819,7 @@ class LoaderManagerImpl extends LoaderManager { mLoaders.valueAt(i).retain(); } } - + void finishRetain() { if (mRetaining) { if (DEBUG) Log.v(TAG, "Finished Retaining in " + this); @@ -833,7 +830,7 @@ class LoaderManagerImpl extends LoaderManager { } } } - + void doReportNextStart() { for (int i = mLoaders.size()-1; i >= 0; i--) { mLoaders.valueAt(i).mReportNextStart = true; @@ -854,7 +851,7 @@ class LoaderManagerImpl extends LoaderManager { } mLoaders.clear(); } - + if (DEBUG) Log.v(TAG, "Destroying Inactive in " + this); for (int i = mInactiveLoaders.size()-1; i >= 0; i--) { mInactiveLoaders.valueAt(i).destroy(); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 0381ee0e25ac..3d9c55c0f37a 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -5003,7 +5003,7 @@ public class Notification implements Parcelable /** * Sets a very short string summarizing the most critical information contained in the - * notification. Suggested max length is 5 characters, and there is no guarantee how much or + * notification. Suggested max length is 7 characters, and there is no guarantee how much or * how little of this text will be shown. */ @FlaggedApi(Flags.FLAG_API_RICH_ONGOING) diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index a458b4e45796..087e246e8841 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -174,22 +174,54 @@ public class ResourcesManager { } /** - * Apply the registered library paths to the passed impl object - * @return the hash code for the current version of the registered paths + * Apply the registered library paths to the passed AssetManager. If may create a new + * AssetManager if any changes are needed and it isn't allowed to reuse the old one. + * + * @return new AssetManager and the hash code for the current version of the registered paths */ - public int updateResourceImplWithRegisteredLibs(@NonNull ResourcesImpl impl) { + public @NonNull Pair<AssetManager, Integer> updateResourceImplAssetsWithRegisteredLibs( + @NonNull AssetManager assets, boolean reuseAssets) { if (!Flags.registerResourcePaths()) { - return 0; + return new Pair<>(assets, 0); } - final var collector = new PathCollector(null); - final int size = mSharedLibAssetsMap.size(); - for (int i = 0; i < size; i++) { - final var libraryKey = mSharedLibAssetsMap.valueAt(i).getResourcesKey(); - collector.appendKey(libraryKey); + final int size; + final PathCollector collector; + + synchronized (mLock) { + size = mSharedLibAssetsMap.size(); + if (assets == AssetManager.getSystem()) { + return new Pair<>(assets, size); + } + collector = new PathCollector(resourcesKeyFromAssets(assets)); + for (int i = 0; i < size; i++) { + final var libraryKey = mSharedLibAssetsMap.valueAt(i).getResourcesKey(); + collector.appendKey(libraryKey); + } + } + if (collector.isSameAsOriginal()) { + return new Pair<>(assets, size); + } + if (reuseAssets) { + assets.addPresetApkKeys(extractApkKeys(collector.collectedKey())); + return new Pair<>(assets, size); + } + final var newAssetsBuilder = new AssetManager.Builder(); + for (final var asset : assets.getApkAssets()) { + if (!asset.isForLoader()) { + newAssetsBuilder.addApkAssets(asset); + } } - impl.getAssets().addPresetApkKeys(extractApkKeys(collector.collectedKey())); - return size; + for (final var key : extractApkKeys(collector.collectedKey())) { + try { + final var asset = loadApkAssets(key); + newAssetsBuilder.addApkAssets(asset); + } catch (IOException e) { + Log.e(TAG, "Couldn't load assets for key " + key, e); + } + } + assets.getLoaders().forEach(newAssetsBuilder::addLoader); + return new Pair<>(newAssetsBuilder.build(), size); } public static class ApkKey { @@ -624,6 +656,23 @@ public class ResourcesManager { return apkKeys; } + private ResourcesKey resourcesKeyFromAssets(@NonNull AssetManager assets) { + final var libs = new ArrayList<String>(); + final var overlays = new ArrayList<String>(); + for (final ApkAssets asset : assets.getApkAssets()) { + if (asset.isSystem() || asset.isForLoader()) { + continue; + } + if (asset.isOverlay()) { + overlays.add(asset.getAssetPath()); + } else if (asset.isSharedLib()) { + libs.add(asset.getAssetPath()); + } + } + return new ResourcesKey(null, null, overlays.toArray(new String[0]), + libs.toArray(new String[0]), 0, null, null); + } + /** * Creates an AssetManager from the paths within the ResourcesKey. * @@ -752,7 +801,7 @@ public class ResourcesManager { final Configuration config = generateConfig(key); final DisplayMetrics displayMetrics = getDisplayMetrics(generateDisplayId(key), daj); - final ResourcesImpl impl = new ResourcesImpl(assets, displayMetrics, config, daj); + final ResourcesImpl impl = new ResourcesImpl(assets, displayMetrics, config, daj, true); if (DEBUG) { Slog.d(TAG, "- creating impl=" + impl + " with key: " + key); @@ -1137,7 +1186,6 @@ public class ResourcesManager { synchronized (mLock) { if (DEBUG) { Throwable here = new Throwable(); - here.fillInStackTrace(); Slog.w(TAG, "!! Create resources for key=" + key, here); } @@ -1158,7 +1206,6 @@ public class ResourcesManager { synchronized (mLock) { if (DEBUG) { Throwable here = new Throwable(); - here.fillInStackTrace(); Slog.w(TAG, "!! Get resources for activity=" + activityToken + " key=" + key, here); } @@ -1302,7 +1349,6 @@ public class ResourcesManager { if (DEBUG) { Throwable here = new Throwable(); - here.fillInStackTrace(); Slog.d(TAG, "updating resources override for activity=" + activityToken + " from oldConfig=" + Configuration.resourceQualifierString(oldConfig) @@ -1835,31 +1881,32 @@ public class ResourcesManager { for (int i = 0; i < resourcesCount; i++) { final WeakReference<Resources> ref = mAllResourceReferences.get(i); final Resources r = ref != null ? ref.get() : null; - if (r != null) { - final ResourcesKey key = updatedResourceKeys.get(r.getImpl()); - if (key != null) { - final ResourcesImpl impl = findOrCreateResourcesImplForKeyLocked(key); - if (impl == null) { - throw new Resources.NotFoundException("failed to redirect ResourcesImpl"); - } - r.setImpl(impl); - } else { - // ResourcesKey is null which means the ResourcesImpl could belong to a - // Resources created by application through Resources constructor and was not - // managed by ResourcesManager, so the ResourcesImpl needs to be recreated to - // have shared library asset paths appended if there are any. - if (r.getImpl() != null) { - final ResourcesImpl oldImpl = r.getImpl(); - final AssetManager oldAssets = oldImpl.getAssets(); - // ResourcesImpl constructor will help to append shared library asset paths. - if (oldAssets != AssetManager.getSystem() && oldAssets.isUpToDate()) { - final ResourcesImpl newImpl = new ResourcesImpl(oldAssets, - oldImpl.getMetrics(), oldImpl.getConfiguration(), - oldImpl.getDisplayAdjustments()); + if (r == null) { + continue; + } + final ResourcesKey key = updatedResourceKeys.get(r.getImpl()); + if (key != null) { + final ResourcesImpl impl = findOrCreateResourcesImplForKeyLocked(key); + if (impl == null) { + throw new Resources.NotFoundException("failed to redirect ResourcesImpl"); + } + r.setImpl(impl); + } else { + // ResourcesKey is null which means the ResourcesImpl could belong to a + // Resources created by application through Resources constructor and was not + // managed by ResourcesManager, so the ResourcesImpl needs to be recreated to + // have shared library asset paths appended if there are any. + final ResourcesImpl oldImpl = r.getImpl(); + if (oldImpl != null) { + final AssetManager oldAssets = oldImpl.getAssets(); + // ResourcesImpl constructor will help to append shared library asset paths. + if (oldAssets != AssetManager.getSystem()) { + if (oldAssets.isUpToDate()) { + final ResourcesImpl newImpl = new ResourcesImpl(oldImpl); r.setImpl(newImpl); } else { - Slog.w(TAG, "Skip appending shared library asset paths for the " - + "Resource as its assets are not up to date."); + Slog.w(TAG, "Skip appending shared library asset paths for " + + "the Resources as its assets are not up to date."); } } } diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index e451116081fa..ee0c38c60ff1 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -190,6 +190,7 @@ import android.os.IBatteryPropertiesRegistrar; import android.os.IBinder; import android.os.IDumpstate; import android.os.IHardwarePropertiesManager; +import android.os.IHintManager; import android.os.IPowerManager; import android.os.IPowerStatsService; import android.os.IRecoverySystem; @@ -1195,8 +1196,10 @@ public final class SystemServiceRegistry { public SystemHealthManager createService(ContextImpl ctx) throws ServiceNotFoundException { IBinder batteryStats = ServiceManager.getServiceOrThrow(BatteryStats.SERVICE_NAME); IBinder powerStats = ServiceManager.getService(Context.POWER_STATS_SERVICE); + IBinder perfHint = ServiceManager.getService(Context.PERFORMANCE_HINT_SERVICE); return new SystemHealthManager(IBatteryStats.Stub.asInterface(batteryStats), - IPowerStatsService.Stub.asInterface(powerStats)); + IPowerStatsService.Stub.asInterface(powerStats), + IHintManager.Stub.asInterface(perfHint)); }}); registerService(Context.CONTEXTHUB_SERVICE, ContextHubManager.class, diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING index 637187e01160..5ed1f4e35533 100644 --- a/core/java/android/app/TEST_MAPPING +++ b/core/java/android/app/TEST_MAPPING @@ -177,10 +177,6 @@ { "file_patterns": ["(/|^)AppOpsManager.java"], "name": "CtsAppOpsTestCases" - }, - { - "file_patterns": ["(/|^)BroadcastStickyCache.java"], - "name": "BroadcastUnitTests" } ] } diff --git a/core/java/android/app/ZenBypassingApp.java b/core/java/android/app/ZenBypassingApp.java new file mode 100644 index 000000000000..89bcfa2d2e7d --- /dev/null +++ b/core/java/android/app/ZenBypassingApp.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; + +import java.util.Objects; + +/** + * @hide + */ +public final class ZenBypassingApp implements Parcelable { + + @NonNull private String mPkg; + private boolean mAllChannelsBypass; + + + public ZenBypassingApp(@NonNull String pkg, boolean allChannelsBypass) { + mPkg = pkg; + mAllChannelsBypass = allChannelsBypass; + } + + public ZenBypassingApp(Parcel source) { + mPkg = source.readString(); + mAllChannelsBypass = source.readBoolean(); + } + + @NonNull + public String getPkg() { + return mPkg; + } + + public boolean doAllChannelsBypass() { + return mAllChannelsBypass; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString(mPkg); + dest.writeBoolean(mAllChannelsBypass); + } + + public static final @android.annotation.NonNull Parcelable.Creator<ZenBypassingApp> CREATOR + = new Parcelable.Creator<ZenBypassingApp>() { + @Override + public ZenBypassingApp createFromParcel(Parcel source) { + return new ZenBypassingApp(source); + } + @Override + public ZenBypassingApp[] newArray(int size) { + return new ZenBypassingApp[size]; + } + }; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ZenBypassingApp)) return false; + ZenBypassingApp that = (ZenBypassingApp) o; + return mAllChannelsBypass == that.mAllChannelsBypass && Objects.equals(mPkg, + that.mPkg); + } + + @Override + public int hashCode() { + return Objects.hash(mPkg, mAllChannelsBypass); + } + + @Override + public String toString() { + return "ZenBypassingApp{" + + "mPkg='" + mPkg + '\'' + + ", mAllChannelsBypass=" + mAllChannelsBypass + + '}'; + } +} diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 707ba347faab..4e68b5af72d2 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -58,6 +58,7 @@ import static android.app.admin.flags.Flags.FLAG_DEVICE_THEFT_API_ENABLED; import static android.app.admin.flags.Flags.FLAG_REMOVE_MANAGED_PROFILE_ENABLED; import static android.app.admin.flags.Flags.onboardingBugreportV2Enabled; import static android.app.admin.flags.Flags.onboardingConsentlessBugreports; +import static android.app.admin.flags.Flags.FLAG_SECONDARY_LOCKSCREEN_API_ENABLED; import static android.content.Intent.LOCAL_FLAG_FROM_SYSTEM; import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1; import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE; @@ -8919,12 +8920,9 @@ public class DevicePolicyManager { /** * Called by a device owner, a profile owner for the primary user or a profile * owner of an organization-owned managed profile to turn auto time on and off. - * Callers are recommended to use {@link UserManager#DISALLOW_CONFIG_DATE_TIME} - * to prevent the user from changing this setting. * <p> - * If user restriction {@link UserManager#DISALLOW_CONFIG_DATE_TIME} is used, - * no user will be able set the date and time. Instead, the network date - * and time will be used. + * Callers are recommended to use {@link UserManager#DISALLOW_CONFIG_DATE_TIME} to prevent the + * user from changing this setting, that way no user will be able set the date and time zone. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the * caller is not a device admin. @@ -8937,7 +8935,13 @@ public class DevicePolicyManager { throwIfParentInstance("setAutoTimeEnabled"); if (mService != null) { try { - mService.setAutoTimeEnabled(admin, mContext.getPackageName(), enabled); + if (Flags.setAutoTimeEnabledCoexistence()) { + mService.setAutoTimePolicy(mContext.getPackageName(), + enabled ? DevicePolicyManager.AUTO_TIME_ENABLED + : DevicePolicyManager.AUTO_TIME_DISABLED); + } else { + mService.setAutoTimeEnabled(admin, mContext.getPackageName(), enabled); + } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -8967,14 +8971,102 @@ public class DevicePolicyManager { } /** + * Specifies that the auto time state is not controlled by device policy. + * + * @see #setAutoTimePolicy(ComponentName, int) + */ + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ENABLED_COEXISTENCE) + public static final int AUTO_TIME_NOT_CONTROLLED_BY_POLICY = 0; + + /** + * Specifies the "disabled" auto time state. + * + * @see #setAutoTimePolicy(ComponentName, int) + */ + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ENABLED_COEXISTENCE) + public static final int AUTO_TIME_DISABLED = 1; + + /** + * Specifies the "enabled" auto time state. + * + * @see #setAutoTimePolicy(ComponentName, int) + */ + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ENABLED_COEXISTENCE) + public static final int AUTO_TIME_ENABLED = 2; + + /** + * Flags supplied to {@link #setAutoTimePolicy}(ComponentName, int)}. + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "AUTO_TIME_" }, value = { + AUTO_TIME_NOT_CONTROLLED_BY_POLICY, + AUTO_TIME_DISABLED, + AUTO_TIME_ENABLED + }) + public @interface AutoTimePolicy {} + + /** + * Called by a device owner, a profile owner for the primary user or a profile owner of an + * organization-owned managed profile to turn auto time on and off i.e. Whether time should be + * obtained automatically from the network or not. + * <p> + * Callers are recommended to use {@link UserManager#DISALLOW_CONFIG_DATE_TIME} to prevent the + * user from changing this setting, that way no user will be able set the date and time zone. + * + * @param policy The desired state among {@link #AUTO_TIME_ENABLED} to enable, + * {@link #AUTO_TIME_DISABLED} to disable and + * {@link #AUTO_TIME_NOT_CONTROLLED_BY_POLICY} to unset the policy. + * @throws SecurityException if caller is not a device owner, a profile owner for the + * primary user, or a profile owner of an organization-owned managed profile, or if the caller + * does not hold the required permission. + */ + @SupportsCoexistence + @RequiresPermission(value = SET_TIME, conditional = true) + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ENABLED_COEXISTENCE) + public void setAutoTimePolicy(@AutoTimePolicy int policy) { + throwIfParentInstance("setAutoTimePolicy"); + if (mService != null) { + try { + mService.setAutoTimePolicy(mContext.getPackageName(), policy); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Returns current auto time policy's state. + * + * @return One of {@link #AUTO_TIME_ENABLED} if enabled, {@link #AUTO_TIME_DISABLED} if disabled + * and {@link #AUTO_TIME_NOT_CONTROLLED_BY_POLICY} if it's not controlled by + * policy. + * @throws SecurityException if caller is not a device owner, a profile owner for the + * primary user, or a profile owner of an organization-owned managed profile, or if the caller + * does not hold the required permission. + */ + @SupportsCoexistence + @RequiresPermission(anyOf = {SET_TIME, QUERY_ADMIN_POLICY}, conditional = true) + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ENABLED_COEXISTENCE) + public @AutoTimePolicy int getAutoTimePolicy() { + throwIfParentInstance("getAutoTimePolicy"); + if (mService != null) { + try { + return mService.getAutoTimePolicy(mContext.getPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + return DevicePolicyManager.AUTO_TIME_NOT_CONTROLLED_BY_POLICY; + } + + /** * Called by a device owner, a profile owner for the primary user or a profile * owner of an organization-owned managed profile to turn auto time zone on and off. - * Callers are recommended to use {@link UserManager#DISALLOW_CONFIG_DATE_TIME} - * to prevent the user from changing this setting. * <p> - * If user restriction {@link UserManager#DISALLOW_CONFIG_DATE_TIME} is used, - * no user will be able set the date and time zone. Instead, the network date - * and time zone will be used. + * Callers are recommended to use {@link UserManager#DISALLOW_CONFIG_DATE_TIME} to prevent the + * user from changing this setting, that way no user will be able set the date and time zone. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with or Null if the * caller is not a device admin. @@ -8982,13 +9074,17 @@ public class DevicePolicyManager { * @throws SecurityException if caller is not a device owner, a profile owner for the * primary user, or a profile owner of an organization-owned managed profile. */ - @SupportsCoexistence @RequiresPermission(value = SET_TIME_ZONE, conditional = true) public void setAutoTimeZoneEnabled(@Nullable ComponentName admin, boolean enabled) { throwIfParentInstance("setAutoTimeZone"); if (mService != null) { try { - mService.setAutoTimeZoneEnabled(admin, mContext.getPackageName(), enabled); + if (Flags.setAutoTimeZoneEnabledCoexistence()) { + mService.setAutoTimeZonePolicy(mContext.getPackageName(), + enabled ? AUTO_TIME_ZONE_ENABLED : AUTO_TIME_ZONE_DISABLED ); + } else { + mService.setAutoTimeZoneEnabled(admin, mContext.getPackageName(), enabled); + } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -9018,6 +9114,96 @@ public class DevicePolicyManager { } /** + * Specifies that the auto time zone state is not controlled by device policy. + * + * @see #setAutoTimeZonePolicy(int) + */ + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ZONE_ENABLED_COEXISTENCE) + public static final int AUTO_TIME_ZONE_NOT_CONTROLLED_BY_POLICY = 0; + + /** + * Specifies the "disabled" auto time zone state. + * + * @see #setAutoTimeZonePolicy(int) + */ + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ZONE_ENABLED_COEXISTENCE) + public static final int AUTO_TIME_ZONE_DISABLED = 1; + + /** + * Specifies the "enabled" auto time zone state. + * + * @see #setAutoTimeZonePolicy(int) + */ + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ZONE_ENABLED_COEXISTENCE) + public static final int AUTO_TIME_ZONE_ENABLED = 2; + + /** + * Flags supplied to {@link #setAutoTimeZonePolicy}(int)}. + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "AUTO_TIME_ZONE_" }, value = { + AUTO_TIME_ZONE_NOT_CONTROLLED_BY_POLICY, + AUTO_TIME_ZONE_DISABLED, + AUTO_TIME_ZONE_ENABLED + }) + public @interface AutoTimeZonePolicy {} + + /** + * Called by a device owner, a profile owner for the primary user or a profile owner of an + * organization-owned managed profile to turn auto time zone on and off. + * <p> + * Callers are recommended to use {@link UserManager#DISALLOW_CONFIG_DATE_TIME} to prevent the + * user from changing this setting, that way no user will be able set the date and time zone. + * + * @param policy The desired state among {@link #AUTO_TIME_ZONE_ENABLED} to enable it, + * {@link #AUTO_TIME_ZONE_DISABLED} to disable it or + * {@link #AUTO_TIME_ZONE_NOT_CONTROLLED_BY_POLICY} to unset the policy. + * @throws SecurityException if caller is not a device owner, a profile owner for the primary + * user, or a profile owner of an organization-owned managed profile, or if the caller does not + * hold the required permission. + */ + @SupportsCoexistence + @RequiresPermission(value = SET_TIME_ZONE, conditional = true) + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ZONE_ENABLED_COEXISTENCE) + public void setAutoTimeZonePolicy(@AutoTimeZonePolicy int policy) { + throwIfParentInstance("setAutoTimeZonePolicy"); + if (mService != null) { + try { + mService.setAutoTimeZonePolicy(mContext.getPackageName(), policy); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Returns auto time zone policy's current state. + * + * @return One of {@link #AUTO_TIME_ZONE_ENABLED} if enabled, {@link #AUTO_TIME_ZONE_DISABLED} + * if disabled and {@link #AUTO_TIME_ZONE_NOT_CONTROLLED_BY_POLICY} if the state is not + * controlled by policy. + * @throws SecurityException if caller is not a device owner, a profile owner for the + * primary user, or a profile owner of an organization-owned managed profile, or if the caller + * does not hold the required permission. + */ + @SupportsCoexistence + @RequiresPermission(anyOf = {SET_TIME_ZONE, QUERY_ADMIN_POLICY}, conditional = true) + @FlaggedApi(Flags.FLAG_SET_AUTO_TIME_ZONE_ENABLED_COEXISTENCE) + public @AutoTimeZonePolicy int getAutoTimeZonePolicy() { + throwIfParentInstance("getAutoTimeZonePolicy"); + if (mService != null) { + try { + return mService.getAutoTimeZonePolicy(mContext.getPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + return DevicePolicyManager.AUTO_TIME_ZONE_NOT_CONTROLLED_BY_POLICY; + } + + /** * TODO (b/137101239): remove this method in follow-up CL * since it's only used for split system user. * Called by a device owner to set whether all users created on the device should be ephemeral. @@ -12010,6 +12196,33 @@ public class DevicePolicyManager { } /** + * Adds a user restriction globally, specified by the {@code key}. + * + * <p>Called by a system service only, meaning that the caller's UID must be equal to + * {@link Process#SYSTEM_UID}. + * + * @param systemEntity The service entity that adds the restriction. A user restriction set by + * a service entity can only be cleared by the same entity. This can be + * just the calling package name, or any string of the caller's choice + * can be used. + * @param key The key of the restriction. + * @throws SecurityException if the caller is not a system service. + * + * @hide + */ + public void addUserRestrictionGlobally(@NonNull String systemEntity, + @NonNull @UserManager.UserRestrictionKey String key) { + if (mService != null) { + try { + mService.setUserRestrictionGloballyFromSystem(systemEntity, key, + /* enable= */ true); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** * Called by a profile owner, device owner or a holder of any permission that is associated with * a user restriction to clear a user restriction specified by the key. * <p> @@ -12095,6 +12308,33 @@ public class DevicePolicyManager { } /** + * Clears a user restriction globally, specified by the {@code key}. + * + * <p>Called by a system service only, meaning that the caller's UID must be equal to + * {@link Process#SYSTEM_UID}. + * + * @param systemEntity The system entity that clears the restriction. A user restriction + * set by a system entity can only be cleared by the same entity. This + * can be just the calling package name, or any string of the caller's + * choice can be used. + * @param key The key of the restriction. + * @throws SecurityException if the caller is not a system service. + * + * @hide + */ + public void clearUserRestrictionGlobally(@NonNull String systemEntity, + @NonNull @UserManager.UserRestrictionKey String key) { + if (mService != null) { + try { + mService.setUserRestrictionGloballyFromSystem(systemEntity, key, + /* enable= */ false); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** * Called by an admin to get user restrictions set by themselves with * {@link #addUserRestriction(ComponentName, String)}. * <p> @@ -12551,28 +12791,43 @@ public class DevicePolicyManager { * @param enabled Whether or not the lockscreen needs to be shown. * @throws SecurityException if {@code admin} is not a device or profile owner. * @see #isSecondaryLockscreenEnabled + * @deprecated Use {@link #setSecondaryLockscreenEnabled(boolean,PersistableBundle)} instead. * @hide - **/ + */ + @Deprecated @SystemApi + @FlaggedApi(FLAG_SECONDARY_LOCKSCREEN_API_ENABLED) public void setSecondaryLockscreenEnabled(@NonNull ComponentName admin, boolean enabled) { - setSecondaryLockscreenEnabled(admin, enabled, null); + throwIfParentInstance("setSecondaryLockscreenEnabled"); + if (mService != null) { + try { + mService.setSecondaryLockscreenEnabled(admin, enabled, null); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } /** * Called by the system supervision app to set whether a secondary lockscreen needs to be shown. * - * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the - * caller is not a device admin. + * <p>The secondary lockscreen will by displayed after the primary keyguard security screen + * requirements are met. + * + * <p>This API, and associated APIs, can only be called by the default supervision app. + * * @param enabled Whether or not the lockscreen needs to be shown. * @param options A {@link PersistableBundle} to supply options to the lock screen. * @hide */ - public void setSecondaryLockscreenEnabled(@Nullable ComponentName admin, boolean enabled, + @SystemApi + @FlaggedApi(FLAG_SECONDARY_LOCKSCREEN_API_ENABLED) + public void setSecondaryLockscreenEnabled(boolean enabled, @Nullable PersistableBundle options) { throwIfParentInstance("setSecondaryLockscreenEnabled"); if (mService != null) { try { - mService.setSecondaryLockscreenEnabled(admin, enabled, options); + mService.setSecondaryLockscreenEnabled(null, enabled, options); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index ba97edb98549..fa984af68016 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -257,6 +257,7 @@ interface IDevicePolicyManager { void setUserRestriction(in ComponentName who, in String callerPackage, in String key, boolean enable, boolean parent); void setUserRestrictionForUser(in String systemEntity, in String key, boolean enable, int targetUser); void setUserRestrictionGlobally(in String callerPackage, in String key); + void setUserRestrictionGloballyFromSystem(in String systemEntity, in String key, boolean enable); Bundle getUserRestrictions(in ComponentName who, in String callerPackage, boolean parent); Bundle getUserRestrictionsGlobally(in String callerPackage); @@ -375,9 +376,15 @@ interface IDevicePolicyManager { void setAutoTimeEnabled(in ComponentName who, String callerPackageName, boolean enabled); boolean getAutoTimeEnabled(in ComponentName who, String callerPackageName); + void setAutoTimePolicy(String callerPackageName, int policy); + int getAutoTimePolicy(String callerPackageName); + void setAutoTimeZoneEnabled(in ComponentName who, String callerPackageName, boolean enabled); boolean getAutoTimeZoneEnabled(in ComponentName who, String callerPackageName); + void setAutoTimeZonePolicy(String callerPackageName, int policy); + int getAutoTimeZonePolicy(String callerPackageName); + void setForceEphemeralUsers(in ComponentName who, boolean forceEpehemeralUsers); boolean getForceEphemeralUsers(in ComponentName who); diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig index 5f868befa368..404471e266d2 100644 --- a/core/java/android/app/admin/flags/flags.aconfig +++ b/core/java/android/app/admin/flags/flags.aconfig @@ -381,3 +381,11 @@ flag { description: "Split up existing create and provision managed profile API." bug: "375382324" } + +flag { + name: "secondary_lockscreen_api_enabled" + is_exported: true + namespace: "enterprise" + description: "Add new API for secondary lockscreen" + bug: "336297680" +} diff --git a/core/java/android/app/jank/JankDataProcessor.java b/core/java/android/app/jank/JankDataProcessor.java index 3783a5f9e829..7525d0402ee4 100644 --- a/core/java/android/app/jank/JankDataProcessor.java +++ b/core/java/android/app/jank/JankDataProcessor.java @@ -70,8 +70,8 @@ public class JankDataProcessor { for (int j = 0; j < mPendingStates.size(); j++) { StateData pendingState = mPendingStates.get(j); // This state was active during the frame - if (frame.frameVsyncId >= pendingState.mVsyncIdStart - && frame.frameVsyncId <= pendingState.mVsyncIdEnd) { + if (frame.getVsyncId() >= pendingState.mVsyncIdStart + && frame.getVsyncId() <= pendingState.mVsyncIdEnd) { recordFrameCount(frame, pendingState, activityName, appUid); pendingState.mProcessed = true; @@ -131,14 +131,14 @@ public class JankDataProcessor { mPendingJankStats.put(stateData.mStateDataKey, jankStats); } // This state has already been accounted for - if (jankStats.processedVsyncId == frameData.frameVsyncId) return; + if (jankStats.processedVsyncId == frameData.getVsyncId()) return; jankStats.mTotalFrames += 1; - if (frameData.jankType == JankData.JANK_APPLICATION) { + if ((frameData.getJankType() & JankData.JANK_APPLICATION) != 0) { jankStats.mJankyFrames += 1; } - jankStats.recordFrameOverrun(frameData.actualAppFrameTimeNs); - jankStats.processedVsyncId = frameData.frameVsyncId; + jankStats.recordFrameOverrun(frameData.getActualAppFrameTimeNanos()); + jankStats.processedVsyncId = frameData.getVsyncId(); } diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig index 6934e9883840..a487da297739 100644 --- a/core/java/android/app/notification.aconfig +++ b/core/java/android/app/notification.aconfig @@ -268,3 +268,10 @@ flag { description: "Adds UI for NAS classification of notifications" bug: "367996732" } + +flag { + name: "no_sbnholder" + namespace: "systemui" + description: "removes sbnholder from NLS" + bug: "362981561" +} diff --git a/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig b/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig index 8b6441ae5a7c..74a96c864167 100644 --- a/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig +++ b/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig @@ -8,3 +8,10 @@ flag { description: "Make methods on OnDeviceIntelligenceManager available for local inference." bug: "304755128" } +flag { + name: "enable_on_device_intelligence_module" + is_exported: true + namespace: "ondeviceintelligence" + description: "Enable migration to mainline module and related changes." + bug: "376427781" +}
\ No newline at end of file diff --git a/core/java/android/app/wallpaper/WallpaperDescription.java b/core/java/android/app/wallpaper/WallpaperDescription.java index 8ffda7242b37..4a142bb5287a 100644 --- a/core/java/android/app/wallpaper/WallpaperDescription.java +++ b/core/java/android/app/wallpaper/WallpaperDescription.java @@ -113,7 +113,7 @@ public final class WallpaperDescription implements Parcelable { /** @return the description for this wallpaper */ @NonNull public List<CharSequence> getDescription() { - return new ArrayList<>(); + return mDescription; } /** @return the {@link Uri} for the action associated with the wallpaper, or {@code null} if not diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java index 964a8be0f153..a81629445263 100644 --- a/core/java/android/content/BroadcastReceiver.java +++ b/core/java/android/content/BroadcastReceiver.java @@ -356,7 +356,6 @@ public abstract class BroadcastReceiver { } RuntimeException e = new RuntimeException( "BroadcastReceiver trying to return result during a non-ordered broadcast"); - e.fillInStackTrace(); Log.e("BroadcastReceiver", e.getMessage(), e); } } @@ -768,7 +767,6 @@ public abstract class BroadcastReceiver { } RuntimeException e = new RuntimeException( "BroadcastReceiver trying to return result during a non-ordered broadcast"); - e.fillInStackTrace(); Log.e("BroadcastReceiver", e.getMessage(), e); } } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index b776b59f11c2..88533049f970 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -87,7 +87,6 @@ import android.util.AttributeSet; import android.util.Log; import android.util.proto.ProtoOutputStream; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.XmlUtils; import com.android.modules.expresslog.Counter; @@ -12304,7 +12303,6 @@ public class Intent implements Parcelable, Cloneable { } /** @hide */ - @VisibleForTesting public Set<NestedIntentKey> getExtraIntentKeys() { return mCreatorTokenInfo == null ? null : mCreatorTokenInfo.mNestedIntentKeys; } diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig index 9ba5a352358b..e181ae8ef3c7 100644 --- a/core/java/android/content/pm/flags.aconfig +++ b/core/java/android/content/pm/flags.aconfig @@ -366,3 +366,13 @@ flag { description: "Block app installations that specify an incompatible minor SDK version" bug: "377474232" } + +flag { + name: "app_compat_option_16kb" + is_exported: true + namespace: "devoptions_settings" + description: "Feature flag to enable page size app compat mode from manifest, package manager and settings level." + bug: "371049373" + is_fixed_read_only: true +} + diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig index 3d89ce12dec4..813208d7ff38 100644 --- a/core/java/android/content/pm/multiuser.aconfig +++ b/core/java/android/content/pm/multiuser.aconfig @@ -330,6 +330,17 @@ flag { is_fixed_read_only: true } +flag { + name: "cache_user_info_read_only" + namespace: "multiuser" + description: "Cache UserInfo to avoid unnecessary binder calls" + bug: "161915546" + metadata { + purpose: PURPOSE_BUGFIX + } + is_fixed_read_only: true +} + # This flag guards the private space feature and all its implementations excluding the APIs. APIs are guarded by android.os.Flags.allow_private_profile. flag { name: "enable_private_space_features" diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java index 68b5d782bfbf..908999b64961 100644 --- a/core/java/android/content/res/ApkAssets.java +++ b/core/java/android/content/res/ApkAssets.java @@ -124,11 +124,13 @@ public final class ApkAssets { @Nullable @GuardedBy("this") - private final StringBlock mStringBlock; // null or closed if mNativePtr = 0. + private StringBlock mStringBlock; // null or closed if mNativePtr = 0. @PropertyFlags private final int mFlags; + private final boolean mIsOverlay; + @Nullable private final AssetsProvider mAssets; @@ -302,40 +304,43 @@ public final class ApkAssets { private ApkAssets(@FormatType int format, @NonNull String path, @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException { + this(format, flags, assets); Objects.requireNonNull(path, "path"); - mFlags = flags; mNativePtr = nativeLoad(format, path, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); - mAssets = assets; } private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException { + this(format, flags, assets); Objects.requireNonNull(fd, "fd"); Objects.requireNonNull(friendlyName, "friendlyName"); - mFlags = flags; mNativePtr = nativeLoadFd(format, fd, friendlyName, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); - mAssets = assets; } private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException { + this(format, flags, assets); Objects.requireNonNull(fd, "fd"); Objects.requireNonNull(friendlyName, "friendlyName"); - mFlags = flags; mNativePtr = nativeLoadFdOffsets(format, fd, friendlyName, offset, length, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); - mAssets = assets; } private ApkAssets(@PropertyFlags int flags, @Nullable AssetsProvider assets) { - mFlags = flags; + this(FORMAT_APK, flags, assets); mNativePtr = nativeLoadEmpty(flags, assets); mStringBlock = null; + } + + private ApkAssets(@FormatType int format, @PropertyFlags int flags, + @Nullable AssetsProvider assets) { + mFlags = flags; mAssets = assets; + mIsOverlay = format == FORMAT_IDMAP; } @UnsupportedAppUsage @@ -425,6 +430,18 @@ public final class ApkAssets { } } + public boolean isSystem() { + return (mFlags & PROPERTY_SYSTEM) != 0; + } + + public boolean isSharedLib() { + return (mFlags & PROPERTY_DYNAMIC) != 0; + } + + public boolean isOverlay() { + return mIsOverlay; + } + @Override public String toString() { return "ApkAssets{path=" + getDebugName() + "}"; diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 6fd4d0141977..4551bd52c960 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -973,9 +973,9 @@ public final class AssetManager implements AutoCloseable { * Open an asset using ACCESS_STREAMING mode. This provides access to * files that have been bundled with an application as assets -- that is, * files placed in to the "assets" directory. - * + * * @param fileName The name of the asset to open. This name can be hierarchical. - * + * * @see #open(String, int) * @see #list */ @@ -988,10 +988,10 @@ public final class AssetManager implements AutoCloseable { * read its contents. This provides access to files that have been bundled * with an application as assets -- that is, files placed in to the * "assets" directory. - * + * * @param fileName The name of the asset to open. This name can be hierarchical. * @param accessMode Desired access mode for retrieving the data. - * + * * @see #ACCESS_UNKNOWN * @see #ACCESS_STREAMING * @see #ACCESS_RANDOM @@ -1037,14 +1037,14 @@ public final class AssetManager implements AutoCloseable { /** * Return a String array of all the assets at the given path. - * + * * @param path A relative path within the assets, i.e., "docs/home.html". - * + * * @return String[] Array of strings, one for each asset. These file * names are relative to 'path'. You can open the file by * concatenating 'path' and a name in the returned string (via * File) and passing that to open(). - * + * * @see #open */ public @Nullable String[] list(@NonNull String path) throws IOException { @@ -1167,20 +1167,20 @@ public final class AssetManager implements AutoCloseable { return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]); } } - + /** * Retrieve a parser for a compiled XML file. - * + * * @param fileName The name of the file to retrieve. */ public @NonNull XmlResourceParser openXmlResourceParser(@NonNull String fileName) throws IOException { return openXmlResourceParser(0, fileName); } - + /** * Retrieve a parser for a compiled XML file. - * + * * @param cookie Identifier of the package to be opened. * @param fileName The name of the file to retrieve. */ @@ -1200,7 +1200,7 @@ public final class AssetManager implements AutoCloseable { /** * Retrieve a non-asset as a compiled XML file. Not for use by applications. - * + * * @param fileName The name of the file to retrieve. * @hide */ @@ -1211,7 +1211,7 @@ public final class AssetManager implements AutoCloseable { /** * Retrieve a non-asset as a compiled XML file. Not for use by * applications. - * + * * @param cookie Identifier of the package to be opened. * @param fileName Name of the asset to retrieve. * @hide @@ -1675,7 +1675,6 @@ public final class AssetManager implements AutoCloseable { mRefStacks = new HashMap<>(); } RuntimeException ex = new RuntimeException(); - ex.fillInStackTrace(); mRefStacks.put(id, ex); } mNumRefs++; diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index e6b93427f413..bcaceb24d767 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -203,9 +203,25 @@ public class ResourcesImpl { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics, @Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments) { - mAssets = assets; - mAppliedSharedLibsHash = - ResourcesManager.getInstance().updateResourceImplWithRegisteredLibs(this); + // Don't reuse assets by default as we have no control over whether they're already + // inside some other ResourcesImpl. + this(assets, metrics, config, displayAdjustments, false); + } + + public ResourcesImpl(@NonNull ResourcesImpl orig) { + // We know for sure that the other assets are in use, so can't reuse the object here. + this(orig.getAssets(), orig.getMetrics(), orig.getConfiguration(), + orig.getDisplayAdjustments(), false); + } + + public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics, + @Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments, + boolean reuseAssets) { + final var assetsAndHash = + ResourcesManager.getInstance().updateResourceImplAssetsWithRegisteredLibs(assets, + reuseAssets); + mAssets = assetsAndHash.first; + mAppliedSharedLibsHash = assetsAndHash.second; mMetrics.setToDefaults(); mDisplayAdjustments = displayAdjustments; mConfiguration.setToDefaults(); diff --git a/core/java/android/credentials/flags.aconfig b/core/java/android/credentials/flags.aconfig index d2435757756c..6c35d106bfb7 100644 --- a/core/java/android/credentials/flags.aconfig +++ b/core/java/android/credentials/flags.aconfig @@ -3,6 +3,16 @@ container: "system" flag { namespace: "credential_manager" + name: "ttl_fix_enabled" + description: "Enable fix for transaction too large issue" + bug: "371052524" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + namespace: "credential_manager" name: "settings_activity_enabled" is_exported: true description: "Enable the Credential Manager Settings Activity APIs" diff --git a/core/java/android/hardware/DisplayLuts.java b/core/java/android/hardware/DisplayLuts.java index b162ad6e2d15..6343ba19f569 100644 --- a/core/java/android/hardware/DisplayLuts.java +++ b/core/java/android/hardware/DisplayLuts.java @@ -16,116 +16,294 @@ package android.hardware; +import android.annotation.FlaggedApi; import android.annotation.NonNull; +import android.hardware.flags.Flags; import android.util.IntArray; import java.util.ArrayList; -import java.util.List; /** - * @hide + * DisplayLuts provides the developers to apply Lookup Tables (Luts) to a + * {@link android.view.SurfaceControl}. Luts provides ways to control tonemapping + * for specific content. + * + * The general flow is as follows: + * <p> + * <img src="{@docRoot}reference/android/images/graphics/DisplayLuts.png" /> + * <figcaption style="text-align: center;">DisplayLuts flow</figcaption> + * </p> + * + * @see LutProperties */ +@FlaggedApi(Flags.FLAG_LUTS_API) public final class DisplayLuts { + private ArrayList<Entry> mEntries; private IntArray mOffsets; private int mTotalLength; - private List<float[]> mLutBuffers; - private IntArray mLutDimensions; - private IntArray mLutSizes; - private IntArray mLutSamplingKeys; - private static final int LUT_LENGTH_LIMIT = 100000; - + /** + * Create a {@link DisplayLuts} instance. + */ + @FlaggedApi(Flags.FLAG_LUTS_API) public DisplayLuts() { + mEntries = new ArrayList<>(); mOffsets = new IntArray(); mTotalLength = 0; - - mLutBuffers = new ArrayList<>(); - mLutDimensions = new IntArray(); - mLutSizes = new IntArray(); - mLutSamplingKeys = new IntArray(); } - /** - * Add the lut to be applied. - * - * @param buffer - * @param dimension either 1D or 3D - * @param size - * @param samplingKey - */ - public void addLut(@NonNull float[] buffer, @LutProperties.Dimension int dimension, - int size, @LutProperties.SamplingKey int samplingKey) { + @FlaggedApi(Flags.FLAG_LUTS_API) + public static class Entry { + private float[] mBuffer; + private @LutProperties.Dimension int mDimension; + private int mSize; + private @LutProperties.SamplingKey int mSamplingKey; + + private static final int LUT_LENGTH_LIMIT = 100000; + + /** + * Create a Lut entry. + * + * <p> + * Noted that 1D Lut(s) are treated as gain curves. + * For 3D Lut(s), 3D Lut(s) are used for direct color manipulations. + * The values of 3D Lut(s) data should be normalized to the range {@code 0.0} + * to {@code 1.0}, inclusive. And 3D Lut(s) data is organized in the order of + * R, G, B channels. + * + * @param buffer The raw lut data + * @param dimension Either 1D or 3D + * @param samplingKey The sampling kay used for the Lut + */ + @FlaggedApi(Flags.FLAG_LUTS_API) + public Entry(@NonNull float[] buffer, + @LutProperties.Dimension int dimension, + @LutProperties.SamplingKey int samplingKey) { + if (buffer == null || buffer.length < 1) { + throw new IllegalArgumentException("The buffer cannot be empty!"); + } + + if (buffer.length >= LUT_LENGTH_LIMIT) { + throw new IllegalArgumentException("The lut length is too big to handle!"); + } + + if (dimension != LutProperties.ONE_DIMENSION + && dimension != LutProperties.THREE_DIMENSION) { + throw new IllegalArgumentException("The dimension should be either 1D or 3D!"); + } + + if (dimension == LutProperties.THREE_DIMENSION) { + if (buffer.length <= 3) { + throw new IllegalArgumentException( + "The 3d lut size of each dimension should be over 1!"); + } + int lengthPerChannel = buffer.length; + if (lengthPerChannel % 3 != 0) { + throw new IllegalArgumentException( + "The lut buffer of 3dlut should have 3 channels!"); + } + lengthPerChannel /= 3; - int lutLength = 0; - if (dimension == LutProperties.ONE_DIMENSION) { - lutLength = size; - } else if (dimension == LutProperties.THREE_DIMENSION) { - lutLength = size * size * size; - } else { - clear(); - throw new IllegalArgumentException("The dimension is either 1D or 3D!"); + double size = Math.cbrt(lengthPerChannel); + if (size == (int) size) { + mSize = (int) size; + } else { + throw new IllegalArgumentException( + "Cannot get the cube root of the 3d lut buffer!"); + } + } else { + mSize = buffer.length; + } + + mBuffer = buffer; + mDimension = dimension; + mSamplingKey = samplingKey; } - if (lutLength >= LUT_LENGTH_LIMIT) { - clear(); - throw new IllegalArgumentException("The lut length is too big to handle!"); + /** + * @return the dimension of the lut entry + */ + @FlaggedApi(Flags.FLAG_LUTS_API) + public int getDimension() { + return mDimension; } - mOffsets.add(mTotalLength); - mTotalLength += lutLength; + /** + * @return the size of the lut for each dimension + * @hide + */ + public int getSize() { + return mSize; + } + + /** + * @return the lut raw data of the lut + */ + @FlaggedApi(Flags.FLAG_LUTS_API) + public @NonNull float[] getBuffer() { + return mBuffer; + } + + /** + * @return the sampling key used by the lut + */ + @FlaggedApi(Flags.FLAG_LUTS_API) + public int getSamplingKey() { + return mSamplingKey; + } + + @Override + public String toString() { + return "Entry{" + + "dimension=" + DisplayLuts.Entry.dimensionToString(getDimension()) + + ", size(each dimension)=" + getSize() + + ", samplingKey=" + samplingKeyToString(getSamplingKey()) + "}"; + } + + private static String dimensionToString(int dimension) { + switch(dimension) { + case LutProperties.ONE_DIMENSION: + return "ONE_DIMENSION"; + case LutProperties.THREE_DIMENSION: + return "THREE_DIMENSION"; + default: + return ""; + } + } + + private static String samplingKeyToString(int key) { + switch(key) { + case LutProperties.SAMPLING_KEY_RGB: + return "SAMPLING_KEY_RGB"; + case LutProperties.SAMPLING_KEY_MAX_RGB: + return "SAMPLING_KEY_MAX_RGB"; + default: + return ""; + } + } + } - mLutBuffers.add(buffer); - mLutDimensions.add(dimension); - mLutSizes.add(size); - mLutSamplingKeys.add(samplingKey); + @Override + public String toString() { + StringBuilder sb = new StringBuilder("DisplayLuts{"); + sb.append("\n"); + for (DisplayLuts.Entry entry: mEntries) { + sb.append(entry.toString()); + sb.append("\n"); + } + sb.append("}"); + return sb.toString(); + } + + private void addEntry(Entry entry) { + mEntries.add(entry); + mOffsets.add(mTotalLength); + mTotalLength += entry.getBuffer().length; } private void clear() { - mTotalLength = 0; mOffsets.clear(); - mLutBuffers.clear(); - mLutDimensions.clear(); - mLutSamplingKeys.clear(); + mTotalLength = 0; + mEntries.clear(); + } + + /** + * Set a Lut to be applied. + * + * <p>Use either this or {@link #set(Entry, Entry)}. The function will + * replace any previously set lut(s).</p> + * + * @param entry Either an 1D Lut or a 3D Lut + */ + @FlaggedApi(Flags.FLAG_LUTS_API) + public void set(@NonNull Entry entry) { + if (entry == null) { + throw new IllegalArgumentException("The entry is null!"); + } + clear(); + addEntry(entry); + } + + /** + * Set Luts in order to be applied. + * + * <p> An 1D Lut and 3D Lut will be applied in order. Use either this or + * {@link #set(Entry)}. The function will replace any previously set lut(s)</p> + * + * @param first An 1D Lut + * @param second A 3D Lut + */ + @FlaggedApi(Flags.FLAG_LUTS_API) + public void set(@NonNull Entry first, @NonNull Entry second) { + if (first == null || second == null) { + throw new IllegalArgumentException("The entry is null!"); + } + if (first.getDimension() != LutProperties.ONE_DIMENSION + || second.getDimension() != LutProperties.THREE_DIMENSION) { + throw new IllegalArgumentException("The entries should be 1D and 3D in order!"); + } + clear(); + addEntry(first); + addEntry(second); } /** - * @return the array of Lut buffers + * @hide + */ + public boolean valid() { + return mEntries.size() > 0; + } + + /** + * @hide */ public float[] getLutBuffers() { float[] buffer = new float[mTotalLength]; - for (int i = 0; i < mLutBuffers.size(); i++) { - float[] lutBuffer = mLutBuffers.get(i); + for (int i = 0; i < mEntries.size(); i++) { + float[] lutBuffer = mEntries.get(i).getBuffer(); System.arraycopy(lutBuffer, 0, buffer, mOffsets.get(i), lutBuffer.length); } return buffer; } /** - * @return the starting point of each lut memory region of the lut buffer + * @hide */ public int[] getOffsets() { return mOffsets.toArray(); } /** - * @return the array of Lut size + * @hide */ public int[] getLutSizes() { - return mLutSizes.toArray(); + int[] sizes = new int[mEntries.size()]; + for (int i = 0; i < mEntries.size(); i++) { + sizes[i] = mEntries.get(i).getSize(); + } + return sizes; } /** - * @return the array of Lut dimension + * @hide */ public int[] getLutDimensions() { - return mLutDimensions.toArray(); + int[] dimensions = new int[mEntries.size()]; + for (int i = 0; i < mEntries.size(); i++) { + dimensions[i] = mEntries.get(i).getDimension(); + } + return dimensions; } /** - * @return the array of sampling key + * @hide */ public int[] getLutSamplingKeys() { - return mLutSamplingKeys.toArray(); + int[] samplingKeys = new int[mEntries.size()]; + for (int i = 0; i < mEntries.size(); i++) { + samplingKeys[i] = mEntries.get(i).getSamplingKey(); + } + return samplingKeys; } } diff --git a/core/java/android/hardware/LutProperties.java b/core/java/android/hardware/LutProperties.java index c9c6d6d08ed2..bf40a415b0f7 100644 --- a/core/java/android/hardware/LutProperties.java +++ b/core/java/android/hardware/LutProperties.java @@ -16,23 +16,31 @@ package android.hardware; +import android.annotation.FlaggedApi; import android.annotation.IntDef; +import android.annotation.NonNull; +import android.hardware.flags.Flags; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * Lut properties class. + * Provides Lut properties of the device. * - * A Lut (Look-Up Table) is a pre-calculated table for color transformation. - * - * @hide + * <p> + * A Lut (Look-Up Table) is a pre-calculated table for color correction. + * Applications may be interested in the Lut properties exposed by + * this class to determine if the Lut(s) they select using + * {@link android.view.SurfaceControl.Transaction#setLuts} are by the HWC. + * </p> */ +@FlaggedApi(Flags.FLAG_LUTS_API) public final class LutProperties { private final @Dimension int mDimension; private final int mSize; private final @SamplingKey int[] mSamplingKeys; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"SAMPLING_KEY_"}, value = { SAMPLING_KEY_RGB, @@ -42,11 +50,14 @@ public final class LutProperties { } /** use r,g,b channel as the gain value of a Lut */ + @FlaggedApi(Flags.FLAG_LUTS_API) public static final int SAMPLING_KEY_RGB = 0; /** use max of r,g,b channel as the gain value of a Lut */ + @FlaggedApi(Flags.FLAG_LUTS_API) public static final int SAMPLING_KEY_MAX_RGB = 1; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(value = { ONE_DIMENSION, @@ -56,18 +67,22 @@ public final class LutProperties { } /** The Lut is one dimensional */ + @FlaggedApi(Flags.FLAG_LUTS_API) public static final int ONE_DIMENSION = 1; /** The Lut is three dimensional */ + @FlaggedApi(Flags.FLAG_LUTS_API) public static final int THREE_DIMENSION = 3; + @FlaggedApi(Flags.FLAG_LUTS_API) public @Dimension int getDimension() { return mDimension; } /** - * @return the size of the Lut. + * @return the size of the Lut for each dimension */ + @FlaggedApi(Flags.FLAG_LUTS_API) public int getSize() { return mSize; } @@ -75,6 +90,8 @@ public final class LutProperties { /** * @return the list of sampling keys */ + @FlaggedApi(Flags.FLAG_LUTS_API) + @NonNull public @SamplingKey int[] getSamplingKeys() { if (mSamplingKeys.length == 0) { throw new IllegalStateException("no sampling key!"); diff --git a/core/java/android/hardware/OverlayProperties.java b/core/java/android/hardware/OverlayProperties.java index 24cfc1b53e00..d42bfae23d2b 100644 --- a/core/java/android/hardware/OverlayProperties.java +++ b/core/java/android/hardware/OverlayProperties.java @@ -18,6 +18,7 @@ package android.hardware; import android.annotation.FlaggedApi; import android.annotation.NonNull; +import android.annotation.SuppressLint; import android.hardware.flags.Flags; import android.os.Parcel; import android.os.Parcelable; @@ -72,9 +73,11 @@ public final class OverlayProperties implements Parcelable { } /** - * Gets the lut properties of the display. - * @hide + * Returns the lut properties of the device. */ + @FlaggedApi(Flags.FLAG_LUTS_API) + @SuppressLint("ArrayReturn") + @NonNull public LutProperties[] getLutProperties() { if (mNativeObject == 0) { return null; diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 28da644dd837..e6a1640781ed 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -21,6 +21,8 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.HdrCapabilities.HdrType; import static android.view.Display.INVALID_DISPLAY; +import static com.android.server.display.feature.flags.Flags.FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS; + import android.Manifest; import android.annotation.FlaggedApi; import android.annotation.FloatRange; @@ -576,6 +578,8 @@ public final class DisplayManager { EVENT_FLAG_DISPLAY_ADDED, EVENT_FLAG_DISPLAY_CHANGED, EVENT_FLAG_DISPLAY_REMOVED, + EVENT_FLAG_DISPLAY_REFRESH_RATE, + EVENT_FLAG_DISPLAY_STATE }) @Retention(RetentionPolicy.SOURCE) public @interface EventFlag {} @@ -596,8 +600,8 @@ public final class DisplayManager { * * @see #registerDisplayListener(DisplayListener, Handler, long) * - * @hide */ + @FlaggedApi(FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS) public static final long EVENT_FLAG_DISPLAY_ADDED = 1L << 0; /** @@ -605,8 +609,8 @@ public final class DisplayManager { * * @see #registerDisplayListener(DisplayListener, Handler, long) * - * @hide */ + @FlaggedApi(FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS) public static final long EVENT_FLAG_DISPLAY_REMOVED = 1L << 1; /** @@ -614,10 +618,27 @@ public final class DisplayManager { * * @see #registerDisplayListener(DisplayListener, Handler, long) * - * @hide */ + @FlaggedApi(FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS) public static final long EVENT_FLAG_DISPLAY_CHANGED = 1L << 2; + + /** + * Event flag to register for a display's refresh rate changes. + * + * @see #registerDisplayListener(DisplayListener, Handler, long) + */ + @FlaggedApi(FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS) + public static final long EVENT_FLAG_DISPLAY_REFRESH_RATE = 1L << 3; + + /** + * Event flag to register for a display state changes. + * + * @see #registerDisplayListener(DisplayListener, Handler, long) + */ + @FlaggedApi(FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS) + public static final long EVENT_FLAG_DISPLAY_STATE = 1L << 4; + /** * Event flag to register for a display's brightness changes. This notification is sent * through the {@link DisplayListener#onDisplayChanged} callback method. New brightness @@ -787,9 +808,6 @@ public final class DisplayManager { * if the listener should be invoked on the calling thread's looper. * @param eventFlags A bitmask of the event types for which this listener is subscribed. * - * @see #EVENT_FLAG_DISPLAY_ADDED - * @see #EVENT_FLAG_DISPLAY_CHANGED - * @see #EVENT_FLAG_DISPLAY_REMOVED * @see #registerDisplayListener(DisplayListener, Handler) * @see #unregisterDisplayListener * @@ -806,18 +824,31 @@ public final class DisplayManager { * Registers a display listener to receive notifications about given display event types. * * @param listener The listener to register. + * @param executor Executor for the thread that will be receiving the callbacks. Cannot be null. + * @param eventFlags A bitmask of the event types for which this listener is subscribed. + * + * @see #registerDisplayListener(DisplayListener, Handler) + * @see #unregisterDisplayListener + * + */ + @FlaggedApi(FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS) + public void registerDisplayListener(@NonNull Executor executor, @EventFlag long eventFlags, + @NonNull DisplayListener listener) { + mGlobal.registerDisplayListener(listener, executor, + mGlobal.mapFlagsToInternalEventFlag(eventFlags, 0), + ActivityThread.currentPackageName()); + } + + /** + * Registers a display listener to receive notifications about given display event types. + * + * @param listener The listener to register. * @param handler The handler on which the listener should be invoked, or null * if the listener should be invoked on the calling thread's looper. * @param eventFlags A bitmask of the event types for which this listener is subscribed. * @param privateEventFlags A bitmask of the private event types for which this listener * is subscribed. * - * @see #EVENT_FLAG_DISPLAY_ADDED - * @see #EVENT_FLAG_DISPLAY_CHANGED - * @see #EVENT_FLAG_DISPLAY_REMOVED - * @see #PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS - * @see #PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED - * @see #PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED * @see #registerDisplayListener(DisplayListener, Handler) * @see #unregisterDisplayListener * diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index 03b44f63e3b7..be710b1328e7 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -62,6 +62,7 @@ import android.view.DisplayInfo; import android.view.Surface; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.display.feature.flags.Flags; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -108,6 +109,8 @@ public final class DisplayManagerGlobal { EVENT_DISPLAY_HDR_SDR_RATIO_CHANGED, EVENT_DISPLAY_CONNECTED, EVENT_DISPLAY_DISCONNECTED, + EVENT_DISPLAY_REFRESH_RATE_CHANGED, + EVENT_DISPLAY_STATE_CHANGED }) @Retention(RetentionPolicy.SOURCE) public @interface DisplayEvent {} @@ -119,6 +122,8 @@ public final class DisplayManagerGlobal { public static final int EVENT_DISPLAY_HDR_SDR_RATIO_CHANGED = 5; public static final int EVENT_DISPLAY_CONNECTED = 6; public static final int EVENT_DISPLAY_DISCONNECTED = 7; + public static final int EVENT_DISPLAY_REFRESH_RATE_CHANGED = 8; + public static final int EVENT_DISPLAY_STATE_CHANGED = 9; @LongDef(prefix = {"INTERNAL_EVENT_DISPLAY"}, flag = true, value = { INTERNAL_EVENT_FLAG_DISPLAY_ADDED, @@ -127,6 +132,8 @@ public final class DisplayManagerGlobal { INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED, INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED, INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED, + INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE, + INTERNAL_EVENT_FLAG_DISPLAY_STATE }) @Retention(RetentionPolicy.SOURCE) public @interface InternalEventFlag {} @@ -137,6 +144,8 @@ public final class DisplayManagerGlobal { public static final long INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED = 1L << 3; public static final long INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED = 1L << 4; public static final long INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED = 1L << 5; + public static final long INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE = 1L << 6; + public static final long INTERNAL_EVENT_FLAG_DISPLAY_STATE = 1L << 7; @UnsupportedAppUsage private static DisplayManagerGlobal sInstance; @@ -1427,6 +1436,18 @@ public final class DisplayManagerGlobal { mListener.onDisplayDisconnected(displayId); } break; + case EVENT_DISPLAY_REFRESH_RATE_CHANGED: + if ((mInternalEventFlagsMask + & INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE) != 0) { + mListener.onDisplayChanged(displayId); + } + break; + case EVENT_DISPLAY_STATE_CHANGED: + if ((mInternalEventFlagsMask + & INTERNAL_EVENT_FLAG_DISPLAY_STATE) != 0) { + mListener.onDisplayChanged(displayId); + } + break; } if (DEBUG) { Trace.endSection(); @@ -1566,6 +1587,10 @@ public final class DisplayManagerGlobal { return "EVENT_DISPLAY_CONNECTED"; case EVENT_DISPLAY_DISCONNECTED: return "EVENT_DISPLAY_DISCONNECTED"; + case EVENT_DISPLAY_REFRESH_RATE_CHANGED: + return "EVENT_DISPLAY_REFRESH_RATE_CHANGED"; + case EVENT_DISPLAY_STATE_CHANGED: + return "EVENT_DISPLAY_STATE_CHANGED"; } return "UNKNOWN"; } @@ -1630,6 +1655,17 @@ public final class DisplayManagerGlobal { baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_REMOVED; } + if (Flags.displayListenerPerformanceImprovements()) { + if ((eventFlags & DisplayManager.EVENT_FLAG_DISPLAY_REFRESH_RATE) != 0) { + baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE; + } + + if ((eventFlags & DisplayManager.EVENT_FLAG_DISPLAY_STATE) != 0) { + baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_STATE; + } + } + + return baseEventMask; } } diff --git a/core/java/android/hardware/display/DisplayTopology.java b/core/java/android/hardware/display/DisplayTopology.java index e349b81614bc..f00c3a53ad0c 100644 --- a/core/java/android/hardware/display/DisplayTopology.java +++ b/core/java/android/hardware/display/DisplayTopology.java @@ -23,6 +23,7 @@ import static android.hardware.display.DisplayTopology.TreeNode.POSITION_TOP; import android.annotation.IntDef; import android.annotation.Nullable; +import android.graphics.PointF; import android.graphics.RectF; import android.os.Parcel; import android.os.Parcelable; @@ -150,6 +151,138 @@ public final class DisplayTopology implements Parcelable { } } + /** + * Rearranges the topology toward the positions given for each display. The width and height of + * each display, as well as the primary display, are not changed by this call. + * <p> + * Upon returning, the topology will be valid and normalized with each display as close to the + * requested positions as possible. + * + * @param newPos the desired positions (upper-left corner) of each display. The keys in the map + * are the display IDs. + * @throws IllegalArgumentException if the keys in {@code positions} are not the exact display + * IDs in this topology, no more, no less + */ + public void rearrange(Map<Integer, PointF> newPos) { + var availableParents = new ArrayList<TreeNode>(); + + availableParents.addLast(mRoot); + + var needsParent = allNodesIdMap(); + + // In the case of missing items, if this check doesn't detect it, a NPE will be thrown + // later. + if (needsParent.size() != newPos.size()) { + throw new IllegalArgumentException("newPos has wrong number of entries: " + newPos); + } + + mRoot.mChildren.clear(); + for (TreeNode n : needsParent.values()) { + n.mChildren.clear(); + } + + needsParent.remove(mRoot.mDisplayId); + // Start with a root island and add children to it one-by-one until the island consists of + // all the displays. The root island begins with only the root node, which has no + // parent. Then we greedily choose an optimal pairing of two nodes, consisting of a node + // from the island and a node not yet in the island. This is repeating until all nodes are + // in the island. + // + // The optimal pair is the pair which has the smallest deviation. The deviation consists of + // an x-axis component and a y-axis component, called xDeviation and yDeviation. + // + // The deviations are like distances but a little different. They are calculated in two + // steps. The first step calculates both axes in a similar way. The next step compares the + // two values and chooses which axis to attach along. Depending on which axis is chosen, + // the deviation for one axis is updated. See below for details. + while (!needsParent.isEmpty()) { + double bestDist = Double.POSITIVE_INFINITY; + TreeNode bestChild = null, bestParent = null; + + for (var child : needsParent.values()) { + PointF childPos = newPos.get(child.mDisplayId); + float childRight = childPos.x + child.getWidth(); + float childBottom = childPos.y + child.getHeight(); + for (var parent : availableParents) { + PointF parentPos = newPos.get(parent.mDisplayId); + float parentRight = parentPos.x + parent.getWidth(); + float parentBottom = parentPos.y + parent.getHeight(); + + // This is the smaller of the two ranges minus the amount of overlap shared + // between them. The "amount of overlap" is negative if there is no overlap, but + // this does not make a parenting ineligible, because we allow for attaching at + // the corner and for floating point error. The overlap is more negative the + // farther apart the closest corner pair is. + // + // For each axis, this calculates (SmallerRange - Overlap). If one range lies + // completely in the other (or they are equal), the axis' deviation will be + // zero. + // + // The "SmallerRange," which refers to smaller of the widths of the two rects, + // or smaller of the heights of the two rects, is added to the deviation so that + // a maximum overlap results in a deviation of zero. + float xSmallerRange = Math.min(child.getWidth(), parent.getWidth()); + float ySmallerRange = Math.min(child.getHeight(), parent.getHeight()); + float xOverlap + = Math.min(parentRight, childRight) + - Math.max(parentPos.x, childPos.x); + float yOverlap + = Math.min(parentBottom, childBottom) + - Math.max(parentPos.y, childPos.y); + float xDeviation = xSmallerRange - xOverlap; + float yDeviation = ySmallerRange - yOverlap; + + float offset; + int pos; + if (xDeviation <= yDeviation) { + if (childPos.y < parentPos.y) { + yDeviation = childBottom - parentPos.y; + pos = POSITION_TOP; + } else { + yDeviation = parentBottom - childPos.y; + pos = POSITION_BOTTOM; + } + offset = childPos.x - parentPos.x; + } else { + if (childPos.x < parentPos.x) { + xDeviation = childRight - parentPos.x; + pos = POSITION_LEFT; + } else { + xDeviation = parentRight - childPos.x; + pos = POSITION_RIGHT; + } + offset = childPos.y - parentPos.y; + } + + double dist = Math.hypot(xDeviation, yDeviation); + if (dist >= bestDist) { + continue; + } + + bestDist = dist; + bestChild = child; + bestParent = parent; + // Eagerly update the child's parenting info, even though we may not use it, in + // which case it will be overwritten later. + bestChild.mPosition = pos; + bestChild.mOffset = offset; + } + } + + assert bestParent != null & bestChild != null; + + bestParent.addChild(bestChild); + if (null == needsParent.remove(bestChild.mDisplayId)) { + throw new IllegalStateException("child not in pending set! " + bestChild); + } + availableParents.add(bestChild); + } + + // The conversion may have introduced an intersection of two display rects. If they are + // bigger than our error tolerance, this function will remove them. + normalize(); + } + @Override public int describeContents() { return 0; @@ -450,6 +583,20 @@ public final class DisplayTopology implements Parcelable { return a == b || (Float.isNaN(a) && Float.isNaN(b)) || Math.abs(a - b) < EPSILON; } + private Map<Integer, TreeNode> allNodesIdMap() { + var pend = new ArrayDeque<TreeNode>(); + var found = new HashMap<Integer, TreeNode>(); + + pend.push(mRoot); + do { + TreeNode node = pend.pop(); + found.put(node.mDisplayId, node); + pend.addAll(node.mChildren); + } while (!pend.isEmpty()); + + return found; + } + public static final class TreeNode implements Parcelable { public static final int POSITION_LEFT = 0; public static final int POSITION_TOP = 1; diff --git a/core/java/android/hardware/flags/overlayproperties_flags.aconfig b/core/java/android/hardware/flags/flags.aconfig index 6c86108c4034..5ca6c6bed1f0 100644 --- a/core/java/android/hardware/flags/overlayproperties_flags.aconfig +++ b/core/java/android/hardware/flags/flags.aconfig @@ -2,6 +2,15 @@ package: "android.hardware.flags" container: "system" flag { + name: "luts_api" + is_exported: true + is_fixed_read_only: true + namespace: "core_graphics" + description: "public Luts related Apis" + bug: "349667978" +} + +flag { name: "overlayproperties_class_api" is_exported: true namespace: "core_graphics" diff --git a/core/java/android/hardware/input/AidlInputGestureData.aidl b/core/java/android/hardware/input/AidlInputGestureData.aidl index e33ec53dd208..f7410d2e7783 100644 --- a/core/java/android/hardware/input/AidlInputGestureData.aidl +++ b/core/java/android/hardware/input/AidlInputGestureData.aidl @@ -28,15 +28,18 @@ parcelable AidlInputGestureData { String appLaunchPackageName; String appLaunchClassName; + @JavaDerive(equals=true) parcelable KeyTrigger { int keycode; int modifierState; } + @JavaDerive(equals=true) parcelable TouchpadGestureTrigger { int gestureType; } + @JavaDerive(equals=true) union Trigger { KeyTrigger key; TouchpadGestureTrigger touchpadGesture; diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig index 4b2f2c218e5a..fee074901c10 100644 --- a/core/java/android/hardware/input/input_framework.aconfig +++ b/core/java/android/hardware/input/input_framework.aconfig @@ -170,4 +170,11 @@ flag { namespace: "input" description: "Adds key gestures for talkback and magnifier" bug: "375277034" -}
\ No newline at end of file +} + +flag { + name: "can_window_override_power_gesture_api" + namespace: "wallet_integration" + description: "Adds new API in WindowManager class to check if the window can override the power key double tap behavior." + bug: "378736024" + }
\ No newline at end of file diff --git a/core/java/android/inputmethodservice/AbstractInputMethodService.java b/core/java/android/inputmethodservice/AbstractInputMethodService.java index 4bc5bd2427ea..26308f69cfbe 100644 --- a/core/java/android/inputmethodservice/AbstractInputMethodService.java +++ b/core/java/android/inputmethodservice/AbstractInputMethodService.java @@ -16,6 +16,9 @@ package android.inputmethodservice; +import static android.view.inputmethod.Flags.FLAG_VERIFY_KEY_EVENT; + +import android.annotation.FlaggedApi; import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; @@ -193,6 +196,12 @@ public abstract class AbstractInputMethodService extends WindowProviderService } } + @FlaggedApi(FLAG_VERIFY_KEY_EVENT) + @Override + public boolean onShouldVerifyKeyEvent(@NonNull KeyEvent event) { + return AbstractInputMethodService.this.onShouldVerifyKeyEvent(event); + } + /** * Take care of dispatching incoming trackball events to the appropriate * callbacks on the service, and tell the client when this is done. @@ -308,6 +317,14 @@ public abstract class AbstractInputMethodService extends WindowProviderService return false; } + /** + * @see InputMethodService#onShouldVerifyKeyEvent(KeyEvent) + */ + @FlaggedApi(FLAG_VERIFY_KEY_EVENT) + public boolean onShouldVerifyKeyEvent(@NonNull KeyEvent event) { + return false; + } + /** @hide */ @Override public final int getWindowType() { diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java index 62b131af74fe..9b37533f5b02 100644 --- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java @@ -16,12 +16,16 @@ package android.inputmethodservice; +import static android.view.inputmethod.Flags.verifyKeyEvent; + import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; +import android.hardware.input.InputManager; import android.os.Bundle; import android.os.Looper; import android.os.Message; +import android.os.SystemClock; import android.util.Log; import android.util.SparseArray; import android.view.InputChannel; @@ -41,6 +45,8 @@ import com.android.internal.inputmethod.IRemoteInputConnection; import com.android.internal.os.HandlerCaller; import com.android.internal.os.SomeArgs; +import java.util.Objects; + class IInputMethodSessionWrapper extends IInputMethodSession.Stub implements HandlerCaller.Callback { private static final String TAG = "InputMethodWrapper"; @@ -56,6 +62,7 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub private static final int DO_REMOVE_IME_SURFACE = 130; private static final int DO_FINISH_INPUT = 140; private static final int DO_INVALIDATE_INPUT = 150; + private final Context mContext; @UnsupportedAppUsage @@ -66,6 +73,7 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub public IInputMethodSessionWrapper(Context context, InputMethodSession inputMethodSession, InputChannel channel) { + mContext = context; mCaller = new HandlerCaller(context, null, this, true /*asyncHandler*/); mInputMethodSession = inputMethodSession; @@ -233,6 +241,8 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub } private final class ImeInputEventReceiver extends InputEventReceiver implements InputMethodSession.EventCallback { + // Time after which a KeyEvent is invalid + private static final long KEY_EVENT_ALLOW_PERIOD_MS = 100L; private final SparseArray<InputEvent> mPendingEvents = new SparseArray<InputEvent>(); public ImeInputEventReceiver(InputChannel inputChannel, Looper looper) { @@ -247,10 +257,23 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub return; } + if (event instanceof KeyEvent keyEvent && needsVerification(keyEvent)) { + // any KeyEvent with modifiers (e.g. Ctrl/Alt/Fn) must be verified that + // they originated from system. + InputManager im = mContext.getSystemService(InputManager.class); + Objects.requireNonNull(im); + final long age = SystemClock.uptimeMillis() - keyEvent.getEventTime(); + if (age >= KEY_EVENT_ALLOW_PERIOD_MS && im.verifyInputEvent(keyEvent) == null) { + Log.w(TAG, "Unverified or Invalid KeyEvent injected into IME. Dropping " + + keyEvent); + finishInputEvent(event, false /* handled */); + return; + } + } + final int seq = event.getSequenceNumber(); mPendingEvents.put(seq, event); - if (event instanceof KeyEvent) { - KeyEvent keyEvent = (KeyEvent)event; + if (event instanceof KeyEvent keyEvent) { mInputMethodSession.dispatchKeyEvent(seq, keyEvent, this); } else { MotionEvent motionEvent = (MotionEvent)event; @@ -271,5 +294,21 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub finishInputEvent(event, handled); } } + + private boolean hasKeyModifiers(KeyEvent event) { + if (event.hasNoModifiers()) { + return false; + } + return event.hasModifiers(KeyEvent.META_CTRL_ON) + || event.hasModifiers(KeyEvent.META_ALT_ON) + || event.hasModifiers(KeyEvent.KEYCODE_FUNCTION); + } + + private boolean needsVerification(KeyEvent event) { + //TODO(b/331730488): Handle a11y events as well. + return verifyKeyEvent() + && (hasKeyModifiers(event) + || mInputMethodSession.onShouldVerifyKeyEvent(event)); + } } } diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 8c3f0ef08039..a8fde4a3f7c6 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -55,6 +55,8 @@ import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECT import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECTIONLESS_HANDWRITING_ERROR_OTHER; import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED; import static android.view.inputmethod.Flags.FLAG_CONNECTIONLESS_HANDWRITING; +import static android.view.inputmethod.Flags.FLAG_IME_SWITCHER_REVAMP_API; +import static android.view.inputmethod.Flags.FLAG_VERIFY_KEY_EVENT; import static android.view.inputmethod.Flags.ctrlShiftShortcut; import static android.view.inputmethod.Flags.predictiveBackIme; @@ -3436,7 +3438,7 @@ public class InputMethodService extends AbstractInputMethodService { initialize(); mInlineSuggestionSessionController.notifyOnStartInput( editorInfo == null ? null : editorInfo.packageName, - editorInfo == null ? null : editorInfo.autofillId); + editorInfo == null ? null : editorInfo.getAutofillId()); if (DEBUG) Log.v(TAG, "CALL: onStartInput"); onStartInput(editorInfo, restarting); if (mDecorViewVisible) { @@ -3734,6 +3736,23 @@ public class InputMethodService extends AbstractInputMethodService { } /** + * Received by the IME before dispatch to {@link #onKeyDown(int, KeyEvent)} to let the system + * know if the {@link KeyEvent} needs to be verified that it originated from the system. + * {@link KeyEvent}s may originate from outside of the system and any sensitive keys should be + * marked for verification. One example of this could be using key shortcuts for switching to + * another IME. + * + * @param keyEvent the event that may need verification. + * @return {@code true} if {@link KeyEvent} should have its HMAC verified before dispatch, + * {@code false} otherwise. + */ + @FlaggedApi(FLAG_VERIFY_KEY_EVENT) + @Override + public boolean onShouldVerifyKeyEvent(@NonNull KeyEvent keyEvent) { + return false; + } + + /** * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent) * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle * the event). @@ -4392,6 +4411,39 @@ public class InputMethodService extends AbstractInputMethodService { } /** + * Called when the requested visibility of a custom IME Switcher button changes. + * + * <p>When the system provides an IME navigation bar, it may decide to show an IME Switcher + * button inside this bar. However, the IME can request hiding the bar provided by the system + * with {@code getWindowInsetsController().hide(captionBar())} (the IME navigation bar provides + * {@link Type#captionBar() captionBar} insets to the IME window). If the request is successful, + * then it becomes the IME's responsibility to provide a custom IME Switcher button in its + * input view, with equivalent functionality.</p> + * + * <p>This custom button is only requested to be visible when the system provides the IME + * navigation bar, both the bar and the IME Switcher button inside it should be visible, + * but the IME successfully requested to hide the bar. This does not depend on the current + * visibility of the IME. It could be called with {@code true} while the IME is hidden, in + * which case the IME should prepare to show the button as soon as the IME itself is shown.</p> + * + * <p>This is only called when the requested visibility changes. The default value is + * {@code false} and as such, this will not be called initially if the resulting value is + * {@code false}.</p> + * + * <p>This can be called at any time after {@link #onCreate}, even if the IME is not currently + * visible. However, this is not guaranteed to be called before the IME is shown, as it depends + * on when the IME requested hiding the IME navigation bar. If the request is sent during + * the showing flow (e.g. during {@link #onStartInputView}), this will be called shortly after + * {@link #onWindowShown}, but before the first IME frame is drawn.</p> + * + * @param visible whether the button is requested visible or not. + */ + @FlaggedApi(FLAG_IME_SWITCHER_REVAMP_API) + public void onCustomImeSwitcherButtonRequestedVisible(boolean visible) { + // Intentionally empty + } + + /** * Called when the IME switch button was clicked from the client. Depending on the number of * enabled IME subtypes, this will either switch to the next IME/subtype, or show the input * method picker dialog. diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java index b08454dd7f8f..38be8d9f772d 100644 --- a/core/java/android/inputmethodservice/NavigationBarController.java +++ b/core/java/android/inputmethodservice/NavigationBarController.java @@ -41,6 +41,7 @@ import android.view.WindowInsets; import android.view.WindowInsetsController.Appearance; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; +import android.view.inputmethod.Flags; import android.view.inputmethod.InputMethodManager; import android.widget.FrameLayout; @@ -178,6 +179,9 @@ final class NavigationBarController { private boolean mDrawLegacyNavigationBarBackground; + /** Whether a custom IME Switcher button should be visible. */ + private boolean mCustomImeSwitcherVisible; + private final Rect mTempRect = new Rect(); private final int[] mTempPos = new int[2]; @@ -265,6 +269,7 @@ final class NavigationBarController { // IME navigation bar. boolean visible = insets.isVisible(captionBar()); mNavigationBarFrame.setVisibility(visible ? View.VISIBLE : View.GONE); + checkCustomImeSwitcherVisibility(); } return view.onApplyWindowInsets(insets); }); @@ -491,6 +496,8 @@ final class NavigationBarController { mShouldShowImeSwitcherWhenImeIsShown; mShouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherWhenImeIsShown; + checkCustomImeSwitcherVisibility(); + mService.mWindow.getWindow().getDecorView().getWindowInsetsController() .setImeCaptionBarInsetsHeight(getImeCaptionBarHeight(imeDrawsImeNavBar)); @@ -616,12 +623,33 @@ final class NavigationBarController { && mNavigationBarFrame.getVisibility() == View.VISIBLE; } + /** + * Checks if a custom IME Switcher button should be visible, and notifies the IME when this + * state changes. This can only be {@code true} if three conditions are met: + * + * <li>The IME should draw the IME navigation bar.</li> + * <li>The IME Switcher button should be visible when the IME is visible.</li> + * <li>The IME navigation bar should be visible, but was requested hidden by the IME.</li> + */ + private void checkCustomImeSwitcherVisibility() { + if (!Flags.imeSwitcherRevampApi()) { + return; + } + final boolean visible = mImeDrawsImeNavBar && mShouldShowImeSwitcherWhenImeIsShown + && mNavigationBarFrame != null && !isShown(); + if (visible != mCustomImeSwitcherVisible) { + mCustomImeSwitcherVisible = visible; + mService.onCustomImeSwitcherButtonRequestedVisible(mCustomImeSwitcherVisible); + } + } + @Override public String toDebugString() { return "{mImeDrawsImeNavBar=" + mImeDrawsImeNavBar + " mNavigationBarFrame=" + mNavigationBarFrame + " mShouldShowImeSwitcherWhenImeIsShown=" + mShouldShowImeSwitcherWhenImeIsShown + + " mCustomImeSwitcherVisible=" + mCustomImeSwitcherVisible + " mAppearance=0x" + Integer.toHexString(mAppearance) + " mDarkIntensity=" + mDarkIntensity + " mDrawLegacyNavigationBarBackground=" + mDrawLegacyNavigationBarBackground diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 102bdd0b625c..c2e9260879a8 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -32,6 +32,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.ravenwood.annotation.RavenwoodKeepWholeClass; import android.sdk.Flags; +import android.sysprop.BackportedFixesProperties; import android.sysprop.DeviceProperties; import android.sysprop.SocProperties; import android.sysprop.TelephonyProperties; @@ -1612,12 +1613,25 @@ public class Build { * is not applicable on this device, * otherwise {@link #BACKPORTED_FIX_STATUS_UNKNOWN}. */ - @FlaggedApi(android.os.Flags.FLAG_API_FOR_BACKPORTED_FIXES) public static @BackportedFixStatus int getBackportedFixStatus(long id) { - // TODO: b/308461809 - query aliases from system prop - // TODO: b/372518979 - use backported fix datastore. - return BACKPORTED_FIX_STATUS_UNKNOWN; + if (id <= 0 || id > 1023) { + return BACKPORTED_FIX_STATUS_UNKNOWN; + } + return isBitSet(BackportedFixesProperties.alias_bitset(), (int) id) + ? BACKPORTED_FIX_STATUS_FIXED : BACKPORTED_FIX_STATUS_UNKNOWN; + } + + private static boolean isBitSet(List<Long> bitsetLongArray, int bitIndex) { + // Because java.util.BitSet is not threadsafe do the calculations here instead. + if (bitIndex < 0) { + return false; + } + int arrayIndex = bitIndex >> 6; + if (bitsetLongArray.size() <= arrayIndex) { + return false; + } + return (bitsetLongArray.get(arrayIndex) & (1L << bitIndex)) != 0; } /** diff --git a/core/java/android/os/CpuHeadroomParams.java b/core/java/android/os/CpuHeadroomParams.java new file mode 100644 index 000000000000..f0d4f7d8737f --- /dev/null +++ b/core/java/android/os/CpuHeadroomParams.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import android.annotation.FlaggedApi; +import android.annotation.IntDef; +import android.os.health.SystemHealthManager; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Headroom request params used by {@link SystemHealthManager#getCpuHeadroom(CpuHeadroomParams)}. + */ +@FlaggedApi(Flags.FLAG_CPU_GPU_HEADROOMS) +public final class CpuHeadroomParams { + final CpuHeadroomParamsInternal mInternal; + + public CpuHeadroomParams() { + mInternal = new CpuHeadroomParamsInternal(); + } + + /** @hide */ + @IntDef(flag = false, prefix = {"CPU_HEADROOM_CALCULATION_TYPE_"}, value = { + CPU_HEADROOM_CALCULATION_TYPE_MIN, // 0 + CPU_HEADROOM_CALCULATION_TYPE_AVERAGE, // 1 + }) + @Retention(RetentionPolicy.SOURCE) + public @interface CpuHeadroomCalculationType { + } + + /** + * Calculates the headroom based on minimum value over a device-defined window. + */ + public static final int CPU_HEADROOM_CALCULATION_TYPE_MIN = 0; + + /** + * Calculates the headroom based on average value over a device-defined window. + */ + public static final int CPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1; + + /** + * Sets the headroom calculation type. + * <p> + * + * @throws IllegalArgumentException if the type is invalid. + */ + public void setCalculationType(@CpuHeadroomCalculationType int calculationType) { + switch (calculationType) { + case CPU_HEADROOM_CALCULATION_TYPE_MIN: + case CPU_HEADROOM_CALCULATION_TYPE_AVERAGE: + mInternal.calculationType = (byte) calculationType; + return; + } + throw new IllegalArgumentException("Invalid calculation type: " + calculationType); + } + + /** + * Gets the headroom calculation type. + * Default to {@link #CPU_HEADROOM_CALCULATION_TYPE_MIN} if not set. + */ + public @CpuHeadroomCalculationType int getCalculationType() { + @CpuHeadroomCalculationType int validatedType = switch ((int) mInternal.calculationType) { + case CPU_HEADROOM_CALCULATION_TYPE_MIN, CPU_HEADROOM_CALCULATION_TYPE_AVERAGE -> + mInternal.calculationType; + default -> CPU_HEADROOM_CALCULATION_TYPE_MIN; + }; + return validatedType; + } + + /** + * @hide + */ + public CpuHeadroomParamsInternal getInternal() { + return mInternal; + } +} diff --git a/core/java/android/os/CpuHeadroomParamsInternal.aidl b/core/java/android/os/CpuHeadroomParamsInternal.aidl new file mode 100644 index 000000000000..6cc4699a809e --- /dev/null +++ b/core/java/android/os/CpuHeadroomParamsInternal.aidl @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import android.hardware.power.CpuHeadroomParams; + +/** + * Changes should be synced with match function of HintManagerService#CpuHeadroomCacheItem. + * {@hide} + */ +@JavaDerive(equals = true, toString = true) +parcelable CpuHeadroomParamsInternal { + boolean usesDeviceHeadroom = false; + CpuHeadroomParams.CalculationType calculationType = CpuHeadroomParams.CalculationType.MIN; + CpuHeadroomParams.SelectionType selectionType = CpuHeadroomParams.SelectionType.ALL; +} + diff --git a/core/java/android/os/GpuHeadroomParams.java b/core/java/android/os/GpuHeadroomParams.java new file mode 100644 index 000000000000..efb2a28ad2b5 --- /dev/null +++ b/core/java/android/os/GpuHeadroomParams.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import android.annotation.FlaggedApi; +import android.annotation.IntDef; +import android.os.health.SystemHealthManager; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Headroom request params used by {@link SystemHealthManager#getGpuHeadroom(GpuHeadroomParams)}. + */ +@FlaggedApi(Flags.FLAG_CPU_GPU_HEADROOMS) +public final class GpuHeadroomParams { + final GpuHeadroomParamsInternal mInternal; + + public GpuHeadroomParams() { + mInternal = new GpuHeadroomParamsInternal(); + } + + /** @hide */ + @IntDef(flag = false, prefix = {"GPU_HEADROOM_CALCULATION_TYPE_"}, value = { + GPU_HEADROOM_CALCULATION_TYPE_MIN, // 0 + GPU_HEADROOM_CALCULATION_TYPE_AVERAGE, // 1 + }) + @Retention(RetentionPolicy.SOURCE) + public @interface GpuHeadroomCalculationType { + } + + /** + * Calculates the headroom based on minimum value over a device-defined window. + */ + public static final int GPU_HEADROOM_CALCULATION_TYPE_MIN = 0; + + /** + * Calculates the headroom based on average value over a device-defined window. + */ + public static final int GPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1; + + /** + * Sets the headroom calculation type. + * <p> + * + * @throws IllegalArgumentException if the type is invalid. + */ + public void setCalculationType(@GpuHeadroomCalculationType int calculationType) { + switch (calculationType) { + case GPU_HEADROOM_CALCULATION_TYPE_MIN: + case GPU_HEADROOM_CALCULATION_TYPE_AVERAGE: + mInternal.calculationType = (byte) calculationType; + return; + } + throw new IllegalArgumentException("Invalid calculation type: " + calculationType); + } + + /** + * Gets the headroom calculation type. + * Default to {@link #GPU_HEADROOM_CALCULATION_TYPE_MIN} if not set. + */ + public @GpuHeadroomCalculationType int getCalculationType() { + @GpuHeadroomCalculationType int validatedType = switch ((int) mInternal.calculationType) { + case GPU_HEADROOM_CALCULATION_TYPE_MIN, GPU_HEADROOM_CALCULATION_TYPE_AVERAGE -> + mInternal.calculationType; + default -> GPU_HEADROOM_CALCULATION_TYPE_MIN; + }; + return validatedType; + } + + /** + * @hide + */ + public GpuHeadroomParamsInternal getInternal() { + return mInternal; + } +} diff --git a/services/core/java/com/android/server/integrity/model/IndexingFileConstants.java b/core/java/android/os/GpuHeadroomParamsInternal.aidl index 0c4052adc3ed..20309e7673f2 100644 --- a/services/core/java/com/android/server/integrity/model/IndexingFileConstants.java +++ b/core/java/android/os/GpuHeadroomParamsInternal.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,15 @@ * limitations under the License. */ -package com.android.server.integrity.model; +package android.os; -/** A helper class containing special indexing file constants. */ -public final class IndexingFileConstants { - // We empirically experimented with different block sizes and identified that 50 is in the - // optimal range of efficient computation. - public static final int INDEXING_BLOCK_SIZE = 50; +import android.hardware.power.GpuHeadroomParams; - public static final String START_INDEXING_KEY = "START_KEY"; - public static final String END_INDEXING_KEY = "END_KEY"; +/** + * Changes should be synced with match function of HintManagerService#GpuHeadroomCacheItem. + * {@hide} + */ +@JavaDerive(equals = true, toString = true) +parcelable GpuHeadroomParamsInternal { + GpuHeadroomParams.CalculationType calculationType = GpuHeadroomParams.CalculationType.MIN; } diff --git a/core/java/android/os/IHintManager.aidl b/core/java/android/os/IHintManager.aidl index 73cdd5682f31..33120556339f 100644 --- a/core/java/android/os/IHintManager.aidl +++ b/core/java/android/os/IHintManager.aidl @@ -17,6 +17,8 @@ package android.os; +import android.os.CpuHeadroomParamsInternal; +import android.os.GpuHeadroomParamsInternal; import android.os.IHintSession; import android.hardware.power.ChannelConfig; import android.hardware.power.SessionConfig; @@ -50,4 +52,8 @@ interface IHintManager { */ @nullable ChannelConfig getSessionChannel(in IBinder token); oneway void closeSessionChannel(); + float[] getCpuHeadroom(in CpuHeadroomParamsInternal params); + long getCpuHeadroomMinIntervalMillis(); + float getGpuHeadroom(in GpuHeadroomParamsInternal params); + long getGpuHeadroomMinIntervalMillis(); } diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS index 590ddb404b63..24e1d6666093 100644 --- a/core/java/android/os/OWNERS +++ b/core/java/android/os/OWNERS @@ -78,6 +78,9 @@ per-file PatternMatcher* = file:/PACKAGE_MANAGER_OWNERS # PermissionEnforcer per-file PermissionEnforcer.java = tweek@google.com, brufino@google.com +# RemoteCallbackList +per-file RemoteCallbackList.java = shayba@google.com + # ART per-file ArtModuleServiceManager.java = file:platform/art:/OWNERS diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index f7285523c01a..bf7116d6a05b 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -1371,7 +1371,6 @@ public final class Parcel { writeInt(N); if (DEBUG_ARRAY_MAP) { RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); Log.d(TAG, "Writing " + N + " ArrayMap entries", here); } int startPos; diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 4bc8fe0a974c..5a53bc1552b8 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -3928,9 +3928,9 @@ public class UserManager { final int callingUid = Binder.getCallingUid(); final int processUid = Process.myUid(); - if (Build.isDebuggable() && callingUid != processUid) { - Log.w(TAG, "Uid " + processUid + " is fetching a copy of UserProperties on" - + " behalf of callingUid " + callingUid + ". Possibly" + if (processUid == Process.SYSTEM_UID && callingUid != processUid) { + Log.w(TAG, "The System (uid " + processUid + ") is fetching a copy of" + + " UserProperties on behalf of callingUid " + callingUid + ". Possibly" + " it should carefully first clearCallingIdentity or perhaps use" + " UserManagerInternal.getUserProperties() instead?", new Throwable()); @@ -5308,7 +5308,13 @@ public class UserManager { Manifest.permission.MANAGE_USERS, Manifest.permission.CREATE_USERS, Manifest.permission.QUERY_USERS}, conditional = true) + @CachedProperty(api = "user_manager_user_data") public List<UserInfo> getProfiles(@UserIdInt int userId) { + if (android.multiuser.Flags.cacheProfilesReadOnly()) { + return UserManagerCache.getProfiles( + (Integer userIdentifier) -> mService.getProfiles(userIdentifier, false), + userId); + } try { return mService.getProfiles(userId, false /* enabledOnly */); } catch (RemoteException re) { @@ -6484,6 +6490,19 @@ public class UserManager { } /** + * This method is used to invalidate caches, when UserManagerService.mUsers + * {@link UserManagerService.UserData} is modified, including changes to {@link UserInfo}. + * In practice we determine modification by when that data is persisted, or scheduled to be + * presisted, to xml. + * @hide + */ + public static final void invalidateCacheOnUserDataChanged() { + if (android.multiuser.Flags.cacheProfilesReadOnly()) { + UserManagerCache.invalidateProfiles(); + } + } + + /** * Returns a serial number on this device for a given userId. User handles can be recycled * when deleting and creating users, but serial numbers are not reused until the device is * wiped. diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java index 0cffd9f990fd..70cbc732366a 100644 --- a/core/java/android/os/VibrationEffect.java +++ b/core/java/android/os/VibrationEffect.java @@ -41,6 +41,7 @@ import android.os.vibrator.PwleSegment; import android.os.vibrator.RampSegment; import android.os.vibrator.StepSegment; import android.os.vibrator.VibrationEffectSegment; +import android.os.vibrator.VibratorEnvelopeEffectInfo; import android.os.vibrator.VibratorFrequencyProfileLegacy; import android.util.MathUtils; @@ -1483,6 +1484,15 @@ public abstract class VibrationEffect implements Parcelable { public @interface PrimitiveType { } + /** @hide */ + @IntDef(prefix = { "DELAY_TYPE_" }, value = { + DELAY_TYPE_PAUSE, + DELAY_TYPE_RELATIVE_START_OFFSET, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DelayType { + } + /** * Exception thrown when adding an element to a {@link Composition} that already ends in an * indefinitely repeating effect. @@ -1541,6 +1551,53 @@ public abstract class VibrationEffect implements Parcelable { // Internally this maps to the HAL constant CompositePrimitive::LOW_TICK public static final int PRIMITIVE_LOW_TICK = 8; + /** + * The delay represents a pause in the composition between the end of the previous primitive + * and the beginning of the next one. + * + * <p>The primitive will start after the requested pause after the last primitive ended. + * The actual time the primitive will be played depends on the previous primitive's actual + * duration on the device hardware. This enables the combination of primitives to create + * more complex effects based on how close to each other they'll play. Here is an example: + * + * <pre> + * VibrationEffect popEffect = VibrationEffect.startComposition() + * .addPrimitive(PRIMITIVE_QUICK_RISE) + * .addPrimitive(PRIMITIVE_CLICK, 0.7, 50, DELAY_TYPE_PAUSE) + * .compose() + * </pre> + */ + @FlaggedApi(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + public static final int DELAY_TYPE_PAUSE = 0; + + /** + * The delay represents an offset before starting this primitive, relative to the start + * time of the previous primitive in the composition. + * + * <p>The primitive will start at the requested fixed time after the last primitive started, + * independently of that primitive's actual duration on the device hardware. This enables + * precise timings of primitives within a composition, ensuring they'll be played at the + * desired intervals. Here is an example: + * + * <pre> + * VibrationEffect.startComposition() + * .addPrimitive(PRIMITIVE_CLICK, 1.0) + * .addPrimitive(PRIMITIVE_TICK, 1.0, 20, DELAY_TYPE_RELATIVE_START_OFFSET) + * .addPrimitive(PRIMITIVE_THUD, 1.0, 80, DELAY_TYPE_RELATIVE_START_OFFSET) + * .compose() + * </pre> + * + * Will be performed on the device as follows: + * + * <pre> + * 0ms 20ms 100ms + * PRIMITIVE_CLICK---PRIMITIVE_TICK-----------PRIMITIVE_THUD + * </pre> + * + * <p>A primitive will be dropped from the composition if it overlaps with previous ones. + */ + @FlaggedApi(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + public static final int DELAY_TYPE_RELATIVE_START_OFFSET = 1; private final ArrayList<VibrationEffectSegment> mSegments = new ArrayList<>(); private int mRepeatIndex = -1; @@ -1665,7 +1722,26 @@ public abstract class VibrationEffect implements Parcelable { @NonNull public Composition addPrimitive(@PrimitiveType int primitiveId, @FloatRange(from = 0f, to = 1f) float scale, @IntRange(from = 0) int delay) { - PrimitiveSegment primitive = new PrimitiveSegment(primitiveId, scale, delay); + return addPrimitive(primitiveId, scale, delay, PrimitiveSegment.DEFAULT_DELAY_TYPE); + } + + /** + * Add a haptic primitive to the end of the current composition. + * + * @param primitiveId The primitive to add + * @param scale The scale to apply to the intensity of the primitive. + * @param delay The amount of time in milliseconds to wait before playing this primitive, + * as defined by the given {@code delayType}. + * @param delayType The type of delay to be applied, e.g. a pause between last primitive and + * this one or a start offset. + * @return This {@link Composition} object to enable adding multiple elements in one chain. + */ + @FlaggedApi(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + @NonNull + public Composition addPrimitive(@PrimitiveType int primitiveId, + @FloatRange(from = 0f, to = 1f) float scale, @IntRange(from = 0) int delay, + @DelayType int delayType) { + PrimitiveSegment primitive = new PrimitiveSegment(primitiveId, scale, delay, delayType); primitive.validate(); return addSegment(primitive); } @@ -1733,6 +1809,20 @@ public abstract class VibrationEffect implements Parcelable { default -> Integer.toString(id); }; } + + /** + * Convert the delay type to a human readable string for debugging. + * @param type The delay type to convert + * @return The delay type in a human readable format. + * @hide + */ + public static String delayTypeToString(@DelayType int type) { + return switch (type) { + case DELAY_TYPE_PAUSE -> "PAUSE"; + case DELAY_TYPE_RELATIVE_START_OFFSET -> "START_OFFSET"; + default -> Integer.toString(type); + }; + } } /** @@ -1819,12 +1909,12 @@ public abstract class VibrationEffect implements Parcelable { * * <p>You can use the following APIs to obtain these limits: * <ul> - * <li>Maximum envelope control points: {@link Vibrator#getMaxEnvelopeEffectSize()}</li> + * <li>Maximum envelope control points: {@link VibratorEnvelopeEffectInfo#getMaxSize()} * <li>Minimum control point duration: - * {@link Vibrator#getMinEnvelopeEffectControlPointDurationMillis()}</li> + * {@link VibratorEnvelopeEffectInfo#getMinControlPointDurationMillis()} * <li>Maximum control point duration: - * {@link Vibrator#getMaxEnvelopeEffectControlPointDurationMillis()}</li> - * <li>Maximum total effect duration: {@link Vibrator#getMaxEnvelopeEffectDurationMillis()}</li> + * {@link VibratorEnvelopeEffectInfo#getMaxControlPointDurationMillis()} + * <li>Maximum total effect duration: {@link VibratorEnvelopeEffectInfo#getMaxDurationMillis()} * </ul> * * @see VibrationEffect#startWaveformEnvelope() diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java index 53f8a9267499..86209140ce51 100644 --- a/core/java/android/os/Vibrator.java +++ b/core/java/android/os/Vibrator.java @@ -35,6 +35,7 @@ import android.media.AudioAttributes; import android.os.vibrator.Flags; import android.os.vibrator.VendorVibrationSession; import android.os.vibrator.VibrationConfig; +import android.os.vibrator.VibratorEnvelopeEffectInfo; import android.os.vibrator.VibratorFrequencyProfile; import android.os.vibrator.VibratorFrequencyProfileLegacy; import android.util.Log; @@ -137,6 +138,9 @@ public abstract class Vibrator { @Nullable private volatile VibrationConfig mVibrationConfig; + private VibratorFrequencyProfile mVibratorFrequencyProfile; + private VibratorEnvelopeEffectInfo mVibratorEnvelopeEffectInfo; + /** * @hide to prevent subclassing from outside of the framework */ @@ -351,7 +355,11 @@ public abstract class Vibrator { return null; } - return new VibratorFrequencyProfile(frequencyProfile); + if (mVibratorFrequencyProfile == null) { + mVibratorFrequencyProfile = new VibratorFrequencyProfile(frequencyProfile); + } + + return mVibratorFrequencyProfile; } /** @@ -383,70 +391,28 @@ public abstract class Vibrator { } /** - * Retrieves the maximum duration supported for an envelope effect, in milliseconds. - * - * <p>If the device supports envelope effects (check {@link #areEnvelopeEffectsSupported}), - * this value will be positive. Devices with envelope effects capabilities guarantees a - * maximum duration equivalent to the product of {@link #getMaxEnvelopeEffectSize()} and - * {@link #getMaxEnvelopeEffectControlPointDurationMillis()}. If the device does not support - * envelope effects, this method will return 0. - * - * @return The maximum duration (in milliseconds) allowed for an envelope effect, or 0 if - * envelope effects are not supported. - */ - @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) - public int getMaxEnvelopeEffectDurationMillis() { - return getInfo().getMaxEnvelopeEffectDurationMillis(); - } - - /** - * Retrieves the maximum number of control points supported for an envelope effect. - * - * <p>If the device supports envelope effects (check {@link #areEnvelopeEffectsSupported}), - * this value will be positive. Devices with envelope effects capabilities guarantee support - * for a minimum of 16 control points. If the device does not support envelope effects, - * this method will return 0. + * Retrieves the vibrator's capabilities and limitations for envelope effects. * - * @return the maximum number of control points allowed for an envelope effect, or 0 if - * envelope effects are not supported. - */ - @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) - public int getMaxEnvelopeEffectSize() { - return getInfo().getMaxEnvelopeEffectSize(); - } - - /** - * Retrieves the minimum duration supported between two control points within an envelope - * effect, in milliseconds. + * <p>These parameters can be used with {@link VibrationEffect.WaveformEnvelopeBuilder} + * to create custom envelope effects. * - * <p>If the device supports envelope effects (check {@link #areEnvelopeEffectsSupported}), - * this value will be positive. Devices with envelope effects capabilities guarantee - * support for durations down to at least 20 milliseconds. If the device does - * not support envelope effects, this method will return 0. + * @return The vibrator's envelope effect information, or null if not supported. If this + * vibrator is a composite of multiple physical devices then this will return a profile + * supported in all devices, or null if the intersection is empty or not available. * - * @return the minimum allowed duration between two control points in an envelope effect, - * or 0 if envelope effects are not supported. + * @see VibrationEffect.WaveformEnvelopeBuilder */ @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) - public int getMinEnvelopeEffectControlPointDurationMillis() { - return getInfo().getMinEnvelopeEffectControlPointDurationMillis(); - } + @NonNull + public VibratorEnvelopeEffectInfo getEnvelopeEffectInfo() { + if (mVibratorEnvelopeEffectInfo == null) { + mVibratorEnvelopeEffectInfo = new VibratorEnvelopeEffectInfo( + getInfo().getMaxEnvelopeEffectSize(), + getInfo().getMinEnvelopeEffectControlPointDurationMillis(), + getInfo().getMaxEnvelopeEffectControlPointDurationMillis()); + } - /** - * Retrieves the maximum duration supported between two control points within an envelope - * effect, in milliseconds. - * - * <p>If the device supports envelope effects (check {@link #areEnvelopeEffectsSupported}), - * this value will be positive. Devices with envelope effects capabilities guarantee support - * for durations up to at least 1 second. If the device does not support envelope effects, - * this method will return 0. - * - * @return the maximum allowed duration between two control points in an envelope effect, - * or 0 if envelope effects are not supported. - */ - @FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) - public int getMaxEnvelopeEffectControlPointDurationMillis() { - return getInfo().getMaxEnvelopeEffectControlPointDurationMillis(); + return mVibratorEnvelopeEffectInfo; } /** diff --git a/core/java/android/os/VibratorInfo.java b/core/java/android/os/VibratorInfo.java index 9dec8673f019..84325a4ac70b 100644 --- a/core/java/android/os/VibratorInfo.java +++ b/core/java/android/os/VibratorInfo.java @@ -121,7 +121,7 @@ public class VibratorInfo implements Parcelable { * @param qFactor The vibrator quality factor. * @param frequencyProfileLegacy The description of the vibrator supported frequencies and max * amplitude mappings. - * @param frequencyProfile The description of the vibrator supported frequencies and + * @param frequencyProfile The description of the vibrator supported frequencies and * output acceleration mappings. * @param maxEnvelopeEffectSize The maximum number of control points supported for an * envelope effect. diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig index d9db28e0b3c3..095799cce646 100644 --- a/core/java/android/os/flags.aconfig +++ b/core/java/android/os/flags.aconfig @@ -148,6 +148,13 @@ flag { } flag { + name: "cpu_gpu_headrooms" + namespace: "game" + description: "Feature flag for adding CPU/GPU headroom API" + bug: "346604998" +} + +flag { name: "disallow_cellular_null_ciphers_restriction" namespace: "cellular_security" description: "Guards a new UserManager user restriction that admins can use to require cellular encryption on their managed devices." diff --git a/core/java/android/os/health/SystemHealthManager.java b/core/java/android/os/health/SystemHealthManager.java index deabfed365a6..4db9bc333e2b 100644 --- a/core/java/android/os/health/SystemHealthManager.java +++ b/core/java/android/os/health/SystemHealthManager.java @@ -17,6 +17,7 @@ package android.os.health; import android.annotation.FlaggedApi; +import android.annotation.FloatRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; @@ -25,6 +26,11 @@ import android.content.Context; import android.os.BatteryStats; import android.os.Build; import android.os.Bundle; +import android.os.CpuHeadroomParams; +import android.os.CpuHeadroomParamsInternal; +import android.os.GpuHeadroomParams; +import android.os.GpuHeadroomParamsInternal; +import android.os.IHintManager; import android.os.IPowerStatsService; import android.os.OutcomeReceiver; import android.os.PowerMonitor; @@ -68,6 +74,8 @@ public class SystemHealthManager { private final IBatteryStats mBatteryStats; @Nullable private final IPowerStatsService mPowerStats; + @Nullable + private final IHintManager mHintManager; private List<PowerMonitor> mPowerMonitorsInfo; private final Object mPowerMonitorsLock = new Object(); private static final long TAKE_UID_SNAPSHOT_TIMEOUT_MILLIS = 10_000; @@ -88,14 +96,111 @@ public class SystemHealthManager { public SystemHealthManager() { this(IBatteryStats.Stub.asInterface(ServiceManager.getService(BatteryStats.SERVICE_NAME)), IPowerStatsService.Stub.asInterface( - ServiceManager.getService(Context.POWER_STATS_SERVICE))); + ServiceManager.getService(Context.POWER_STATS_SERVICE)), + IHintManager.Stub.asInterface( + ServiceManager.getService(Context.PERFORMANCE_HINT_SERVICE))); } /** {@hide} */ public SystemHealthManager(@NonNull IBatteryStats batteryStats, - @Nullable IPowerStatsService powerStats) { + @Nullable IPowerStatsService powerStats, @Nullable IHintManager hintManager) { mBatteryStats = batteryStats; mPowerStats = powerStats; + mHintManager = hintManager; + } + + /** + * Provides an estimate of global available CPU headroom of the calling thread. + * <p> + * + * @param params params to customize the CPU headroom calculation, null to use default params. + * @return a single value a {@code Float.NaN} if it's temporarily unavailable. + * A valid value is ranged from [0, 100], where 0 indicates no more CPU resources can be + * granted. + * @throws UnsupportedOperationException if the API is unsupported or the request params can't + * be served. + */ + @FlaggedApi(android.os.Flags.FLAG_CPU_GPU_HEADROOMS) + public @FloatRange(from = 0f, to = 100f) float getCpuHeadroom( + @Nullable CpuHeadroomParams params) { + if (mHintManager == null) { + throw new UnsupportedOperationException(); + } + try { + return mHintManager.getCpuHeadroom( + params != null ? params.getInternal() : new CpuHeadroomParamsInternal())[0]; + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + + + /** + * Provides an estimate of global available GPU headroom of the device. + * <p> + * + * @param params params to customize the GPU headroom calculation, null to use default params. + * @return a single value headroom or a {@code Float.NaN} if it's temporarily unavailable. + * A valid value is ranged from [0, 100], where 0 indicates no more GPU resources can be + * granted. + * @throws UnsupportedOperationException if the API is unsupported or the request params can't + * be served. + */ + @FlaggedApi(android.os.Flags.FLAG_CPU_GPU_HEADROOMS) + public @FloatRange(from = 0f, to = 100f) float getGpuHeadroom( + @Nullable GpuHeadroomParams params) { + if (mHintManager == null) { + throw new UnsupportedOperationException(); + } + try { + return mHintManager.getGpuHeadroom( + params != null ? params.getInternal() : new GpuHeadroomParamsInternal()); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** + * Minimum polling interval for calling {@link #getCpuHeadroom(CpuHeadroomParams)} in + * milliseconds. + * <p> + * The {@link #getCpuHeadroom(CpuHeadroomParams)} API may return cached result if called more + * frequent than the interval. + * + * @throws UnsupportedOperationException if the API is unsupported. + */ + @FlaggedApi(android.os.Flags.FLAG_CPU_GPU_HEADROOMS) + public long getCpuHeadroomMinIntervalMillis() { + if (mHintManager == null) { + throw new UnsupportedOperationException(); + } + try { + return mHintManager.getCpuHeadroomMinIntervalMillis(); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** + * Minimum polling interval for calling {@link #getGpuHeadroom(GpuHeadroomParams)} in + * milliseconds. + * <p> + * The {@link #getGpuHeadroom(GpuHeadroomParams)} API may return cached result if called more + * frequent than the interval. + * + * @throws UnsupportedOperationException if the API is unsupported. + */ + @FlaggedApi(android.os.Flags.FLAG_CPU_GPU_HEADROOMS) + public long getGpuHeadroomMinIntervalMillis() { + if (mHintManager == null) { + throw new UnsupportedOperationException(); + } + try { + return mHintManager.getGpuHeadroomMinIntervalMillis(); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } } /** @@ -261,7 +366,7 @@ public class SystemHealthManager { mPowerMonitorsInfo = result; } if (executor != null) { - executor.execute(()-> onResult.accept(result)); + executor.execute(() -> onResult.accept(result)); } else { onResult.accept(result); } diff --git a/core/java/android/os/vibrator/PrimitiveSegment.java b/core/java/android/os/vibrator/PrimitiveSegment.java index 91653edd1ba5..889d735c1d39 100644 --- a/core/java/android/os/vibrator/PrimitiveSegment.java +++ b/core/java/android/os/vibrator/PrimitiveSegment.java @@ -26,6 +26,7 @@ import android.os.VibratorInfo; import com.android.internal.util.Preconditions; +import java.util.Locale; import java.util.Objects; /** @@ -43,19 +44,29 @@ public final class PrimitiveSegment extends VibrationEffectSegment { /** @hide */ public static final int DEFAULT_DELAY_MILLIS = 0; + /** @hide */ + public static final int DEFAULT_DELAY_TYPE = VibrationEffect.Composition.DELAY_TYPE_PAUSE; + private final int mPrimitiveId; private final float mScale; private final int mDelay; + private final int mDelayType; PrimitiveSegment(@NonNull Parcel in) { - this(in.readInt(), in.readFloat(), in.readInt()); + this(in.readInt(), in.readFloat(), in.readInt(), in.readInt()); } /** @hide */ public PrimitiveSegment(int id, float scale, int delay) { + this(id, scale, delay, DEFAULT_DELAY_TYPE); + } + + /** @hide */ + public PrimitiveSegment(int id, float scale, int delay, int delayType) { mPrimitiveId = id; mScale = scale; mDelay = delay; + mDelayType = delayType; } public int getPrimitiveId() { @@ -70,6 +81,11 @@ public final class PrimitiveSegment extends VibrationEffectSegment { return mDelay; } + /** @hide */ + public int getDelayType() { + return mDelayType; + } + @Override public long getDuration() { return -1; @@ -112,8 +128,7 @@ public final class PrimitiveSegment extends VibrationEffectSegment { if (Float.compare(mScale, newScale) == 0) { return this; } - - return new PrimitiveSegment(mPrimitiveId, newScale, mDelay); + return new PrimitiveSegment(mPrimitiveId, newScale, mDelay, mDelayType); } /** @hide */ @@ -124,8 +139,7 @@ public final class PrimitiveSegment extends VibrationEffectSegment { if (Float.compare(mScale, newScale) == 0) { return this; } - - return new PrimitiveSegment(mPrimitiveId, newScale, mDelay); + return new PrimitiveSegment(mPrimitiveId, newScale, mDelay, mDelayType); } /** @hide */ @@ -142,6 +156,7 @@ public final class PrimitiveSegment extends VibrationEffectSegment { VibrationEffect.Composition.PRIMITIVE_LOW_TICK, "primitiveId"); Preconditions.checkArgumentInRange(mScale, 0f, 1f, "scale"); VibrationEffectSegment.checkDurationArgument(mDelay, "delay"); + Preconditions.checkArgument(isValidDelayType(mDelayType), "delayType"); } @Override @@ -150,6 +165,7 @@ public final class PrimitiveSegment extends VibrationEffectSegment { dest.writeInt(mPrimitiveId); dest.writeFloat(mScale); dest.writeInt(mDelay); + dest.writeInt(mDelayType); } @Override @@ -163,14 +179,16 @@ public final class PrimitiveSegment extends VibrationEffectSegment { + "primitive=" + VibrationEffect.Composition.primitiveToString(mPrimitiveId) + ", scale=" + mScale + ", delay=" + mDelay + + ", delayType=" + VibrationEffect.Composition.delayTypeToString(mDelayType) + '}'; } /** @hide */ @Override public String toDebugString() { - return String.format("Primitive=%s(scale=%.2f, delay=%dms)", - VibrationEffect.Composition.primitiveToString(mPrimitiveId), mScale, mDelay); + return String.format(Locale.ROOT, "Primitive=%s(scale=%.2f, %s=%dms)", + VibrationEffect.Composition.primitiveToString(mPrimitiveId), mScale, + toDelayTypeDebugString(mDelayType), mDelay); } @Override @@ -180,12 +198,28 @@ public final class PrimitiveSegment extends VibrationEffectSegment { PrimitiveSegment that = (PrimitiveSegment) o; return mPrimitiveId == that.mPrimitiveId && Float.compare(that.mScale, mScale) == 0 - && mDelay == that.mDelay; + && mDelay == that.mDelay + && mDelayType == that.mDelayType; } @Override public int hashCode() { - return Objects.hash(mPrimitiveId, mScale, mDelay); + return Objects.hash(mPrimitiveId, mScale, mDelay, mDelayType); + } + + private static boolean isValidDelayType(int delayType) { + return switch (delayType) { + case VibrationEffect.Composition.DELAY_TYPE_PAUSE, + VibrationEffect.Composition.DELAY_TYPE_RELATIVE_START_OFFSET -> true; + default -> false; + }; + } + + private static String toDelayTypeDebugString(int delayType) { + return switch (delayType) { + case VibrationEffect.Composition.DELAY_TYPE_RELATIVE_START_OFFSET -> "startOffset"; + default -> "pause"; + }; } @NonNull diff --git a/core/java/android/os/vibrator/VibratorEnvelopeEffectInfo.java b/core/java/android/os/vibrator/VibratorEnvelopeEffectInfo.java new file mode 100644 index 000000000000..f2ad7a402b60 --- /dev/null +++ b/core/java/android/os/vibrator/VibratorEnvelopeEffectInfo.java @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os.vibrator; + +import android.annotation.FlaggedApi; +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.VibrationEffect; + +import java.util.Objects; + +/** + * Provides information about the vibrator hardware capabilities and limitations regarding + * waveform envelope effects. This includes: + * <ul> + * <li>Maximum number of control points supported. + * <li>Minimum and maximum duration for individual segments. + * <li>Maximum total duration for an envelope effect. + * </ul> + * + * <p>This information can be used to help construct waveform envelope effects with + * {@link VibrationEffect#startWaveformEnvelope()}. When designing these effects, it is also + * recommended to check the {@link VibratorFrequencyProfile} for information about the supported + * frequency range and the vibrator's output response. + * + * @see VibrationEffect#startWaveformEnvelope() + * @see VibratorFrequencyProfile + */ +@FlaggedApi(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) +public final class VibratorEnvelopeEffectInfo implements Parcelable { + private final int mMaxSize; + private final long mMinControlPointDurationMillis; + private final long mMaxControlPointDurationMillis; + + VibratorEnvelopeEffectInfo(Parcel in) { + mMaxSize = in.readInt(); + mMinControlPointDurationMillis = in.readLong(); + mMaxControlPointDurationMillis = in.readLong(); + } + + /** + * Default constructor. + * + * @param maxSize The maximum number of control points supported for an + * envelope effect. + * @param minControlPointDurationMillis The minimum duration supported between two control + * points within an envelope effect. + * @param maxControlPointDurationMillis The maximum duration supported between two control + * points within an envelope effect. + * @hide + */ + public VibratorEnvelopeEffectInfo(int maxSize, + long minControlPointDurationMillis, + long maxControlPointDurationMillis) { + mMaxSize = maxSize; + mMinControlPointDurationMillis = minControlPointDurationMillis; + mMaxControlPointDurationMillis = maxControlPointDurationMillis; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mMaxSize); + dest.writeLong(mMinControlPointDurationMillis); + dest.writeLong(mMaxControlPointDurationMillis); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof VibratorEnvelopeEffectInfo)) { + return false; + } + VibratorEnvelopeEffectInfo other = (VibratorEnvelopeEffectInfo) o; + return mMaxSize == other.mMaxSize + && mMinControlPointDurationMillis == other.mMinControlPointDurationMillis + && mMaxControlPointDurationMillis == other.mMaxControlPointDurationMillis; + } + + @Override + public int hashCode() { + return Objects.hash(mMaxSize, + mMinControlPointDurationMillis, + mMaxControlPointDurationMillis); + } + + @Override + public String toString() { + return "VibratorEnvelopeEffectInfo{" + + ", mMaxSize=" + mMaxSize + + ", mMinControlPointDurationMillis=" + mMinControlPointDurationMillis + + ", mMaxControlPointDurationMillis=" + mMaxControlPointDurationMillis + + '}'; + } + + @NonNull + public static final Creator<VibratorEnvelopeEffectInfo> CREATOR = + new Creator<VibratorEnvelopeEffectInfo>() { + @Override + public VibratorEnvelopeEffectInfo createFromParcel(Parcel in) { + return new VibratorEnvelopeEffectInfo(in); + } + + @Override + public VibratorEnvelopeEffectInfo[] newArray(int size) { + return new VibratorEnvelopeEffectInfo[size]; + } + }; + + /** + * Retrieves the maximum duration supported for an envelope effect, in milliseconds. + * + * <p>If the device supports envelope effects + * (check {@link android.os.VibratorInfo#areEnvelopeEffectsSupported}), this value will be + * positive. Devices with envelope effects capabilities guarantees a maximum duration + * equivalent to the product of {@link #getMaxSize()} and + * {@link #getMaxControlPointDurationMillis()}. If the device does not support + * envelope effects, this method will return 0. + * + * @return The maximum duration (in milliseconds) allowed for an envelope effect, or 0 if + * envelope effects are not supported. + */ + public long getMaxDurationMillis() { + return mMaxSize * mMaxControlPointDurationMillis; + } + + /** + * Retrieves the maximum number of control points supported for an envelope effect. + * + * <p>If the device supports envelope effects + * (check {@link android.os.VibratorInfo#areEnvelopeEffectsSupported}), this value will be + * positive. Devices with envelope effects capabilities guarantee support for a minimum of + * 16 control points. If the device does not support envelope effects, this method will + * return 0. + * + * @return the maximum number of control points allowed for an envelope effect, or 0 if + * envelope effects are not supported. + */ + public int getMaxSize() { + return mMaxSize; + } + + /** + * Retrieves the minimum duration supported between two control points within an envelope + * effect, in milliseconds. + * + * <p>If the device supports envelope effects + * (check {@link android.os.VibratorInfo#areEnvelopeEffectsSupported}), this value will be + * positive. Devices with envelope effects capabilities guarantee support for durations down + * to at least 20 milliseconds. If the device does not support envelope effects, + * this method will return 0. + * + * @return the minimum allowed duration between two control points in an envelope effect, + * or 0 if envelope effects are not supported. + */ + public long getMinControlPointDurationMillis() { + return mMinControlPointDurationMillis; + } + + /** + * Retrieves the maximum duration supported between two control points within an envelope + * effect, in milliseconds. + * + * <p>If the device supports envelope effects + * (check {@link android.os.VibratorInfo#areEnvelopeEffectsSupported}), this value will be + * positive. Devices with envelope effects capabilities guarantee support for durations up to + * at least 1 second. If the device does not support envelope effects, this method + * will return 0. + * + * @return the maximum allowed duration between two control points in an envelope effect, + * or 0 if envelope effects are not supported. + */ + public long getMaxControlPointDurationMillis() { + return mMaxControlPointDurationMillis; + } +} diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig index 33040be7c0fb..6264fbbbcb7a 100644 --- a/core/java/android/permission/flags.aconfig +++ b/core/java/android/permission/flags.aconfig @@ -391,3 +391,12 @@ flag{ description: "Batch noteOperations on the client to reduce binder call volume" bug: "366013082" } + +flag { + name: "supervision_role_permission_update_enabled" + is_fixed_read_only: true + is_exported: true + namespace: "supervision" + description: "This flag is used to enable all the remaining permissions required to the supervision role" + bug: "367333883" +}
\ No newline at end of file diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java index 6f3e3d8f0d3b..9fe0dda136d1 100644 --- a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java +++ b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java @@ -16,20 +16,30 @@ package android.security.advancedprotection; +import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; + import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.FlaggedApi; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SdkConstant; +import android.annotation.StringDef; import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.Context; +import android.content.Intent; import android.os.Binder; import android.os.RemoteException; import android.security.Flags; import android.util.Log; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.List; +import java.util.Objects; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; @@ -45,6 +55,139 @@ import java.util.concurrent.Executor; public final class AdvancedProtectionManager { private static final String TAG = "AdvancedProtectionMgr"; + /** + * Advanced Protection's identifier for setting policies or restrictions in DevicePolicyManager. + * + * @hide */ + public static final String ADVANCED_PROTECTION_SYSTEM_ENTITY = + "android.security.advancedprotection"; + + /** + * Feature identifier for disallowing 2G. + * + * @hide */ + @SystemApi + public static final String FEATURE_ID_DISALLOW_CELLULAR_2G = + "android.security.advancedprotection.feature_disallow_2g"; + + /** + * Feature identifier for disallowing install of unknown sources. + * + * @hide */ + @SystemApi + public static final String FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES = + "android.security.advancedprotection.feature_disallow_install_unknown_sources"; + + /** + * Feature identifier for disallowing USB. + * + * @hide */ + @SystemApi + public static final String FEATURE_ID_DISALLOW_USB = + "android.security.advancedprotection.feature_disallow_usb"; + + /** + * Feature identifier for disallowing WEP. + * + * @hide */ + @SystemApi + public static final String FEATURE_ID_DISALLOW_WEP = + "android.security.advancedprotection.feature_disallow_wep"; + + /** + * Feature identifier for enabling MTE. + * + * @hide */ + @SystemApi + public static final String FEATURE_ID_ENABLE_MTE = + "android.security.advancedprotection.feature_enable_mte"; + + /** @hide */ + @StringDef(prefix = { "FEATURE_ID_" }, value = { + FEATURE_ID_DISALLOW_CELLULAR_2G, + FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES, + FEATURE_ID_DISALLOW_USB, + FEATURE_ID_DISALLOW_WEP, + FEATURE_ID_ENABLE_MTE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface FeatureId {} + + private static final Set<String> ALL_FEATURE_IDS = Set.of( + FEATURE_ID_DISALLOW_CELLULAR_2G, + FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES, + FEATURE_ID_DISALLOW_USB, + FEATURE_ID_DISALLOW_WEP, + FEATURE_ID_ENABLE_MTE); + + /** + * Activity Action: Show a dialog with disabled by advanced protection message. + * <p> If a user action or a setting toggle is disabled by advanced protection, this dialog can + * be triggered to let the user know about this. + * <p> + * Input: + * <p>{@link #EXTRA_SUPPORT_DIALOG_FEATURE}: The feature identifier. + * <p>{@link #EXTRA_SUPPORT_DIALOG_TYPE}: The type of the action. + * <p> + * Output: Nothing. + * + * @hide */ + @SystemApi + @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION) + @FlaggedApi(android.security.Flags.FLAG_AAPM_API) + public static final String ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG = + "android.security.advancedprotection.action.SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG"; + + /** + * A string extra used with {@link #createSupportIntent} to identify the feature that needs to + * show a support dialog explaining it was disabled by advanced protection. + * + * @hide */ + @FeatureId + @SystemApi + public static final String EXTRA_SUPPORT_DIALOG_FEATURE = + "android.security.advancedprotection.extra.SUPPORT_DIALOG_FEATURE"; + + /** + * A string extra used with {@link #createSupportIntent} to identify the type of the action that + * needs to be explained in the support dialog. + * + * @hide */ + @SupportDialogType + @SystemApi + public static final String EXTRA_SUPPORT_DIALOG_TYPE = + "android.security.advancedprotection.extra.SUPPORT_DIALOG_TYPE"; + + /** + * Type for {@link #EXTRA_SUPPORT_DIALOG_TYPE} indicating a user performed an action that was + * blocked by advanced protection. + * + * @hide */ + @SystemApi + public static final String SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION = + "android.security.advancedprotection.type_blocked_interaction"; + + /** + * Type for {@link #EXTRA_SUPPORT_DIALOG_TYPE} indicating a user pressed on a setting toggle + * that was disabled by advanced protection. + * + * @hide */ + @SystemApi + public static final String SUPPORT_DIALOG_TYPE_DISABLED_SETTING = + "android.security.advancedprotection.type_disabled_setting"; + + /** @hide */ + @StringDef(prefix = { "SUPPORT_DIALOG_TYPE_" }, value = { + SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION, + SUPPORT_DIALOG_TYPE_DISABLED_SETTING, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SupportDialogType {} + + private static final Set<String> ALL_SUPPORT_DIALOG_TYPES = Set.of( + SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION, + SUPPORT_DIALOG_TYPE_DISABLED_SETTING); + private final ConcurrentHashMap<Callback, IAdvancedProtectionCallback> mCallbackMap = new ConcurrentHashMap<>(); @@ -164,6 +307,43 @@ public final class AdvancedProtectionManager { } /** + * Called by a feature to display a support dialog when a feature was disabled by advanced + * protection. This returns an intent that can be used with + * {@link Context#startActivity(Intent)} to display the dialog. + * + * <p>Note that this method doesn't check if the feature is actually disabled, i.e. this method + * will always return an intent. + * + * @param featureId The feature identifier. + * @param type The type of the feature describing the action that needs to be explained + * in the dialog or null for default explanation. + * @return Intent An intent to be used to start the dialog-activity that explains a feature was + * disabled by advanced protection. + * @hide + */ + @SystemApi + public @NonNull Intent createSupportIntent(@NonNull @FeatureId String featureId, + @Nullable @SupportDialogType String type) { + Objects.requireNonNull(featureId); + if (!ALL_FEATURE_IDS.contains(featureId)) { + throw new IllegalArgumentException(featureId + " is not a valid feature ID. See" + + " FEATURE_ID_* APIs."); + } + if (type != null && !ALL_SUPPORT_DIALOG_TYPES.contains(type)) { + throw new IllegalArgumentException(type + " is not a valid type. See" + + " SUPPORT_DIALOG_TYPE_* APIs."); + } + + Intent intent = new Intent(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(EXTRA_SUPPORT_DIALOG_FEATURE, featureId); + if (type != null) { + intent.putExtra(EXTRA_SUPPORT_DIALOG_TYPE, type); + } + return intent; + } + + /** * A callback class for monitoring changes to Advanced Protection state * * <p>To register a callback, implement this interface, and register it with diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index ce901217d700..09004b3dcf03 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -115,6 +115,14 @@ flag { } flag { + name: "protect_device_config_flags" + namespace: "psap_ai" + description: "Feature flag to limit adb shell to allowlisted flags" + bug: "364083026" + is_fixed_read_only: true +} + +flag { name: "keystore_grant_api" namespace: "hardware_backed_security" description: "Feature flag for exposing KeyStore grant APIs" diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig index 66e1f38621ae..6c92991ceff6 100644 --- a/core/java/android/security/responsible_apis_flags.aconfig +++ b/core/java/android/security/responsible_apis_flags.aconfig @@ -103,3 +103,10 @@ flag { description: "Applies intentMatchingFlags while matching intents to application components" bug: "364354494" } + +flag { + name: "aapm_feature_disable_install_unknown_sources" + namespace: "responsible_apis" + description: "Android Advanced Protection Mode Feature: Disable Install Unknown Sources" + bug: "369361373" +} diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java index ca20801852f1..be4629ab8178 100644 --- a/core/java/android/service/autofill/FillRequest.java +++ b/core/java/android/service/autofill/FillRequest.java @@ -16,6 +16,9 @@ package android.service.autofill; +import static android.service.autofill.Flags.FLAG_FILL_DIALOG_IMPROVEMENTS; + +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -100,7 +103,12 @@ public final class FillRequest implements Parcelable { /** * Indicates the request supports fill dialog presentation for the fields, the * system will send the request when the activity just started. + * + * @deprecated All requests would support fill dialog by default. + * Presence of this flag isn't needed. */ + @FlaggedApi(FLAG_FILL_DIALOG_IMPROVEMENTS) + @Deprecated public static final @RequestFlags int FLAG_SUPPORTS_FILL_DIALOG = 0x40; /** @@ -588,10 +596,10 @@ public final class FillRequest implements Parcelable { }; @DataClass.Generated( - time = 1701010178309L, + time = 1730991738865L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/service/autofill/FillRequest.java", - inputSignatures = "public static final @android.service.autofill.FillRequest.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PASSWORD_INPUT_TYPE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_VIEW_NOT_FOCUSED\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_SUPPORTS_FILL_DIALOG\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_IME_SHOWING\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_RESET_FILL_DIALOG_STATE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PCC_DETECTION\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_SCREEN_HAS_CREDMAN_FIELD\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_VIEW_REQUESTS_CREDMAN_SERVICE\npublic static final int INVALID_REQUEST_ID\nprivate final int mId\nprivate final @android.annotation.NonNull java.util.List<android.service.autofill.FillContext> mFillContexts\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mHints\nprivate final @android.annotation.Nullable android.os.Bundle mClientState\nprivate final @android.service.autofill.FillRequest.RequestFlags int mFlags\nprivate final @android.annotation.Nullable android.view.inputmethod.InlineSuggestionsRequest mInlineSuggestionsRequest\nprivate final @android.annotation.Nullable android.content.IntentSender mDelayedFillIntentSender\nprivate void onConstructed()\nclass FillRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)") + inputSignatures = "public static final @android.service.autofill.FillRequest.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PASSWORD_INPUT_TYPE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_VIEW_NOT_FOCUSED\npublic static final @android.annotation.FlaggedApi @java.lang.Deprecated @android.service.autofill.FillRequest.RequestFlags int FLAG_SUPPORTS_FILL_DIALOG\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_IME_SHOWING\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_RESET_FILL_DIALOG_STATE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PCC_DETECTION\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_SCREEN_HAS_CREDMAN_FIELD\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_VIEW_REQUESTS_CREDMAN_SERVICE\npublic static final int INVALID_REQUEST_ID\nprivate final int mId\nprivate final @android.annotation.NonNull java.util.List<android.service.autofill.FillContext> mFillContexts\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mHints\nprivate final @android.annotation.Nullable android.os.Bundle mClientState\nprivate final @android.service.autofill.FillRequest.RequestFlags int mFlags\nprivate final @android.annotation.Nullable android.view.inputmethod.InlineSuggestionsRequest mInlineSuggestionsRequest\nprivate final @android.annotation.Nullable android.content.IntentSender mDelayedFillIntentSender\nprivate void onConstructed()\nclass FillRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl index b384b66bf680..54710488cd67 100644 --- a/core/java/android/service/notification/INotificationListener.aidl +++ b/core/java/android/service/notification/INotificationListener.aidl @@ -34,10 +34,14 @@ oneway interface INotificationListener void onListenerConnected(in NotificationRankingUpdate update); void onNotificationPosted(in IStatusBarNotificationHolder notificationHolder, in NotificationRankingUpdate update); + void onNotificationPostedFull(in StatusBarNotification sbn, + in NotificationRankingUpdate update); void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons); // stats only for assistant void onNotificationRemoved(in IStatusBarNotificationHolder notificationHolder, in NotificationRankingUpdate update, in NotificationStats stats, int reason); + void onNotificationRemovedFull(in StatusBarNotification sbn, + in NotificationRankingUpdate update, in NotificationStats stats, int reason); void onNotificationRankingUpdate(in NotificationRankingUpdate update); void onListenerHintsChanged(int hints); void onInterruptionFilterChanged(int interruptionFilter); @@ -48,7 +52,9 @@ oneway interface INotificationListener // assistants only void onNotificationEnqueuedWithChannel(in IStatusBarNotificationHolder notificationHolder, in NotificationChannel channel, in NotificationRankingUpdate update); + void onNotificationEnqueuedWithChannelFull(in StatusBarNotification sbn, in NotificationChannel channel, in NotificationRankingUpdate update); void onNotificationSnoozedUntilContext(in IStatusBarNotificationHolder notificationHolder, String snoozeCriterionId); + void onNotificationSnoozedUntilContextFull(in StatusBarNotification sbn, String snoozeCriterionId); void onNotificationsSeen(in List<String> keys); void onPanelRevealed(int items); void onPanelHidden(); diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java index 091b25ab77ce..0a9276c34bfd 100644 --- a/core/java/android/service/notification/NotificationAssistantService.java +++ b/core/java/android/service/notification/NotificationAssistantService.java @@ -423,7 +423,12 @@ public abstract class NotificationAssistantService extends NotificationListenerS + "Error receiving StatusBarNotification"); return; } + onNotificationEnqueuedWithChannelFull(sbn, channel, update); + } + @Override + public void onNotificationEnqueuedWithChannelFull(StatusBarNotification sbn, + NotificationChannel channel, NotificationRankingUpdate update) { applyUpdateLocked(update); SomeArgs args = SomeArgs.obtain(); args.arg1 = sbn; @@ -447,7 +452,12 @@ public abstract class NotificationAssistantService extends NotificationListenerS Log.w(TAG, "onNotificationSnoozed: Error receiving StatusBarNotification"); return; } + onNotificationSnoozedUntilContextFull(sbn, snoozeCriterionId); + } + @Override + public void onNotificationSnoozedUntilContextFull( + StatusBarNotification sbn, String snoozeCriterionId) { SomeArgs args = SomeArgs.obtain(); args.arg1 = sbn; args.arg2 = snoozeCriterionId; diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index a8ab2115d97f..5d0ec73a024b 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -1490,7 +1490,12 @@ public abstract class NotificationListenerService extends Service { Log.w(TAG, "onNotificationPosted: Error receiving StatusBarNotification"); return; } + onNotificationPostedFull(sbn, update); + } + @Override + public void onNotificationPostedFull(StatusBarNotification sbn, + NotificationRankingUpdate update) { try { // convert icon metadata to legacy format for older clients createLegacyIconExtras(sbn.getNotification()); @@ -1518,7 +1523,6 @@ public abstract class NotificationListenerService extends Service { mRankingMap).sendToTarget(); } } - } @Override @@ -1531,6 +1535,12 @@ public abstract class NotificationListenerService extends Service { Log.w(TAG, "onNotificationRemoved: Error receiving StatusBarNotification", e); return; } + onNotificationRemovedFull(sbn, update, stats, reason); + } + + @Override + public void onNotificationRemovedFull(StatusBarNotification sbn, + NotificationRankingUpdate update, NotificationStats stats, int reason) { if (sbn == null) { Log.w(TAG, "onNotificationRemoved: Error receiving StatusBarNotification"); return; @@ -1592,6 +1602,14 @@ public abstract class NotificationListenerService extends Service { } @Override + public void onNotificationEnqueuedWithChannelFull( + StatusBarNotification sbn, NotificationChannel channel, + NotificationRankingUpdate update) + throws RemoteException { + // no-op in the listener + } + + @Override public void onNotificationsSeen(List<String> keys) throws RemoteException { // no-op in the listener @@ -1621,6 +1639,13 @@ public abstract class NotificationListenerService extends Service { } @Override + public void onNotificationSnoozedUntilContextFull( + StatusBarNotification sbn, String snoozeCriterionId) + throws RemoteException { + // no-op in the listener + } + + @Override public void onNotificationExpansionChanged( String key, boolean isUserAction, boolean isExpanded) { // no-op in the listener @@ -1688,8 +1713,6 @@ public abstract class NotificationListenerService extends Service { Bundle feedback) { // no-op in the listener } - - } /** diff --git a/core/java/android/service/quickaccesswallet/flags.aconfig b/core/java/android/service/quickaccesswallet/flags.aconfig new file mode 100644 index 000000000000..07311d5ffbe1 --- /dev/null +++ b/core/java/android/service/quickaccesswallet/flags.aconfig @@ -0,0 +1,9 @@ +package: "android.service.quickaccesswallet" +container: "system" + +flag { + name: "launch_wallet_option_on_power_double_tap" + namespace: "wallet_integrations" + description: "Option to launch the Wallet app on double-tap of the power button" + bug: "378469025" +}
\ No newline at end of file diff --git a/core/java/android/telephony/SubscriptionPlan.java b/core/java/android/telephony/SubscriptionPlan.java index 7b48a16c2227..4c59a8589df2 100644 --- a/core/java/android/telephony/SubscriptionPlan.java +++ b/core/java/android/telephony/SubscriptionPlan.java @@ -18,6 +18,7 @@ package android.telephony; import android.annotation.BytesLong; import android.annotation.CurrentTimeMillisLong; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -28,6 +29,7 @@ import android.telephony.Annotation.NetworkType; import android.util.Range; import android.util.RecurrenceRule; +import com.android.internal.telephony.flags.Flags; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; @@ -83,6 +85,33 @@ public final class SubscriptionPlan implements Parcelable { /** Value indicating a timestamp is unknown. */ public static final long TIME_UNKNOWN = -1; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "SUBSCRIPTION_STATUS_" }, value = { + SUBSCRIPTION_STATUS_UNKNOWN, + SUBSCRIPTION_STATUS_ACTIVE, + SUBSCRIPTION_STATUS_INACTIVE, + SUBSCRIPTION_STATUS_TRIAL, + SUBSCRIPTION_STATUS_SUSPENDED + }) + public @interface SubscriptionStatus {} + + /** Subscription status is unknown. */ + @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE) + public static final int SUBSCRIPTION_STATUS_UNKNOWN = 0; + /** Subscription is active. */ + @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE) + public static final int SUBSCRIPTION_STATUS_ACTIVE = 1; + /** Subscription is inactive. */ + @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE) + public static final int SUBSCRIPTION_STATUS_INACTIVE = 2; + /** Subscription is in a trial period. */ + @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE) + public static final int SUBSCRIPTION_STATUS_TRIAL = 3; + /** Subscription is suspended. */ + @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE) + public static final int SUBSCRIPTION_STATUS_SUSPENDED = 4; + private final RecurrenceRule cycleRule; private CharSequence title; private CharSequence summary; @@ -91,6 +120,7 @@ public final class SubscriptionPlan implements Parcelable { private long dataUsageBytes = BYTES_UNKNOWN; private long dataUsageTime = TIME_UNKNOWN; private @NetworkType int[] networkTypes; + private int mSubscriptionStatus = SUBSCRIPTION_STATUS_UNKNOWN; private SubscriptionPlan(RecurrenceRule cycleRule) { this.cycleRule = Preconditions.checkNotNull(cycleRule); @@ -107,6 +137,7 @@ public final class SubscriptionPlan implements Parcelable { dataUsageBytes = source.readLong(); dataUsageTime = source.readLong(); networkTypes = source.createIntArray(); + mSubscriptionStatus = source.readInt(); } @Override @@ -124,6 +155,7 @@ public final class SubscriptionPlan implements Parcelable { dest.writeLong(dataUsageBytes); dest.writeLong(dataUsageTime); dest.writeIntArray(networkTypes); + dest.writeInt(mSubscriptionStatus); } @Override @@ -137,13 +169,14 @@ public final class SubscriptionPlan implements Parcelable { .append(" dataUsageBytes=").append(dataUsageBytes) .append(" dataUsageTime=").append(dataUsageTime) .append(" networkTypes=").append(Arrays.toString(networkTypes)) + .append(" subscriptionStatus=").append(mSubscriptionStatus) .append("}").toString(); } @Override public int hashCode() { return Objects.hash(cycleRule, title, summary, dataLimitBytes, dataLimitBehavior, - dataUsageBytes, dataUsageTime, Arrays.hashCode(networkTypes)); + dataUsageBytes, dataUsageTime, Arrays.hashCode(networkTypes), mSubscriptionStatus); } @Override @@ -157,7 +190,8 @@ public final class SubscriptionPlan implements Parcelable { && dataLimitBehavior == other.dataLimitBehavior && dataUsageBytes == other.dataUsageBytes && dataUsageTime == other.dataUsageTime - && Arrays.equals(networkTypes, other.networkTypes); + && Arrays.equals(networkTypes, other.networkTypes) + && mSubscriptionStatus == other.mSubscriptionStatus; } return false; } @@ -179,6 +213,13 @@ public final class SubscriptionPlan implements Parcelable { return cycleRule; } + /** Return the end date of this plan, or null if no end date exists. */ + @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE) + public @Nullable ZonedDateTime getPlanEndDate() { + // ZonedDateTime is immutable, so no need to create a defensive copy. + return cycleRule.end; + } + /** Return the short title of this plan. */ public @Nullable CharSequence getTitle() { return title; @@ -238,6 +279,16 @@ public final class SubscriptionPlan implements Parcelable { } /** + * Returns the status of the subscription plan. + * + * @return The subscription status, or {@link #SUBSCRIPTION_STATUS_UNKNOWN} if not available. + */ + @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE) + public @SubscriptionStatus int getSubscriptionStatus() { + return mSubscriptionStatus; + } + + /** * Builder for a {@link SubscriptionPlan}. */ public static class Builder { @@ -382,5 +433,21 @@ public final class SubscriptionPlan implements Parcelable { TelephonyManager.getAllNetworkTypes().length); return this; } + + /** + * Set the subscription status. + * + * @param subscriptionStatus the current subscription status + */ + @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE) + public @NonNull Builder setSubscriptionStatus(@SubscriptionStatus int subscriptionStatus) { + if (subscriptionStatus < SUBSCRIPTION_STATUS_UNKNOWN + || subscriptionStatus > SUBSCRIPTION_STATUS_SUSPENDED) { + throw new IllegalArgumentException( + "Subscription status must be defined with a valid value"); + } + plan.mSubscriptionStatus = subscriptionStatus; + return this; + } } } diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java index ae12132d49a1..a42eece57eec 100644 --- a/core/java/android/text/Html.java +++ b/core/java/android/text/Html.java @@ -614,7 +614,7 @@ public class Html { if (style[j] instanceof TypefaceSpan) { String s = ((TypefaceSpan) style[j]).getFamily(); - if (s.equals("monospace")) { + if ("monospace".equals(s)) { out.append("</tt>"); } } diff --git a/core/java/android/text/TextFlags.java b/core/java/android/text/TextFlags.java deleted file mode 100644 index f69a333ff81f..000000000000 --- a/core/java/android/text/TextFlags.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.text; - -import android.annotation.NonNull; -import android.app.AppGlobals; - -/** - * Flags in the "text" namespace. - * - * TODO(nona): Remove this class. - * @hide - */ -public final class TextFlags { - - /** - * The name space of the "text" feature. - * - * This needs to move to DeviceConfig constant. - */ - public static final String NAMESPACE = "text"; - - /** - * Whether we use the new design of context menu. - */ - public static final String ENABLE_NEW_CONTEXT_MENU = - "TextEditing__enable_new_context_menu"; - - /** - * The key name used in app core settings for {@link #ENABLE_NEW_CONTEXT_MENU}. - */ - public static final String KEY_ENABLE_NEW_CONTEXT_MENU = "text__enable_new_context_menu"; - - /** - * Default value for the flag {@link #ENABLE_NEW_CONTEXT_MENU}. - */ - public static final boolean ENABLE_NEW_CONTEXT_MENU_DEFAULT = true; - - /** - * List of text flags to be transferred to the application process. - */ - public static final String[] TEXT_ACONFIGS_FLAGS = { - }; - - /** - * List of the default values of the text flags. - * - * The order must be the same to the TEXT_ACONFIG_FLAGS. - */ - public static final boolean[] TEXT_ACONFIG_DEFAULT_VALUE = { - }; - - /** - * Get a key for the feature flag. - */ - public static String getKeyForFlag(@NonNull String flag) { - return "text__" + flag; - } - - /** - * Return true if the feature flag is enabled. - */ - public static boolean isFeatureEnabled(@NonNull String flag) { - return AppGlobals.getIntCoreSetting( - getKeyForFlag(flag), 0 /* aconfig is false by default */) != 0; - } -} diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java index 174e0c8e6549..7ee0ff15c5ad 100644 --- a/core/java/android/util/ArrayMap.java +++ b/core/java/android/util/ArrayMap.java @@ -649,7 +649,6 @@ public final class ArrayMap<K, V> implements Map<K, V> { } if (index > 0 && mHashes[index-1] > hash) { RuntimeException e = new RuntimeException("here"); - e.fillInStackTrace(); Log.w(TAG, "New hash " + hash + " is before end of array hash " + mHashes[index-1] + " at index " + index + (DEBUG ? " key " + key : ""), e); diff --git a/core/java/android/util/ArraySet.java b/core/java/android/util/ArraySet.java index bfbca07ed256..1344bb9a73eb 100644 --- a/core/java/android/util/ArraySet.java +++ b/core/java/android/util/ArraySet.java @@ -526,7 +526,6 @@ public final class ArraySet<E> implements Collection<E>, Set<E> { // Cannot optimize since it would break the sorted order - fallback to add() if (DEBUG) { RuntimeException e = new RuntimeException("here"); - e.fillInStackTrace(); Log.w(TAG, "New hash " + hash + " is before end of array hash " + mHashes[index - 1] + " at index " + index, e); diff --git a/core/java/android/view/AttachedSurfaceControl.java b/core/java/android/view/AttachedSurfaceControl.java index 5406cf557410..264db4a604ff 100644 --- a/core/java/android/view/AttachedSurfaceControl.java +++ b/core/java/android/view/AttachedSurfaceControl.java @@ -15,9 +15,11 @@ */ package android.view; +import android.annotation.CallbackExecutor; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SuppressLint; import android.annotation.UiThread; import android.content.Context; import android.graphics.Rect; @@ -29,6 +31,8 @@ import android.window.SurfaceSyncGroup; import com.android.window.flags.Flags; +import java.util.concurrent.Executor; + /** * Provides an interface to the root-Surface of a View Hierarchy or Window. This * is used in combination with the {@link android.view.SurfaceControl} API to enable @@ -202,4 +206,21 @@ public interface AttachedSurfaceControl { throw new UnsupportedOperationException("The getInputTransferToken needs to be " + "implemented before making this call."); } + + /** + * Registers a {@link OnJankDataListener} to receive jank classification data about rendered + * frames. + * + * @param executor The executor on which the listener will be invoked. + * @param listener The listener to add. + * @return The {@link OnJankDataListenerRegistration} for the listener. + */ + @NonNull + @FlaggedApi(Flags.FLAG_JANK_API) + @SuppressLint("PairedRegistration") + default SurfaceControl.OnJankDataListenerRegistration registerOnJankDataListener( + @NonNull @CallbackExecutor Executor executor, + @NonNull SurfaceControl.OnJankDataListener listener) { + return SurfaceControl.OnJankDataListenerRegistration.NONE; + } } diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 7e247493e35c..5a71282dab0a 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -189,6 +189,11 @@ public final class Choreographer { @UnsupportedAppUsage private long mLastFrameTimeNanos; + // Keeps track of the last scheduled frame time without additional offsets + // added from buffer stuffing recovery. Used to compare timing of vsyncs to + // determine idle state. + private long mLastNoOffsetFrameTimeNanos; + /** DO NOT USE since this will not updated when screen refresh changes. */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "Use {@link android.view.Display#getRefreshRate} instead") @@ -203,6 +208,50 @@ public final class Choreographer { private final FrameData mFrameData = new FrameData(); private volatile boolean mInDoFrameCallback = false; + private static class BufferStuffingData { + enum RecoveryAction { + // No recovery + NONE, + // Recovery has started, adds a negative offset + OFFSET, + // Recovery has started, delays a frame to return buffer count + // back toward threshold. + DELAY_FRAME + } + // The maximum number of times frames will be delayed per buffer stuffing event. + // Since buffer stuffing can persist for several consecutive frames following the + // initial missed frame, we want to adjust the timeline with enough frame delays and + // offsets to return the queued buffer count back to threshold. + public static final int MAX_FRAME_DELAYS = 3; + + // Whether buffer stuffing recovery has begun. Recovery can only end + // when events are idle. + public boolean isRecovering = false; + + // The number of frames delayed so far during recovery. Used to compare with + // MAX_FRAME_DELAYS to safeguard against excessive frame delays during recovery. + // Also used as unique cookie for tracing. + public int numberFrameDelays = 0; + + // The number of additional frame delays scheduled during recovery to wait for the next + // vsync. These are scheduled when frame times appear to go backward or frames are + // being skipped due to FPSDivisor. + public int numberWaitsForNextVsync = 0; + + /** + * After buffer stuffing recovery has ended with a detected idle state, the + * recovery data trackers can be reset in preparation for any future + * stuffing events. + */ + public void reset() { + isRecovering = false; + numberFrameDelays = 0; + numberWaitsForNextVsync = 0; + } + } + + private final BufferStuffingData mBufferStuffingData = new BufferStuffingData(); + /** * Contains information about the current frame for jank-tracking, * mainly timings of key events along with a bit of metadata about @@ -850,13 +899,99 @@ public final class Choreographer { Trace.traceEnd(Trace.TRACE_TAG_VIEW); } + // Conducts logic for beginning or ending buffer stuffing recovery. + // Returns an enum for the recovery action that should be taken in doFrame(). + BufferStuffingData.RecoveryAction checkBufferStuffingRecovery(long frameTimeNanos, + DisplayEventReceiver.VsyncEventData vsyncEventData) { + // Canned animations can recover from buffer stuffing whenever more + // than 2 buffers are queued. + if (vsyncEventData.numberQueuedBuffers > 2) { + mBufferStuffingData.isRecovering = true; + // Intentional frame delay that can happen at most MAX_FRAME_DELAYS times per + // buffer stuffing event until the buffer count returns to threshold. The + // delayed frames are compensated for by the negative offsets added to the + // animation timestamps. + if (mBufferStuffingData.numberFrameDelays < mBufferStuffingData.MAX_FRAME_DELAYS) { + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.asyncTraceForTrackBegin( + Trace.TRACE_TAG_VIEW, "Buffer stuffing recovery", "Thread " + + android.os.Process.myTid() + ", recover frame #" + + mBufferStuffingData.numberFrameDelays, + mBufferStuffingData.numberFrameDelays); + } + mBufferStuffingData.numberFrameDelays++; + scheduleVsyncLocked(); + return BufferStuffingData.RecoveryAction.DELAY_FRAME; + } + } + + if (mBufferStuffingData.isRecovering) { + // Includes an additional expected frame delay from the natural scheduling + // of the next vsync event. + int totalFrameDelays = mBufferStuffingData.numberFrameDelays + + mBufferStuffingData.numberWaitsForNextVsync + 1; + long vsyncsSinceLastCallback = + (frameTimeNanos - mLastNoOffsetFrameTimeNanos) / mLastFrameIntervalNanos; + + // Detected idle state due to a longer inactive period since the last vsync callback + // than the total expected number of vsync frame delays. End buffer stuffing recovery. + // There are no frames to animate and offsets no longer need to be added + // since the idle state gives the animation a chance to catch up. + if (vsyncsSinceLastCallback > totalFrameDelays) { + if (DEBUG_JANK) { + Log.d(TAG, "End buffer stuffing recovery"); + } + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + for (int i = 0; i < mBufferStuffingData.numberFrameDelays; i++) { + Trace.asyncTraceForTrackEnd( + Trace.TRACE_TAG_VIEW, "Buffer stuffing recovery", i); + } + } + mBufferStuffingData.reset(); + + } else { + if (DEBUG_JANK) { + Log.d(TAG, "Adjust animation timeline with a negative offset"); + } + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.instantForTrack( + Trace.TRACE_TAG_VIEW, "Buffer stuffing recovery", + "Negative offset added to animation"); + } + return BufferStuffingData.RecoveryAction.OFFSET; + } + } + return BufferStuffingData.RecoveryAction.NONE; + } + void doFrame(long frameTimeNanos, int frame, DisplayEventReceiver.VsyncEventData vsyncEventData) { final long startNanos; final long frameIntervalNanos = vsyncEventData.frameInterval; boolean resynced = false; + long offsetFrameTimeNanos = frameTimeNanos; + + // Evaluate if buffer stuffing recovery needs to start or end, and + // what actions need to be taken for recovery. + switch (checkBufferStuffingRecovery(frameTimeNanos, vsyncEventData)) { + case NONE: + // Without buffer stuffing recovery, offsetFrameTimeNanos is + // synonymous with frameTimeNanos. + break; + case OFFSET: + // Add animation offset. Used to update frame timeline with + // offset before jitter is calculated. + offsetFrameTimeNanos = frameTimeNanos - frameIntervalNanos; + break; + case DELAY_FRAME: + // Intentional frame delay to help restore queued buffer count to threshold. + return; + default: + break; + } + try { - FrameTimeline timeline = mFrameData.update(frameTimeNanos, vsyncEventData); + FrameTimeline timeline = mFrameData.update(offsetFrameTimeNanos, vsyncEventData); if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Trace.traceBegin( Trace.TRACE_TAG_VIEW, "Choreographer#doFrame " + timeline.mVsyncId); @@ -867,15 +1002,18 @@ public final class Choreographer { traceMessage("Frame not scheduled"); return; // no work to do } + mLastNoOffsetFrameTimeNanos = frameTimeNanos; if (DEBUG_JANK && mDebugPrintNextFrameTimeDelta) { mDebugPrintNextFrameTimeDelta = false; Log.d(TAG, "Frame time delta: " - + ((frameTimeNanos - mLastFrameTimeNanos) * 0.000001f) + " ms"); + + ((offsetFrameTimeNanos - mLastFrameTimeNanos) * 0.000001f) + " ms"); } - long intendedFrameTimeNanos = frameTimeNanos; + long intendedFrameTimeNanos = offsetFrameTimeNanos; startNanos = System.nanoTime(); + // Calculating jitter involves using the original frame time without + // adjustments from buffer stuffing final long jitterNanos = startNanos - frameTimeNanos; if (jitterNanos >= frameIntervalNanos) { frameTimeNanos = startNanos; @@ -899,6 +1037,13 @@ public final class Choreographer { + " ms in the past."); } } + if (mBufferStuffingData.isRecovering) { + frameTimeNanos -= frameIntervalNanos; + if (DEBUG_JANK) { + Log.d(TAG, "Adjusted animation timeline with a negative offset after" + + " jitter calculation"); + } + } timeline = mFrameData.update( frameTimeNanos, mDisplayEventReceiver, jitterNanos); resynced = true; @@ -910,6 +1055,9 @@ public final class Choreographer { + "previously skipped frame. Waiting for next vsync."); } traceMessage("Frame time goes backward"); + if (mBufferStuffingData.isRecovering) { + mBufferStuffingData.numberWaitsForNextVsync++; + } scheduleVsyncLocked(); return; } @@ -918,6 +1066,9 @@ public final class Choreographer { long timeSinceVsync = frameTimeNanos - mLastFrameTimeNanos; if (timeSinceVsync < (frameIntervalNanos * mFPSDivisor) && timeSinceVsync > 0) { traceMessage("Frame skipped due to FPSDivisor"); + if (mBufferStuffingData.isRecovering) { + mBufferStuffingData.numberWaitsForNextVsync++; + } scheduleVsyncLocked(); return; } diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index fc7a65dbdc41..bb233d2711de 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -207,6 +207,8 @@ public abstract class DisplayEventReceiver { // reasonable timestamps. public int frameTimelinesLength = 1; + public int numberQueuedBuffers = 0; + VsyncEventData() { frameTimelines = new FrameTimeline[FRAME_TIMELINES_CAPACITY]; for (int i = 0; i < frameTimelines.length; i++) { @@ -217,11 +219,13 @@ public abstract class DisplayEventReceiver { // Called from native code. @SuppressWarnings("unused") VsyncEventData(FrameTimeline[] frameTimelines, int preferredFrameTimelineIndex, - int frameTimelinesLength, long frameInterval) { + int frameTimelinesLength, long frameInterval, + int numberQueuedBuffers) { this.frameTimelines = frameTimelines; this.preferredFrameTimelineIndex = preferredFrameTimelineIndex; this.frameTimelinesLength = frameTimelinesLength; this.frameInterval = frameInterval; + this.numberQueuedBuffers = numberQueuedBuffers; } void copyFrom(VsyncEventData other) { @@ -231,6 +235,7 @@ public abstract class DisplayEventReceiver { for (int i = 0; i < frameTimelines.length; i++) { frameTimelines[i].copyFrom(other.frameTimelines[i]); } + numberQueuedBuffers = other.numberQueuedBuffers; } public FrameTimeline preferredFrameTimeline() { diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java index 9e25a3e18c0c..58b2a67ec69e 100644 --- a/core/java/android/view/FrameMetrics.java +++ b/core/java/android/view/FrameMetrics.java @@ -18,10 +18,13 @@ package android.view; import static android.graphics.FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; +import com.android.window.flags.Flags; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -177,6 +180,16 @@ public final class FrameMetrics { public static final int DEADLINE = 13; /** + * Metric identifier for the frame's VSync identifier. + * <p> + * The id that corresponds to the chosen frame timeline, used to correlate a frame produced + * by HWUI with the timeline data from the compositor. + * </p> + */ + @FlaggedApi(Flags.FLAG_JANK_API) + public static final int FRAME_TIMELINE_VSYNC_ID = 14; + + /** * Identifiers for metrics available for each frame. * * {@see #getMetric(int)} @@ -337,7 +350,8 @@ public final class FrameMetrics { * @return the value of the metric or -1 if it is not available. */ public long getMetric(@Metric int id) { - if (id < UNKNOWN_DELAY_DURATION || id > DEADLINE) { + if (id < UNKNOWN_DELAY_DURATION + || id > (Flags.jankApi() ? FRAME_TIMELINE_VSYNC_ID : DEADLINE)) { return -1; } @@ -351,6 +365,8 @@ public final class FrameMetrics { return mTimingData[Index.INTENDED_VSYNC]; } else if (id == VSYNC_TIMESTAMP) { return mTimingData[Index.VSYNC]; + } else if (id == FRAME_TIMELINE_VSYNC_ID) { + return mTimingData[Index.FRAME_TIMELINE_VSYNC_ID]; } int durationsIdx = 2 * id; @@ -358,4 +374,3 @@ public final class FrameMetrics { - mTimingData[DURATIONS[durationsIdx]]; } } - diff --git a/core/java/android/view/HapticScrollFeedbackProvider.java b/core/java/android/view/HapticScrollFeedbackProvider.java index 0001176220b5..c3fb855eb1ff 100644 --- a/core/java/android/view/HapticScrollFeedbackProvider.java +++ b/core/java/android/view/HapticScrollFeedbackProvider.java @@ -16,6 +16,8 @@ package android.view; +import static android.view.flags.Flags.dynamicViewRotaryHapticsConfiguration; + import android.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; @@ -41,13 +43,8 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider { private final View mView; private final ViewConfiguration mViewConfig; - /** - * Flag to disable the logic in this class if the View-based scroll haptics implementation is - * enabled. If {@code false}, this class will continue to run despite the View's scroll - * haptics implementation being enabled. This value should be set to {@code true} when this - * class is directly used by the View class. - */ - private final boolean mDisabledIfViewPlaysScrollHaptics; + /** Whether or not this provider is being used directly by the View class. */ + private final boolean mIsFromView; // Info about the cause of the latest scroll event. @@ -65,17 +62,23 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider { private boolean mHapticScrollFeedbackEnabled = false; public HapticScrollFeedbackProvider(@NonNull View view) { - this(view, ViewConfiguration.get(view.getContext()), - /* disabledIfViewPlaysScrollHaptics= */ true); + this(view, ViewConfiguration.get(view.getContext()), /* isFromView= */ false); } /** @hide */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public HapticScrollFeedbackProvider( - View view, ViewConfiguration viewConfig, boolean disabledIfViewPlaysScrollHaptics) { + View view, ViewConfiguration viewConfig, boolean isFromView) { mView = view; mViewConfig = viewConfig; - mDisabledIfViewPlaysScrollHaptics = disabledIfViewPlaysScrollHaptics; + mIsFromView = isFromView; + if (dynamicViewRotaryHapticsConfiguration() && !isFromView) { + // Disable the View class's rotary scroll feedback logic if this provider is not being + // directly used by the View class. This is to avoid double rotary scroll feedback: + // one from the View class, and one from this provider instance (i.e. mute the View + // class's rotary feedback and enable this provider). + view.disableRotaryScrollFeedback(); + } } @Override @@ -151,7 +154,8 @@ public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider { mAxis = axis; mDeviceId = deviceId; - if (mDisabledIfViewPlaysScrollHaptics + if (!dynamicViewRotaryHapticsConfiguration() + && !mIsFromView && (source == InputDevice.SOURCE_ROTARY_ENCODER) && mViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) { mHapticScrollFeedbackEnabled = false; diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java index 97148969e17f..2d2f79d76008 100644 --- a/core/java/android/view/ImeFocusController.java +++ b/core/java/android/view/ImeFocusController.java @@ -23,6 +23,7 @@ import android.annotation.NonNull; import android.annotation.UiThread; import android.util.Log; import android.util.proto.ProtoOutputStream; +import android.view.inputmethod.Flags; import android.view.inputmethod.InputMethodManager; import com.android.internal.inputmethod.InputMethodDebug; @@ -150,6 +151,17 @@ public final class ImeFocusController { if (!mHasImeFocus || isInLocalFocusMode(windowAttribute)) { return InputMethodManager.DISPATCH_NOT_HANDLED; } + if (Flags.refactorInsetsController() && event instanceof KeyEvent keyEvent + && keyEvent.getKeyCode() == KeyEvent.KEYCODE_BACK) { + final var insetsController = mViewRootImpl.getInsetsController(); + if (insetsController.getAnimationType(WindowInsets.Type.ime()) + == InsetsController.ANIMATION_TYPE_HIDE + || insetsController.isPredictiveBackImeHideAnimInProgress()) { + // if there is an ongoing hide animation, the back event should not be dispatched + // to the IME. + return InputMethodManager.DISPATCH_NOT_HANDLED; + } + } final InputMethodManager imm = mViewRootImpl.mContext.getSystemService(InputMethodManager.class); if (imm == null) { diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 26ca813a9caa..b0813f3a98f6 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -1910,7 +1910,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mImeSourceConsumer.onWindowFocusLost(); } - @VisibleForTesting + /** Returns the current {@link AnimationType} of an {@link InsetsType}. */ + @VisibleForTesting(visibility = PACKAGE) public @AnimationType int getAnimationType(@InsetsType int type) { for (int i = mRunningAnimations.size() - 1; i >= 0; i--) { InsetsAnimationControlRunner control = mRunningAnimations.get(i).runner; diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 206c73756088..d56768d2db03 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -22,6 +22,7 @@ import static android.graphics.Matrix.MSKEW_X; import static android.graphics.Matrix.MSKEW_Y; import static android.graphics.Matrix.MTRANS_X; import static android.graphics.Matrix.MTRANS_Y; +import static android.view.flags.Flags.bufferStuffingRecovery; import static android.view.SurfaceControlProto.HASH_CODE; import static android.view.SurfaceControlProto.LAYER_ID; import static android.view.SurfaceControlProto.NAME; @@ -410,8 +411,19 @@ public final class SurfaceControl implements Parcelable { /** * Jank information to be fed back via {@link OnJankDataListener}. - * @hide + * <p> + * Apps may register a {@link OnJankDataListener} to get periodic batches of jank classification + * data from the (<a + * href="https://source.android.com/docs/core/graphics/surfaceflinger-windowmanagersystem"> + * composer</a> regarding rendered frames. A frame is considered janky if it did not reach the + * display at the intended time, typically due to missing a rendering deadline. This API + * provides information that can be used to identify the root cause of the scheduling misses + * and provides overall frame scheduling statistics. + * <p> + * This API can be used in conjunction with the {@link FrameMetrics} API by associating jank + * classification data with {@link FrameMetrics} data via the frame VSync id. */ + @FlaggedApi(Flags.FLAG_JANK_API) public static class JankData { /** @@ -428,29 +440,105 @@ public final class SurfaceControl implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface JankType {} - // No Jank + /** + * No jank detected, the frame was on time. + */ public static final int JANK_NONE = 0; - // Jank caused by the composer missing a deadline + + /** + * Bitmask for jank due to deadlines missed by the composer. + */ public static final int JANK_COMPOSER = 1 << 0; - // Jank caused by the application missing the composer's deadline + + /** + * Bitmask for jank due to deadlines missed by the application. + */ public static final int JANK_APPLICATION = 1 << 1; - // Jank due to other unknown reasons + + /** + * Bitmask for jank due to deadlines missed by other system components. + */ public static final int JANK_OTHER = 1 << 2; + private final long mFrameVsyncId; + private final @JankType int mJankType; + private final long mFrameIntervalNs; + private final long mScheduledAppFrameTimeNs; + private final long mActualAppFrameTimeNs; + + /** + * @hide + */ public JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs, long scheduledAppFrameTimeNs, long actualAppFrameTimeNs) { - this.frameVsyncId = frameVsyncId; - this.jankType = jankType; - this.frameIntervalNs = frameIntervalNs; - this.scheduledAppFrameTimeNs = scheduledAppFrameTimeNs; - this.actualAppFrameTimeNs = actualAppFrameTimeNs; - } - - public final long frameVsyncId; - public final @JankType int jankType; - public final long frameIntervalNs; - public final long scheduledAppFrameTimeNs; - public final long actualAppFrameTimeNs; + mFrameVsyncId = frameVsyncId; + mJankType = jankType; + mFrameIntervalNs = frameIntervalNs; + mScheduledAppFrameTimeNs = scheduledAppFrameTimeNs; + mActualAppFrameTimeNs = actualAppFrameTimeNs; + } + + /** + * Returns the id of the frame for this jank classification. + * + * @see FrameMetrics#FRAME_TIMELINE_VSYNC_ID + * @see Choreographer.FrameTimeline#getVsyncId + * @see Transaction#setFrameTimeline + * @return the frame id + */ + public long getVsyncId() { + return mFrameVsyncId; + } + + /** + * Returns the bitmask indicating the types of jank observed. + * + * @return the jank type bitmask + */ + public @JankType int getJankType() { + return mJankType; + } + + /** + * Returns the time between frame VSyncs in nanoseconds. + * + * @return the frame interval in ns + * @hide + */ + public long getFrameIntervalNanos() { + return mFrameIntervalNs; + } + + /** + * Returns the duration in nanoseconds the application was scheduled to use to render this + * frame. + * <p> + * Note that this may be higher than the frame interval to allow for CPU/GPU + * parallelization of work. + * + * @return scheduled app time in ns + */ + public long getScheduledAppFrameTimeNanos() { + return mScheduledAppFrameTimeNs; + } + + /** + * Returns the actual time in nanoseconds taken by the application to render this frame. + * + * @return the actual app time in ns + */ + public long getActualAppFrameTimeNanos() { + return mActualAppFrameTimeNs; + } + + @Override + public String toString() { + return "JankData{vsync=" + mFrameVsyncId + + ", jankType=0x" + Integer.toHexString(mJankType) + + ", frameInterval=" + mFrameIntervalNs + "ns" + + ", scheduledAppTime=" + mScheduledAppFrameTimeNs + "ns" + + ", actualAppTime=" + mActualAppFrameTimeNs + "ns}"; + } } /** @@ -458,12 +546,13 @@ public final class SurfaceControl implements Parcelable { * surface. * * @see JankData - * @see #addJankDataListener - * @hide + * @see #addOnJankDataListener */ + @FlaggedApi(Flags.FLAG_JANK_API) public interface OnJankDataListener { /** - * Called when new jank classifications are available. + * Called when new jank classifications are available. The listener is invoked out of band + * of the rendered frames with jank classification data for a batch of frames. */ void onJankDataAvailable(@NonNull List<JankData> jankData); @@ -471,9 +560,22 @@ public final class SurfaceControl implements Parcelable { /** * Handle to a registered {@link OnJankDatalistener}. - * @hide */ + @FlaggedApi(Flags.FLAG_JANK_API) public static class OnJankDataListenerRegistration { + /** @hide */ + public static final OnJankDataListenerRegistration NONE = + new OnJankDataListenerRegistration() { + @Override + public void flush() {} + + @Override + public void removeAfter(long afterVsync) {} + + @Override + public void release() {} + }; + private final long mNativeObject; private static final NativeAllocationRegistry sRegistry = @@ -484,6 +586,11 @@ public final class SurfaceControl implements Parcelable { private final Runnable mFreeNativeResources; private boolean mRemoved = false; + private OnJankDataListenerRegistration() { + mNativeObject = 0; + mFreeNativeResources = () -> {}; + } + OnJankDataListenerRegistration(SurfaceControl surface, OnJankDataListener listener) { mNativeObject = nativeCreateJankDataListenerWrapper(surface.mNativeObject, listener); mFreeNativeResources = (mNativeObject == 0) ? () -> {} : @@ -499,10 +606,17 @@ public final class SurfaceControl implements Parcelable { } /** - * Request the removal of the registered listener after the VSync with the provided ID. Use - * a value <= 0 for afterVsync to remove the listener immediately. The given listener will - * not be removed before the given VSync, but may still reveive data for frames past the - * provided VSync. + * Schedule the removal of the registered listener after the frame with the provided id. + * <p> + * Because jank classification is only possible after frames have been displayed, the + * callbacks are always delayed. To ensure receipt of all jank classification data, an + * application can schedule the removal to happen no sooner than after the data for the + * frame with the provided id has been provided. + * <p> + * Use a value <= 0 for afterVsync to remove the listener immediately, ensuring no future + * callbacks. + * + * @param afterVsync the id of the Vsync after which to remove the listener */ public void removeAfter(long afterVsync) { mRemoved = true; @@ -511,6 +625,7 @@ public final class SurfaceControl implements Parcelable { /** * Free the native resources associated with the listener registration. + * @hide */ public void release() { if (!mRemoved) { @@ -663,6 +778,13 @@ public final class SurfaceControl implements Parcelable { public static final int CAN_OCCLUDE_PRESENTATION = 0x00001000; /** + * Indicates that the SurfaceControl should recover from buffer stuffing when + * possible. This is the case when the SurfaceControl is a ViewRootImpl. + * @hide + */ + public static final int RECOVERABLE_FROM_BUFFER_STUFFING = 0x00002000; + + /** * Surface creation flag: Creates a surface where color components are interpreted * as "non pre-multiplied" by their alpha channel. Of course this flag is * meaningless for surfaces without an alpha channel. By default @@ -4444,14 +4566,31 @@ public final class SurfaceControl implements Parcelable { return this; } - /** @hide */ + /** + * Sets the Luts for the layer. + * + * <p> The function also allows to clear previously applied lut(s). To do this, + * set the displayluts to be either {@code nullptr} or + * an empty {@link android.hardware.DisplayLuts} instance. + * + * @param sc The SurfaceControl to update + * + * @param displayLuts The selected Lut(s) + * + * @return this + * @see DisplayLuts + */ + @FlaggedApi(android.hardware.flags.Flags.FLAG_LUTS_API) public @NonNull Transaction setLuts(@NonNull SurfaceControl sc, - @NonNull DisplayLuts displayLuts) { + @Nullable DisplayLuts displayLuts) { checkPreconditions(sc); - - nativeSetLuts(mNativeObject, sc.mNativeObject, displayLuts.getLutBuffers(), - displayLuts.getOffsets(), displayLuts.getLutDimensions(), - displayLuts.getLutSizes(), displayLuts.getLutSamplingKeys()); + if (displayLuts != null && displayLuts.valid()) { + nativeSetLuts(mNativeObject, sc.mNativeObject, displayLuts.getLutBuffers(), + displayLuts.getOffsets(), displayLuts.getLutDimensions(), + displayLuts.getLutSizes(), displayLuts.getLutSamplingKeys()); + } else { + nativeSetLuts(mNativeObject, sc.mNativeObject, null, null, null, null, null); + } return this; } @@ -4867,6 +5006,23 @@ public final class SurfaceControl implements Parcelable { nativeSetDesiredPresentTimeNanos(mNativeObject, desiredPresentTimeNanos); return this; } + + /** + * Specifies that the SurfaceControl is a buffer producer that should recover from buffer + * stuffing, meaning that the SurfaceControl is a ViewRootImpl. + * + * @hide + */ + @NonNull + public Transaction setRecoverableFromBufferStuffing(@NonNull SurfaceControl sc) { + if (bufferStuffingRecovery()) { + checkPreconditions(sc); + nativeSetFlags(mNativeObject, sc.mNativeObject, RECOVERABLE_FROM_BUFFER_STUFFING, + RECOVERABLE_FROM_BUFFER_STUFFING); + } + return this; + } + /** * Writes the transaction to parcel, clearing the transaction as if it had been applied so * it can be used to store future transactions. It's the responsibility of the parcel diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index c71bf4be308c..049189f8af8d 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -16754,9 +16754,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_DETERMINED; } } - final boolean processForRotaryScrollHaptics = - isRotaryEncoderEvent && ((mPrivateFlags4 & PFLAG4_ROTARY_HAPTICS_ENABLED) != 0); - if (processForRotaryScrollHaptics) { + if (isRotaryEncoderEvent && ((mPrivateFlags4 & PFLAG4_ROTARY_HAPTICS_ENABLED) != 0)) { mPrivateFlags4 &= ~PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT; mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT; } @@ -16773,7 +16771,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Process scroll haptics after `onGenericMotionEvent`, since that's where scrolling usually // happens. Some views may return false from `onGenericMotionEvent` even if they have done // scrolling, so disregard the return value when processing for scroll haptics. - if (processForRotaryScrollHaptics) { + // Check for `PFLAG4_ROTARY_HAPTICS_ENABLED` again, because the View implementation may + // call `disableRotaryScrollFeedback` in `onGenericMotionEvent`, which could change the + // value of `PFLAG4_ROTARY_HAPTICS_ENABLED`. + if (isRotaryEncoderEvent && ((mPrivateFlags4 & PFLAG4_ROTARY_HAPTICS_ENABLED) != 0)) { if ((mPrivateFlags4 & PFLAG4_ROTARY_HAPTICS_SCROLL_SINCE_LAST_ROTARY_INPUT) != 0) { doRotaryProgressForScrollHaptics(event); } else { @@ -18716,7 +18717,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private HapticScrollFeedbackProvider getScrollFeedbackProvider() { if (mScrollFeedbackProvider == null) { mScrollFeedbackProvider = new HapticScrollFeedbackProvider(this, - ViewConfiguration.get(mContext), /* disabledIfViewPlaysScrollHaptics= */ false); + ViewConfiguration.get(mContext), /* isFromView= */ true); } return mScrollFeedbackProvider; } @@ -18746,6 +18747,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Disables the rotary scroll feedback implementation of the View class. + * + * <p>Note that this does NOT disable all rotary scroll feedback; it just disables the logic + * implemented within the View class. The child implementation of the View may implement its own + * rotary scroll feedback logic or use {@link ScrollFeedbackProvider} to generate rotary scroll + * feedback. + */ + void disableRotaryScrollFeedback() { + // Force set PFLAG4_ROTARY_HAPTICS_DETERMINED to avoid recalculating + // PFLAG4_ROTARY_HAPTICS_ENABLED under any circumstance. + mPrivateFlags4 |= PFLAG4_ROTARY_HAPTICS_DETERMINED; + mPrivateFlags4 &= ~PFLAG4_ROTARY_HAPTICS_ENABLED; + } + + /** * This is called in response to an internal scroll in this view (i.e., the * view scrolled its own contents). This is typically as a result of * {@link #scrollBy(int, int)} or {@link #scrollTo(int, int)} having been diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 75d2da1b70e4..e50662adc3f1 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -140,6 +140,8 @@ import android.accessibilityservice.AccessibilityService; import android.animation.AnimationHandler; import android.animation.LayoutTransition; import android.annotation.AnyThread; +import android.annotation.CallbackExecutor; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; @@ -1250,7 +1252,6 @@ public final class ViewRootImpl implements ViewParent, mExtraDisplayListenerLogging = !TextUtils.isEmpty(name) && name.equals(mBasePackageName); mThread = Thread.currentThread(); mLocation = new WindowLeaked(null); - mLocation.fillInStackTrace(); mWidth = -1; mHeight = -1; mDirty = new Rect(); @@ -2758,6 +2759,9 @@ public final class ViewRootImpl implements ViewParent, // Only call transferFrom if the surface has changed to prevent inc the generation ID and // causing EGL resources to be recreated. mSurface.transferFrom(blastSurface); + + // Since the SurfaceControl is a VRI, indicate that it can recover from buffer stuffing. + mTransaction.setRecoverableFromBufferStuffing(mSurfaceControl).applyAsyncUnsafe(); } private void setBoundsLayerCrop(Transaction t) { @@ -11897,6 +11901,20 @@ public final class ViewRootImpl implements ViewParent, } /** + * {@inheritDoc} + */ + @NonNull + @Override + @FlaggedApi(com.android.window.flags.Flags.FLAG_JANK_API) + public SurfaceControl.OnJankDataListenerRegistration registerOnJankDataListener( + @NonNull @CallbackExecutor Executor executor, + @NonNull SurfaceControl.OnJankDataListener listener) { + SurfaceControl.OnJankDataListener wrapped = (data) -> + executor.execute(() -> listener.onJankDataAvailable(data)); + return mSurfaceControl.addOnJankDataListener(wrapped); + } + + /** * Class for managing the accessibility interaction connection * based on the global accessibility state. */ diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 1a45939f65b6..52c5af8889ec 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -25,12 +25,14 @@ import static android.service.autofill.FillRequest.FLAG_SCREEN_HAS_CREDMAN_FIELD import static android.service.autofill.FillRequest.FLAG_SUPPORTS_FILL_DIALOG; import static android.service.autofill.FillRequest.FLAG_VIEW_NOT_FOCUSED; import static android.service.autofill.FillRequest.FLAG_VIEW_REQUESTS_CREDMAN_SERVICE; +import static android.service.autofill.Flags.FLAG_FILL_DIALOG_IMPROVEMENTS; import static android.view.ContentInfo.SOURCE_AUTOFILL; import static android.view.autofill.Helper.sDebug; import static android.view.autofill.Helper.sVerbose; import static android.view.autofill.Helper.toList; import android.accessibilityservice.AccessibilityServiceInfo; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -1607,7 +1609,12 @@ public final class AutofillManager { * the virtual view in the host view. * * @throws IllegalArgumentException if the {@code infos} was empty + * + * @deprecated This function will not do anything. Showing fill dialog is now fully controlled + * by the framework and the autofill provider. */ + @FlaggedApi(FLAG_FILL_DIALOG_IMPROVEMENTS) + @Deprecated public void notifyVirtualViewsReady( @NonNull View view, @NonNull SparseArray<VirtualViewFillInfo> infos) { Objects.requireNonNull(infos); @@ -4034,8 +4041,13 @@ public final class AutofillManager { * receiving a focus event. The autofill suggestions shown will include content for * related views as well. * @return {@code true} if the autofill dialog is being shown + * + * @deprecated This function will not do anything. Showing fill dialog is now fully controlled + * by the framework and the autofill provider. */ // TODO(b/210926084): Consider whether to include the one-time show logic within this method. + @FlaggedApi(FLAG_FILL_DIALOG_IMPROVEMENTS) + @Deprecated public boolean showAutofillDialog(@NonNull View view) { Objects.requireNonNull(view); if (shouldShowAutofillDialog(view, view.getAutofillId())) { @@ -4073,7 +4085,12 @@ public final class AutofillManager { * suggestions. * @param virtualId id identifying the virtual view inside the host view. * @return {@code true} if the autofill dialog is being shown + * + * @deprecated This function will not do anything. Showing fill dialog is now fully controlled + * by the framework and the autofill provider. */ + @FlaggedApi(FLAG_FILL_DIALOG_IMPROVEMENTS) + @Deprecated public boolean showAutofillDialog(@NonNull View view, int virtualId) { Objects.requireNonNull(view); if (shouldShowAutofillDialog(view, getAutofillId(view, virtualId))) { diff --git a/core/java/android/view/flags/scroll_feedback_flags.aconfig b/core/java/android/view/flags/scroll_feedback_flags.aconfig index 658aa29a3cc6..b180e58cbe49 100644 --- a/core/java/android/view/flags/scroll_feedback_flags.aconfig +++ b/core/java/android/view/flags/scroll_feedback_flags.aconfig @@ -23,3 +23,10 @@ flag { bug: "331830899" is_fixed_read_only: true } + +flag { + namespace: "wear_frameworks" + name: "dynamic_view_rotary_haptics_configuration" + description: "Whether ScrollFeedbackProvider dynamically disables View-based rotary haptics." + bug: "377998870 " +} diff --git a/core/java/android/view/flags/view_flags.aconfig b/core/java/android/view/flags/view_flags.aconfig index 1b86f96d7eb7..3b6343e7c4ae 100644 --- a/core/java/android/view/flags/view_flags.aconfig +++ b/core/java/android/view/flags/view_flags.aconfig @@ -132,4 +132,12 @@ flag { description: "Use refactored round scrollbar." bug: "333417898" is_fixed_read_only: true +} + +flag { + name: "buffer_stuffing_recovery" + namespace: "window_surfaces" + description: "Recover from buffer stuffing when SurfaceFlinger misses a frame" + bug: "294922229" + is_fixed_read_only: true }
\ No newline at end of file diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java index fb3e0831fdc9..afe195c48b01 100644 --- a/core/java/android/view/inputmethod/EditorInfo.java +++ b/core/java/android/view/inputmethod/EditorInfo.java @@ -24,6 +24,7 @@ import static android.view.inputmethod.EditorInfoProto.PACKAGE_NAME; import static android.view.inputmethod.EditorInfoProto.PRIVATE_IME_OPTIONS; import static android.view.inputmethod.EditorInfoProto.TARGET_INPUT_METHOD_USER_ID; import static android.view.inputmethod.Flags.FLAG_EDITORINFO_HANDWRITING_ENABLED; +import static android.view.inputmethod.Flags.FLAG_PUBLIC_AUTOFILL_ID_IN_EDITORINFO; import android.annotation.FlaggedApi; import android.annotation.IntDef; @@ -470,12 +471,10 @@ public class EditorInfo implements InputType, Parcelable { public String packageName; /** - * Autofill Id for the field that's currently on focus. - * - * <p> Marked as hide since it's only used by framework.</p> - * @hide + * Autofill Id for the field that's currently on focus. See link {@link AutofillId} for more + * details. It is set by {@link View#getAutofillId()} */ - public AutofillId autofillId; + private AutofillId autofillId; /** * Identifier for the editor's field. This is optional, and may be @@ -524,7 +523,6 @@ public class EditorInfo implements InputType, Parcelable { @Nullable public LocaleList hintLocales = null; - /** * List of acceptable MIME types for * {@link InputConnection#commitContent(InputContentInfo, int, Bundle)}. @@ -759,6 +757,30 @@ public class EditorInfo implements InputType, Parcelable { return mIsStylusHandwritingEnabled; } + private boolean mWritingToolsEnabled = true; + + /** + * Returns {@code true} when an {@code Editor} has writing tools enabled. + * {@code true} by default for all editors. Toolkits can optionally disable them where not + * relevant e.g. passwords, number input, etc. + * @see #setWritingToolsEnabled(boolean) + */ + @FlaggedApi(Flags.FLAG_WRITING_TOOLS) + public boolean isWritingToolsEnabled() { + return mWritingToolsEnabled; + } + + /** + * Set {@code false} if {@code Editor} opts-out of writing tools, that enable IMEs to replace + * text with generative AI text. + * @param enabled set {@code true} to enabled or {@code false to disable} support. + * @see #isWritingToolsEnabled() + */ + @FlaggedApi(Flags.FLAG_WRITING_TOOLS) + public void setWritingToolsEnabled(boolean enabled) { + mWritingToolsEnabled = enabled; + } + /** * If not {@code null}, this editor needs to talk to IMEs that run for the specified user, no * matter what user ID the calling process has. @@ -1200,6 +1222,28 @@ public class EditorInfo implements InputType, Parcelable { } /** + * Returns the {@link AutofillId} of the view that this {@link EditorInfo} is associated with. + * The value is filled in with the result of {@link android.view.View#getAutofillId() + * View.getAutofillId()} on the view that is being edited. + * + * Note: For virtual view(e.g. Compose or Webview), default behavior is the autofillId is the id + * of the container view, unless the virtual view provider sets the virtual id when the + * InputMethodManager calls {@link android.view.View#onCreateInputConnection()} on the container + * view. + */ + @FlaggedApi(FLAG_PUBLIC_AUTOFILL_ID_IN_EDITORINFO) + @Nullable + public AutofillId getAutofillId() { + return autofillId; + } + + /** Sets the {@link AutofillId} of the view that this {@link EditorInfo} is associated with. */ + @FlaggedApi(FLAG_PUBLIC_AUTOFILL_ID_IN_EDITORINFO) + public void setAutofillId(@Nullable AutofillId autofillId) { + this.autofillId = autofillId; + } + + /** * Export the state of {@link EditorInfo} into a protocol buffer output stream. * * @param proto Stream to write the state to @@ -1255,6 +1299,7 @@ public class EditorInfo implements InputType, Parcelable { + InputMethodDebug.handwritingGestureTypeFlagsToString( mSupportedHandwritingGesturePreviewTypes)); pw.println(prefix + "isStylusHandwritingEnabled=" + mIsStylusHandwritingEnabled); + pw.println(prefix + "writingToolsEnabled=" + mWritingToolsEnabled); pw.println(prefix + "contentMimeTypes=" + Arrays.toString(contentMimeTypes)); if (targetInputMethodUser != null) { pw.println(prefix + "targetInputMethodUserId=" + targetInputMethodUser.getIdentifier()); @@ -1335,6 +1380,7 @@ public class EditorInfo implements InputType, Parcelable { } dest.writeStringArray(contentMimeTypes); UserHandle.writeToParcel(targetInputMethodUser, dest); + dest.writeBoolean(mWritingToolsEnabled); } /** @@ -1375,6 +1421,7 @@ public class EditorInfo implements InputType, Parcelable { res.hintLocales = hintLocales.isEmpty() ? null : hintLocales; res.contentMimeTypes = source.readStringArray(); res.targetInputMethodUser = UserHandle.readFromParcel(source); + res.mWritingToolsEnabled = source.readBoolean(); return res; } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 73f9d9fc23dc..6303c7637a59 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -2471,6 +2471,11 @@ public final class InputMethodManager { return; } + if (Flags.refactorInsetsController()) { + showSoftInput(rootView, statsToken, flags, resultReceiver, reason); + return; + } + ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED); // Makes sure to call ImeInsetsSourceConsumer#onShowRequested on the UI thread. @@ -5174,7 +5179,7 @@ public final class InputMethodManager { // system can verify the consistency between the uid of this process and package name passed // from here. See comment of Context#getOpPackageName() for details. editorInfo.packageName = servedView.getContext().getOpPackageName(); - editorInfo.autofillId = servedView.getAutofillId(); + editorInfo.setAutofillId(servedView.getAutofillId()); editorInfo.fieldId = servedView.getId(); final InputConnection ic = servedView.onCreateInputConnection(editorInfo); if (DEBUG) Log.v(TAG, "Starting input: editorInfo=" + editorInfo + " ic=" + ic); @@ -5183,7 +5188,7 @@ public final class InputMethodManager { // This ensures that even disconnected EditorInfos have well-defined attributes, // making them consistently and straightforwardly comparable. if (ic == null) { - editorInfo.autofillId = AutofillId.NO_AUTOFILL_ID; + editorInfo.setAutofillId(AutofillId.NO_AUTOFILL_ID); editorInfo.fieldId = 0; } return new Pair<>(ic, editorInfo); diff --git a/core/java/android/view/inputmethod/InputMethodSession.java b/core/java/android/view/inputmethod/InputMethodSession.java index 4f48cb684e8c..0f48f1246cf5 100644 --- a/core/java/android/view/inputmethod/InputMethodSession.java +++ b/core/java/android/view/inputmethod/InputMethodSession.java @@ -16,6 +16,7 @@ package android.view.inputmethod; +import android.annotation.NonNull; import android.graphics.Rect; import android.inputmethodservice.InputMethodService; import android.os.Bundle; @@ -125,6 +126,11 @@ public interface InputMethodSession { public void dispatchKeyEvent(int seq, KeyEvent event, EventCallback callback); /** + * @hide + */ + boolean onShouldVerifyKeyEvent(@NonNull KeyEvent event); + + /** * This method is called when there is a track ball event. * * <p> diff --git a/core/java/android/view/inputmethod/flags.aconfig b/core/java/android/view/inputmethod/flags.aconfig index edd9d6cff799..63f8c8024e59 100644 --- a/core/java/android/view/inputmethod/flags.aconfig +++ b/core/java/android/view/inputmethod/flags.aconfig @@ -165,4 +165,21 @@ flag { description: "Writing tools API" bug: "373788889" is_fixed_read_only: true +} + +flag { + name: "public_autofill_id_in_editorinfo" + is_exported: true + namespace: "input_method" + description: "Guarding public API autofillId in editor info" + bug: "342672560" + is_fixed_read_only: true +} + +flag { + name: "verify_key_event" + namespace: "input_method" + description: "Verify KeyEvents in IME" + bug: "331730488" + is_fixed_read_only: true }
\ No newline at end of file diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index d7750bd412a3..cb70466fcd81 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -106,6 +106,7 @@ import android.os.Parcelable; import android.os.ParcelableParcel; import android.os.Process; import android.os.SystemClock; +import android.os.Trace; import android.os.UserHandle; import android.provider.Settings; import android.text.BoringLayout; @@ -9229,174 +9230,179 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override protected void onDraw(Canvas canvas) { - restartMarqueeIfNeeded(); + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "TextView.onDraw"); + try { + restartMarqueeIfNeeded(); - // Draw the background for this view - super.onDraw(canvas); - - final int compoundPaddingLeft = getCompoundPaddingLeft(); - final int compoundPaddingTop = getCompoundPaddingTop(); - final int compoundPaddingRight = getCompoundPaddingRight(); - final int compoundPaddingBottom = getCompoundPaddingBottom(); - final int scrollX = mScrollX; - final int scrollY = mScrollY; - final int right = mRight; - final int left = mLeft; - final int bottom = mBottom; - final int top = mTop; - final boolean isLayoutRtl = isLayoutRtl(); - final int offset = getHorizontalOffsetForDrawables(); - final int leftOffset = isLayoutRtl ? 0 : offset; - final int rightOffset = isLayoutRtl ? offset : 0; + // Draw the background for this view + super.onDraw(canvas); - final Drawables dr = mDrawables; - if (dr != null) { - /* - * Compound, not extended, because the icon is not clipped - * if the text height is smaller. - */ + final int compoundPaddingLeft = getCompoundPaddingLeft(); + final int compoundPaddingTop = getCompoundPaddingTop(); + final int compoundPaddingRight = getCompoundPaddingRight(); + final int compoundPaddingBottom = getCompoundPaddingBottom(); + final int scrollX = mScrollX; + final int scrollY = mScrollY; + final int right = mRight; + final int left = mLeft; + final int bottom = mBottom; + final int top = mTop; + final boolean isLayoutRtl = isLayoutRtl(); + final int offset = getHorizontalOffsetForDrawables(); + final int leftOffset = isLayoutRtl ? 0 : offset; + final int rightOffset = isLayoutRtl ? offset : 0; - int vspace = bottom - top - compoundPaddingBottom - compoundPaddingTop; - int hspace = right - left - compoundPaddingRight - compoundPaddingLeft; + final Drawables dr = mDrawables; + if (dr != null) { + /* + * Compound, not extended, because the icon is not clipped + * if the text height is smaller. + */ - // IMPORTANT: The coordinates computed are also used in invalidateDrawable() - // Make sure to update invalidateDrawable() when changing this code. - if (dr.mShowing[Drawables.LEFT] != null) { - canvas.save(); - canvas.translate(scrollX + mPaddingLeft + leftOffset, - scrollY + compoundPaddingTop + (vspace - dr.mDrawableHeightLeft) / 2); - dr.mShowing[Drawables.LEFT].draw(canvas); - canvas.restore(); - } + int vspace = bottom - top - compoundPaddingBottom - compoundPaddingTop; + int hspace = right - left - compoundPaddingRight - compoundPaddingLeft; + + // IMPORTANT: The coordinates computed are also used in invalidateDrawable() + // Make sure to update invalidateDrawable() when changing this code. + if (dr.mShowing[Drawables.LEFT] != null) { + canvas.save(); + canvas.translate(scrollX + mPaddingLeft + leftOffset, + scrollY + compoundPaddingTop + (vspace - dr.mDrawableHeightLeft) / 2); + dr.mShowing[Drawables.LEFT].draw(canvas); + canvas.restore(); + } - // IMPORTANT: The coordinates computed are also used in invalidateDrawable() - // Make sure to update invalidateDrawable() when changing this code. - if (dr.mShowing[Drawables.RIGHT] != null) { - canvas.save(); - canvas.translate(scrollX + right - left - mPaddingRight - - dr.mDrawableSizeRight - rightOffset, - scrollY + compoundPaddingTop + (vspace - dr.mDrawableHeightRight) / 2); - dr.mShowing[Drawables.RIGHT].draw(canvas); - canvas.restore(); - } + // IMPORTANT: The coordinates computed are also used in invalidateDrawable() + // Make sure to update invalidateDrawable() when changing this code. + if (dr.mShowing[Drawables.RIGHT] != null) { + canvas.save(); + canvas.translate(scrollX + right - left - mPaddingRight + - dr.mDrawableSizeRight - rightOffset, + scrollY + compoundPaddingTop + (vspace - dr.mDrawableHeightRight) / 2); + dr.mShowing[Drawables.RIGHT].draw(canvas); + canvas.restore(); + } - // IMPORTANT: The coordinates computed are also used in invalidateDrawable() - // Make sure to update invalidateDrawable() when changing this code. - if (dr.mShowing[Drawables.TOP] != null) { - canvas.save(); - canvas.translate(scrollX + compoundPaddingLeft - + (hspace - dr.mDrawableWidthTop) / 2, scrollY + mPaddingTop); - dr.mShowing[Drawables.TOP].draw(canvas); - canvas.restore(); - } + // IMPORTANT: The coordinates computed are also used in invalidateDrawable() + // Make sure to update invalidateDrawable() when changing this code. + if (dr.mShowing[Drawables.TOP] != null) { + canvas.save(); + canvas.translate(scrollX + compoundPaddingLeft + + (hspace - dr.mDrawableWidthTop) / 2, scrollY + mPaddingTop); + dr.mShowing[Drawables.TOP].draw(canvas); + canvas.restore(); + } - // IMPORTANT: The coordinates computed are also used in invalidateDrawable() - // Make sure to update invalidateDrawable() when changing this code. - if (dr.mShowing[Drawables.BOTTOM] != null) { - canvas.save(); - canvas.translate(scrollX + compoundPaddingLeft - + (hspace - dr.mDrawableWidthBottom) / 2, - scrollY + bottom - top - mPaddingBottom - dr.mDrawableSizeBottom); - dr.mShowing[Drawables.BOTTOM].draw(canvas); - canvas.restore(); + // IMPORTANT: The coordinates computed are also used in invalidateDrawable() + // Make sure to update invalidateDrawable() when changing this code. + if (dr.mShowing[Drawables.BOTTOM] != null) { + canvas.save(); + canvas.translate(scrollX + compoundPaddingLeft + + (hspace - dr.mDrawableWidthBottom) / 2, + scrollY + bottom - top - mPaddingBottom - dr.mDrawableSizeBottom); + dr.mShowing[Drawables.BOTTOM].draw(canvas); + canvas.restore(); + } } - } - int color = mCurTextColor; + int color = mCurTextColor; - if (mLayout == null) { - assumeLayout(); - } + if (mLayout == null) { + assumeLayout(); + } + + Layout layout = mLayout; - Layout layout = mLayout; + if (mHint != null && !mHideHint && mText.length() == 0) { + if (mHintTextColor != null) { + color = mCurHintTextColor; + } - if (mHint != null && !mHideHint && mText.length() == 0) { - if (mHintTextColor != null) { - color = mCurHintTextColor; + layout = mHintLayout; } - layout = mHintLayout; - } + mTextPaint.setColor(color); + mTextPaint.drawableState = getDrawableState(); - mTextPaint.setColor(color); - mTextPaint.drawableState = getDrawableState(); + canvas.save(); + /* Would be faster if we didn't have to do this. Can we chop the + (displayable) text so that we don't need to do this ever? + */ - canvas.save(); - /* Would be faster if we didn't have to do this. Can we chop the - (displayable) text so that we don't need to do this ever? - */ + int extendedPaddingTop = getExtendedPaddingTop(); + int extendedPaddingBottom = getExtendedPaddingBottom(); - int extendedPaddingTop = getExtendedPaddingTop(); - int extendedPaddingBottom = getExtendedPaddingBottom(); + final int vspace = mBottom - mTop - compoundPaddingBottom - compoundPaddingTop; + final int maxScrollY = mLayout.getHeight() - vspace; - final int vspace = mBottom - mTop - compoundPaddingBottom - compoundPaddingTop; - final int maxScrollY = mLayout.getHeight() - vspace; + float clipLeft = compoundPaddingLeft + scrollX; + float clipTop = (scrollY == 0) ? 0 : extendedPaddingTop + scrollY; + float clipRight = right - left - getCompoundPaddingRight() + scrollX; + float clipBottom = bottom - top + scrollY + - ((scrollY == maxScrollY) ? 0 : extendedPaddingBottom); - float clipLeft = compoundPaddingLeft + scrollX; - float clipTop = (scrollY == 0) ? 0 : extendedPaddingTop + scrollY; - float clipRight = right - left - getCompoundPaddingRight() + scrollX; - float clipBottom = bottom - top + scrollY - - ((scrollY == maxScrollY) ? 0 : extendedPaddingBottom); + if (mShadowRadius != 0) { + clipLeft += Math.min(0, mShadowDx - mShadowRadius); + clipRight += Math.max(0, mShadowDx + mShadowRadius); - if (mShadowRadius != 0) { - clipLeft += Math.min(0, mShadowDx - mShadowRadius); - clipRight += Math.max(0, mShadowDx + mShadowRadius); + clipTop += Math.min(0, mShadowDy - mShadowRadius); + clipBottom += Math.max(0, mShadowDy + mShadowRadius); + } - clipTop += Math.min(0, mShadowDy - mShadowRadius); - clipBottom += Math.max(0, mShadowDy + mShadowRadius); - } + canvas.clipRect(clipLeft, clipTop, clipRight, clipBottom); - canvas.clipRect(clipLeft, clipTop, clipRight, clipBottom); + int voffsetText = 0; + int voffsetCursor = 0; - int voffsetText = 0; - int voffsetCursor = 0; + // translate in by our padding + /* shortcircuit calling getVerticaOffset() */ + if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.TOP) { + voffsetText = getVerticalOffset(false); + voffsetCursor = getVerticalOffset(true); + } + canvas.translate(compoundPaddingLeft, extendedPaddingTop + voffsetText); + + final int layoutDirection = getLayoutDirection(); + final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection); + if (isMarqueeFadeEnabled()) { + if (!mSingleLine && getLineCount() == 1 && canMarquee() + && (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != Gravity.LEFT) { + final int width = mRight - mLeft; + final int padding = getCompoundPaddingLeft() + getCompoundPaddingRight(); + final float dx = mLayout.getLineRight(0) - (width - padding); + canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f); + } - // translate in by our padding - /* shortcircuit calling getVerticaOffset() */ - if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.TOP) { - voffsetText = getVerticalOffset(false); - voffsetCursor = getVerticalOffset(true); - } - canvas.translate(compoundPaddingLeft, extendedPaddingTop + voffsetText); - - final int layoutDirection = getLayoutDirection(); - final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection); - if (isMarqueeFadeEnabled()) { - if (!mSingleLine && getLineCount() == 1 && canMarquee() - && (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != Gravity.LEFT) { - final int width = mRight - mLeft; - final int padding = getCompoundPaddingLeft() + getCompoundPaddingRight(); - final float dx = mLayout.getLineRight(0) - (width - padding); - canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f); + if (mMarquee != null && mMarquee.isRunning()) { + final float dx = -mMarquee.getScroll(); + canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f); + } } - if (mMarquee != null && mMarquee.isRunning()) { - final float dx = -mMarquee.getScroll(); - canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f); - } - } + final int cursorOffsetVertical = voffsetCursor - voffsetText; - final int cursorOffsetVertical = voffsetCursor - voffsetText; + maybeUpdateHighlightPaths(); + // If there is a gesture preview highlight, then the selection or cursor is not drawn. + Path highlight = hasGesturePreviewHighlight() ? null : getUpdatedHighlightPath(); + if (mEditor != null) { + mEditor.onDraw(canvas, layout, mHighlightPaths, mHighlightPaints, highlight, + mHighlightPaint, cursorOffsetVertical); + } else { + layout.draw(canvas, mHighlightPaths, mHighlightPaints, highlight, mHighlightPaint, + cursorOffsetVertical); + } - maybeUpdateHighlightPaths(); - // If there is a gesture preview highlight, then the selection or cursor is not drawn. - Path highlight = hasGesturePreviewHighlight() ? null : getUpdatedHighlightPath(); - if (mEditor != null) { - mEditor.onDraw(canvas, layout, mHighlightPaths, mHighlightPaints, highlight, - mHighlightPaint, cursorOffsetVertical); - } else { - layout.draw(canvas, mHighlightPaths, mHighlightPaints, highlight, mHighlightPaint, - cursorOffsetVertical); - } + if (mMarquee != null && mMarquee.shouldDrawGhost()) { + final float dx = mMarquee.getGhostOffset(); + canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f); + layout.draw(canvas, mHighlightPaths, mHighlightPaints, highlight, mHighlightPaint, + cursorOffsetVertical); + } - if (mMarquee != null && mMarquee.shouldDrawGhost()) { - final float dx = mMarquee.getGhostOffset(); - canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f); - layout.draw(canvas, mHighlightPaths, mHighlightPaints, highlight, mHighlightPaint, - cursorOffsetVertical); + canvas.restore(); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); } - - canvas.restore(); } @Override @@ -11254,192 +11260,201 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int widthMode = MeasureSpec.getMode(widthMeasureSpec); - int heightMode = MeasureSpec.getMode(heightMeasureSpec); - int widthSize = MeasureSpec.getSize(widthMeasureSpec); - int heightSize = MeasureSpec.getSize(heightMeasureSpec); - - int width; - int height; + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "TextView.onMeasure"); + try { + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int heightMode = MeasureSpec.getMode(heightMeasureSpec); + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + int heightSize = MeasureSpec.getSize(heightMeasureSpec); - BoringLayout.Metrics boring = UNKNOWN_BORING; - BoringLayout.Metrics hintBoring = UNKNOWN_BORING; + int width; + int height; - if (mTextDir == null) { - mTextDir = getTextDirectionHeuristic(); - } + BoringLayout.Metrics boring = UNKNOWN_BORING; + BoringLayout.Metrics hintBoring = UNKNOWN_BORING; - int des = -1; - boolean fromexisting = false; - final float widthLimit = (widthMode == MeasureSpec.AT_MOST) - ? (float) widthSize : Float.MAX_VALUE; - - if (widthMode == MeasureSpec.EXACTLY) { - // Parent has told us how big to be. So be it. - width = widthSize; - } else { - if (mLayout != null && mEllipsize == null) { - des = desired(mLayout, mUseBoundsForWidth); + if (mTextDir == null) { + mTextDir = getTextDirectionHeuristic(); } - if (des < 0) { - boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, - isFallbackLineSpacingForBoringLayout(), getResolvedMinimumFontMetrics(), - mBoring); - if (boring != null) { - mBoring = boring; - } - } else { - fromexisting = true; - } + int des = -1; + boolean fromexisting = false; + final float widthLimit = (widthMode == MeasureSpec.AT_MOST) + ? (float) widthSize : Float.MAX_VALUE; - if (boring == null || boring == UNKNOWN_BORING) { - if (des < 0) { - des = (int) Math.ceil(Layout.getDesiredWidthWithLimit(mTransformed, 0, - mTransformed.length(), mTextPaint, mTextDir, widthLimit, - mUseBoundsForWidth)); - } - width = des; + if (widthMode == MeasureSpec.EXACTLY) { + // Parent has told us how big to be. So be it. + width = widthSize; } else { - if (mUseBoundsForWidth) { - RectF bbox = boring.getDrawingBoundingBox(); - float rightMax = Math.max(bbox.right, boring.width); - float leftMin = Math.min(bbox.left, 0); - width = Math.max(boring.width, (int) Math.ceil(rightMax - leftMin)); - } else { - width = boring.width; + if (mLayout != null && mEllipsize == null) { + des = desired(mLayout, mUseBoundsForWidth); } - } - - final Drawables dr = mDrawables; - if (dr != null) { - width = Math.max(width, dr.mDrawableWidthTop); - width = Math.max(width, dr.mDrawableWidthBottom); - } - - if (mHint != null) { - int hintDes = -1; - int hintWidth; - if (mHintLayout != null && mEllipsize == null) { - hintDes = desired(mHintLayout, mUseBoundsForWidth); - } - - if (hintDes < 0) { - hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mTextDir, + if (des < 0) { + boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, isFallbackLineSpacingForBoringLayout(), getResolvedMinimumFontMetrics(), - mHintBoring); - if (hintBoring != null) { - mHintBoring = hintBoring; + mBoring); + if (boring != null) { + mBoring = boring; } + } else { + fromexisting = true; } - if (hintBoring == null || hintBoring == UNKNOWN_BORING) { - if (hintDes < 0) { - hintDes = (int) Math.ceil(Layout.getDesiredWidthWithLimit(mHint, 0, - mHint.length(), mTextPaint, mTextDir, widthLimit, + if (boring == null || boring == UNKNOWN_BORING) { + if (des < 0) { + des = (int) Math.ceil(Layout.getDesiredWidthWithLimit(mTransformed, 0, + mTransformed.length(), mTextPaint, mTextDir, widthLimit, mUseBoundsForWidth)); } - hintWidth = hintDes; + width = des; } else { - hintWidth = hintBoring.width; + if (mUseBoundsForWidth) { + RectF bbox = boring.getDrawingBoundingBox(); + float rightMax = Math.max(bbox.right, boring.width); + float leftMin = Math.min(bbox.left, 0); + width = Math.max(boring.width, (int) Math.ceil(rightMax - leftMin)); + } else { + width = boring.width; + } } - if (hintWidth > width) { - width = hintWidth; + final Drawables dr = mDrawables; + if (dr != null) { + width = Math.max(width, dr.mDrawableWidthTop); + width = Math.max(width, dr.mDrawableWidthBottom); } - } - width += getCompoundPaddingLeft() + getCompoundPaddingRight(); + if (mHint != null) { + int hintDes = -1; + int hintWidth; - if (mMaxWidthMode == EMS) { - width = Math.min(width, mMaxWidth * getLineHeight()); - } else { - width = Math.min(width, mMaxWidth); - } + if (mHintLayout != null && mEllipsize == null) { + hintDes = desired(mHintLayout, mUseBoundsForWidth); + } - if (mMinWidthMode == EMS) { - width = Math.max(width, mMinWidth * getLineHeight()); - } else { - width = Math.max(width, mMinWidth); - } + if (hintDes < 0) { + hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mTextDir, + isFallbackLineSpacingForBoringLayout(), + getResolvedMinimumFontMetrics(), + mHintBoring); + if (hintBoring != null) { + mHintBoring = hintBoring; + } + } - // Check against our minimum width - width = Math.max(width, getSuggestedMinimumWidth()); + if (hintBoring == null || hintBoring == UNKNOWN_BORING) { + if (hintDes < 0) { + hintDes = (int) Math.ceil(Layout.getDesiredWidthWithLimit(mHint, 0, + mHint.length(), mTextPaint, mTextDir, widthLimit, + mUseBoundsForWidth)); + } + hintWidth = hintDes; + } else { + hintWidth = hintBoring.width; + } - if (widthMode == MeasureSpec.AT_MOST) { - width = Math.min(widthSize, width); - } - } + if (hintWidth > width) { + width = hintWidth; + } + } - int want = width - getCompoundPaddingLeft() - getCompoundPaddingRight(); - int unpaddedWidth = want; + width += getCompoundPaddingLeft() + getCompoundPaddingRight(); - if (mHorizontallyScrolling) want = VERY_WIDE; + if (mMaxWidthMode == EMS) { + width = Math.min(width, mMaxWidth * getLineHeight()); + } else { + width = Math.min(width, mMaxWidth); + } - int hintWant = want; - int hintWidth = (mHintLayout == null) ? hintWant : mHintLayout.getWidth(); + if (mMinWidthMode == EMS) { + width = Math.max(width, mMinWidth * getLineHeight()); + } else { + width = Math.max(width, mMinWidth); + } - if (mLayout == null) { - makeNewLayout(want, hintWant, boring, hintBoring, - width - getCompoundPaddingLeft() - getCompoundPaddingRight(), false); - } else { - final boolean layoutChanged = (mLayout.getWidth() != want) || (hintWidth != hintWant) - || (mLayout.getEllipsizedWidth() - != width - getCompoundPaddingLeft() - getCompoundPaddingRight()); + // Check against our minimum width + width = Math.max(width, getSuggestedMinimumWidth()); + + if (widthMode == MeasureSpec.AT_MOST) { + width = Math.min(widthSize, width); + } + } - final boolean widthChanged = (mHint == null) && (mEllipsize == null) - && (want > mLayout.getWidth()) - && (mLayout instanceof BoringLayout - || (fromexisting && des >= 0 && des <= want)); + int want = width - getCompoundPaddingLeft() - getCompoundPaddingRight(); + int unpaddedWidth = want; - final boolean maximumChanged = (mMaxMode != mOldMaxMode) || (mMaximum != mOldMaximum); + if (mHorizontallyScrolling) want = VERY_WIDE; - if (layoutChanged || maximumChanged) { - if (!maximumChanged && widthChanged) { - mLayout.increaseWidthTo(want); + int hintWant = want; + int hintWidth = (mHintLayout == null) ? hintWant : mHintLayout.getWidth(); + + if (mLayout == null) { + makeNewLayout(want, hintWant, boring, hintBoring, + width - getCompoundPaddingLeft() - getCompoundPaddingRight(), false); + } else { + final boolean layoutChanged = + (mLayout.getWidth() != want) || (hintWidth != hintWant) + || (mLayout.getEllipsizedWidth() + != width - getCompoundPaddingLeft() - getCompoundPaddingRight()); + + final boolean widthChanged = (mHint == null) && (mEllipsize == null) + && (want > mLayout.getWidth()) + && (mLayout instanceof BoringLayout + || (fromexisting && des >= 0 && des <= want)); + + final boolean maximumChanged = + (mMaxMode != mOldMaxMode) || (mMaximum != mOldMaximum); + + if (layoutChanged || maximumChanged) { + if (!maximumChanged && widthChanged) { + mLayout.increaseWidthTo(want); + } else { + makeNewLayout(want, hintWant, boring, hintBoring, + width - getCompoundPaddingLeft() - getCompoundPaddingRight(), + false); + } } else { - makeNewLayout(want, hintWant, boring, hintBoring, - width - getCompoundPaddingLeft() - getCompoundPaddingRight(), false); + // Nothing has changed } - } else { - // Nothing has changed } - } - if (heightMode == MeasureSpec.EXACTLY) { - // Parent has told us how big to be. So be it. - height = heightSize; - mDesiredHeightAtMeasure = -1; - } else { - int desired = getDesiredHeight(); + if (heightMode == MeasureSpec.EXACTLY) { + // Parent has told us how big to be. So be it. + height = heightSize; + mDesiredHeightAtMeasure = -1; + } else { + int desired = getDesiredHeight(); - height = desired; - mDesiredHeightAtMeasure = desired; + height = desired; + mDesiredHeightAtMeasure = desired; - if (heightMode == MeasureSpec.AT_MOST) { - height = Math.min(desired, heightSize); + if (heightMode == MeasureSpec.AT_MOST) { + height = Math.min(desired, heightSize); + } } - } - int unpaddedHeight = height - getCompoundPaddingTop() - getCompoundPaddingBottom(); - if (mMaxMode == LINES && mLayout.getLineCount() > mMaximum) { - unpaddedHeight = Math.min(unpaddedHeight, mLayout.getLineTop(mMaximum)); - } + int unpaddedHeight = height - getCompoundPaddingTop() - getCompoundPaddingBottom(); + if (mMaxMode == LINES && mLayout.getLineCount() > mMaximum) { + unpaddedHeight = Math.min(unpaddedHeight, mLayout.getLineTop(mMaximum)); + } - /* - * We didn't let makeNewLayout() register to bring the cursor into view, - * so do it here if there is any possibility that it is needed. - */ - if (mMovement != null - || mLayout.getWidth() > unpaddedWidth - || mLayout.getHeight() > unpaddedHeight) { - registerForPreDraw(); - } else { - scrollTo(0, 0); - } + /* + * We didn't let makeNewLayout() register to bring the cursor into view, + * so do it here if there is any possibility that it is needed. + */ + if (mMovement != null + || mLayout.getWidth() > unpaddedWidth + || mLayout.getHeight() > unpaddedHeight) { + registerForPreDraw(); + } else { + scrollTo(0, 0); + } - setMeasuredDimension(width, height); + setMeasuredDimension(width, height); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } } /** diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java index 0f2dd10d7f47..2c21417fb790 100644 --- a/core/java/android/window/TransitionInfo.java +++ b/core/java/android/window/TransitionInfo.java @@ -49,6 +49,7 @@ import android.content.ComponentName; import android.graphics.Point; import android.graphics.Rect; import android.hardware.HardwareBuffer; +import android.os.BinderProxy; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -1089,8 +1090,13 @@ public final class TransitionInfo implements Parcelable { @Override public String toString() { final StringBuilder sb = new StringBuilder(); - sb.append('{'); sb.append(mContainer); - sb.append(" m="); sb.append(modeToString(mMode)); + sb.append('{'); + if (mContainer != null && !(mContainer.asBinder() instanceof BinderProxy)) { + // Only log the token if it is not a binder proxy and has additional container info + sb.append(mContainer); + sb.append(" "); + } + sb.append("m="); sb.append(modeToString(mMode)); sb.append(" f="); sb.append(flagsToString(mFlags)); if (mParent != null) { sb.append(" p="); sb.append(mParent); diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java index 3fe63ab17248..a88a17283482 100644 --- a/core/java/android/window/WindowContainerTransaction.java +++ b/core/java/android/window/WindowContainerTransaction.java @@ -1120,8 +1120,8 @@ public final class WindowContainerTransaction implements Parcelable { @NonNull public String toString() { return "WindowContainerTransaction {" - + " changes = " + mChanges - + " hops = " + mHierarchyOps + + " changes= " + mChanges + + " hops= " + mHierarchyOps + " errorCallbackToken=" + mErrorCallbackToken + " taskFragmentOrganizer=" + mTaskFragmentOrganizer + " }"; diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig index 392c307de7ba..96b9dc7cab0e 100644 --- a/core/java/android/window/flags/window_surfaces.aconfig +++ b/core/java/android/window/flags/window_surfaces.aconfig @@ -97,3 +97,12 @@ flag { is_fixed_read_only: true bug: "308662081" } + +flag { + name: "jank_api" + namespace: "window_surfaces" + description: "Adds the jank data listener to AttachedSurfaceControl" + is_fixed_read_only: true + is_exported: true + bug: "293949943" +} diff --git a/core/java/com/android/internal/app/procstats/AssociationState.java b/core/java/com/android/internal/app/procstats/AssociationState.java index a21a84261ae0..543adac14d36 100644 --- a/core/java/com/android/internal/app/procstats/AssociationState.java +++ b/core/java/com/android/internal/app/procstats/AssociationState.java @@ -257,7 +257,6 @@ public final class AssociationState { if (VALIDATE_TIMES) { if (mActiveDuration > mAssociationState.mTotalActiveDuration) { RuntimeException ex = new RuntimeException(); - ex.fillInStackTrace(); Slog.w(TAG, "Source act duration " + mActiveDurations + " exceeds total " + mAssociationState.mTotalActiveDuration + " in procstate " + mActiveProcState + " in source " @@ -650,7 +649,6 @@ public final class AssociationState { + mySrc.mKey.mProcess + " to assoc " + mName); if ((mySrc.mDuration + otherSrc.mDuration) > mTotalDuration) { RuntimeException ex = new RuntimeException(); - ex.fillInStackTrace(); Slog.w(TAG, "Source tot duration " + mySrc.mDuration + "+" + otherSrc.mDuration + (newSrc ? " (new)" : " (old)") + " exceeds total " @@ -665,7 +663,6 @@ public final class AssociationState { + mySrc.mKey.mProcess + " to assoc " + mName); if ((mySrc.mActiveDuration + otherSrc.mActiveDuration) > mTotalDuration) { RuntimeException ex = new RuntimeException(); - ex.fillInStackTrace(); Slog.w(TAG, "Source act duration " + mySrc.mActiveDuration + "+" + otherSrc.mActiveDuration + (newSrc ? " (new)" : " (old)") + " exceeds total " @@ -746,14 +743,12 @@ public final class AssociationState { if (VALIDATE_TIMES) { if (src.mDuration > mTotalDuration) { RuntimeException ex = new RuntimeException(); - ex.fillInStackTrace(); Slog.w(TAG, "Reading tot duration " + src.mDuration + " exceeds total " + mTotalDuration + " in source " + src.mKey.mProcess + " to assoc " + mName, ex); } if (src.mActiveDurations == null && src.mActiveDuration > mTotalDuration) { RuntimeException ex = new RuntimeException(); - ex.fillInStackTrace(); Slog.w(TAG, "Reading act duration " + src.mActiveDuration + " exceeds total " + mTotalDuration + " in source " + src.mKey.mProcess + " to assoc " + mName, ex); diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java index 0dbdb36977f4..7523a2d24af8 100644 --- a/core/java/com/android/internal/app/procstats/ProcessState.java +++ b/core/java/com/android/internal/app/procstats/ProcessState.java @@ -538,7 +538,6 @@ public final class ProcessState { public void incActiveServices(String serviceName) { if (DEBUG && "".equals(mName)) { RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); Slog.d(TAG, "incActiveServices: " + this + " service=" + serviceName + " to " + (mNumActiveServices+1), here); } @@ -551,7 +550,6 @@ public final class ProcessState { public void decActiveServices(String serviceName) { if (DEBUG && "".equals(mName)) { RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); Slog.d(TAG, "decActiveServices: " + this + " service=" + serviceName + " to " + (mNumActiveServices-1), here); } @@ -569,7 +567,6 @@ public final class ProcessState { public void incStartedServices(int memFactor, long now, String serviceName) { if (false) { RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); Slog.d(TAG, "incStartedServices: " + this + " service=" + serviceName + " to " + (mNumStartedServices+1), here); } @@ -585,7 +582,6 @@ public final class ProcessState { public void decStartedServices(int memFactor, long now, String serviceName) { if (false) { RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); Slog.d(TAG, "decActiveServices: " + this + " service=" + serviceName + " to " + (mNumStartedServices-1), here); } diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java index 44c0bd01d545..2834e6883316 100644 --- a/core/java/com/android/internal/jank/FrameTracker.java +++ b/core/java/com/android/internal/jank/FrameTracker.java @@ -139,7 +139,7 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai } static JankInfo createFromSurfaceControlCallback(SurfaceControl.JankData jankStat) { - return new JankInfo(jankStat.frameVsyncId).update(jankStat); + return new JankInfo(jankStat.getVsyncId()).update(jankStat); } private JankInfo(long frameVsyncId) { @@ -154,10 +154,10 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai private JankInfo update(SurfaceControl.JankData jankStat) { this.surfaceControlCallbackFired = true; - this.jankType = jankStat.jankType; - this.refreshRate = DisplayRefreshRate.getRefreshRate(jankStat.frameIntervalNs); + this.jankType = jankStat.getJankType(); + this.refreshRate = DisplayRefreshRate.getRefreshRate(jankStat.getFrameIntervalNanos()); if (Flags.useSfFrameDuration()) { - this.totalDurationNanos = jankStat.actualAppFrameTimeNs; + this.totalDurationNanos = jankStat.getActualAppFrameTimeNanos(); } return this; } @@ -458,14 +458,14 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai } for (SurfaceControl.JankData jankStat : jankData) { - if (!isInRange(jankStat.frameVsyncId)) { + if (!isInRange(jankStat.getVsyncId())) { continue; } - JankInfo info = findJankInfo(jankStat.frameVsyncId); + JankInfo info = findJankInfo(jankStat.getVsyncId()); if (info != null) { info.update(jankStat); } else { - mJankInfos.put((int) jankStat.frameVsyncId, + mJankInfos.put((int) jankStat.getVsyncId(), JankInfo.createFromSurfaceControlCallback(jankStat)); } } diff --git a/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java b/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java index 6b6b81f1f805..48d0d6c777de 100644 --- a/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java +++ b/core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java @@ -410,6 +410,11 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, private int mLocaleConfigRes; private boolean mAllowCrossUidActivitySwitchFromBelow; + @Nullable + private int[] mAlternateLauncherIconResIds; + @Nullable + private int[] mAlternateLauncherLabelResIds; + private List<AndroidPackageSplit> mSplits; @NonNull @@ -874,6 +879,18 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, return adoptPermissions; } + @Nullable + @Override + public int[] getAlternateLauncherIconResIds() { + return mAlternateLauncherIconResIds; + } + + @Nullable + @Override + public int[] getAlternateLauncherLabelResIds() { + return mAlternateLauncherLabelResIds; + } + @NonNull @Override public List<ParsedApexSystemService> getApexSystemServices() { @@ -1888,6 +1905,19 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, } @Override + public PackageImpl setAlternateLauncherIconResIds(@Nullable int[] alternateLauncherIconResIds) { + this.mAlternateLauncherIconResIds = alternateLauncherIconResIds; + return this; + } + + @Override + public PackageImpl setAlternateLauncherLabelResIds( + @Nullable int[] alternateLauncherLabelResIds) { + this.mAlternateLauncherLabelResIds = alternateLauncherLabelResIds; + return this; + } + + @Override public PackageImpl setTaskReparentingAllowed(boolean value) { return setBoolean(Booleans.ALLOW_TASK_REPARENTING, value); } @@ -3273,6 +3303,8 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, dest.writeLong(this.mBooleans2); dest.writeBoolean(this.mAllowCrossUidActivitySwitchFromBelow); dest.writeInt(this.mIntentMatchingFlags); + dest.writeIntArray(this.mAlternateLauncherIconResIds); + dest.writeIntArray(this.mAlternateLauncherLabelResIds); } private void writeFeatureFlagState(@NonNull Parcel dest) { @@ -3465,6 +3497,8 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, this.mBooleans2 = in.readLong(); this.mAllowCrossUidActivitySwitchFromBelow = in.readBoolean(); this.mIntentMatchingFlags = in.readInt(); + this.mAlternateLauncherIconResIds = in.createIntArray(); + this.mAlternateLauncherLabelResIds = in.createIntArray(); assignDerivedFields(); assignDerivedFields2(); diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java index f4bceb880617..67b985a61455 100644 --- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java +++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java @@ -413,6 +413,18 @@ public interface ParsingPackage { ParsingPackage setOnBackInvokedCallbackEnabled(boolean enableOnBackInvokedCallback); + /** + * Set the drawable resources id array of the alternate icons that are parsing from the + * AndroidManifest file + */ + ParsingPackage setAlternateLauncherIconResIds(int[] alternateLauncherIconResIds); + + /** + * Set the string resources id array of the alternate labels that are parsing from the + * AndroidManifest file + */ + ParsingPackage setAlternateLauncherLabelResIds(int[] alternateLauncherLabelResIds); + @CallSuper ParsedPackage hideAsParsed(); diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java index 5db7b4197658..8a6e6be1abbf 100644 --- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java +++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java @@ -46,6 +46,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.ConfigurationInfo; import android.content.pm.FeatureGroupInfo; import android.content.pm.FeatureInfo; +import android.content.pm.Flags; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.Property; @@ -154,6 +155,13 @@ public class ParsingPackageUtils { private static final String TAG = ParsingUtils.TAG; + // It is the maximum length of the typedArray of {@link android.R.attr#alternateIcons} + // and {@link android.R.attr#alternateLabels}. + private static final int MAXIMUM_LAUNCHER_ALTERNATE_IDS_LENGTH = 500; + + private static final String TYPE_STRING = "string"; + private static final String TYPE_DRAWABLE = "drawable"; + public static final boolean DEBUG_JAR = false; public static final boolean DEBUG_BACKUP = false; public static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f; @@ -2021,6 +2029,24 @@ public class ParsingPackageUtils { pkg.setManageSpaceActivityName(manageSpaceActivityName); } + if (Flags.changeLauncherBadging()) { + ParseResult<int[]> result = drawableResIdArray(input, sa, res, + R.styleable.AndroidManifestApplication_alternateLauncherIcons, + MAXIMUM_LAUNCHER_ALTERNATE_IDS_LENGTH); + if (result.isError()) { + return input.error(result); + } + pkg.setAlternateLauncherIconResIds(result.getResult()); + + result = stringResIdArray(input, sa, res, + R.styleable.AndroidManifestApplication_alternateLauncherLabels, + MAXIMUM_LAUNCHER_ALTERNATE_IDS_LENGTH); + if (result.isError()) { + return input.error(result); + } + pkg.setAlternateLauncherLabelResIds(result.getResult()); + } + if (pkg.isBackupAllowed()) { // backupAgent, killAfterRestore, fullBackupContent, backupInForeground, // and restoreAnyVersion are only relevant if backup is possible for the @@ -3395,6 +3421,95 @@ public class ParsingPackageUtils { return sa.getResourceId(attribute, 0); } + /** + * Parse the drawable resource id array in the typed array {@code resourceId} + * if available. If {@code maxSize} is not zero, only parse and preserve at most + * {@code maxSize} ids. + */ + private static ParseResult<int[]> drawableResIdArray(ParseInput input, @NonNull TypedArray sa, + @NonNull Resources res, int resourceId, int maxSize) { + return resIdArray(input, sa, res, resourceId, TYPE_DRAWABLE, maxSize); + } + + /** + * Parse the string resource id array in the typed array {@code resourceId} + * if available. If {@code maxSize} is not zero, only parse and preserve at most + * {@code maxSize} ids. + */ + private static ParseResult<int[]> stringResIdArray(ParseInput input, @NonNull TypedArray sa, + @NonNull Resources res, int resourceId, int maxSize) { + return resIdArray(input, sa, res, resourceId, TYPE_STRING, maxSize); + } + + /** + * Parse the resource id array in the typed array {@code resourceId} + * if available. If {@code maxSize} is larger than zero, only parse and preserve + * at most {@code maxSize} ids that type is matched to the {@code expectedTypeName}. + * Because the TypedArray allows mixed types in an array, if {@code expectedTypeName} + * is null, it means don't check the type. + */ + private static ParseResult<int[]> resIdArray(ParseInput input, @NonNull TypedArray sa, + @NonNull Resources res, int resourceId, @Nullable String expectedTypeName, + int maxSize) { + if (!sa.hasValue(resourceId)) { + return input.success(null); + } + + final int typeArrayResId = sa.getResourceId(resourceId, /* defValue= */ 0); + if (typeArrayResId == 0) { + return input.success(null); + } + + // Parse the typedArray + try (TypedArray typedArray = res.obtainTypedArray(typeArrayResId)) { + final String typedArrayName = res.getResourceName(typeArrayResId); + final int length = typedArray.length(); + if (maxSize > 0 && length > maxSize) { + return input.error(TextUtils.formatSimple( + "The length of the typedArray (%s) is larger than %d.", + typedArrayName, maxSize)); + } + Set<Integer> resourceIdSet = new ArraySet<>(); + for (int i = 0; i < length; i++) { + final int id = typedArray.getResourceId(i, /* defValue= */ 0); + // Add the id when the conditions are all matched: + // 1. The resource Id is not 0 + // 2. The type is the expected type + // 3. The id is not duplicated + if (id == 0) { + return input.error(TextUtils.formatSimple( + "There is an item that is not a resource id in the typedArray (%s).", + typedArrayName)); + } + + try { + if (resourceIdSet.contains(id)) { + return input.error(TextUtils.formatSimple( + "There is a duplicated resource (%s) in the typedArray (%s).", + res.getResourceName(id), typedArrayName)); + } + final String typeName = res.getResourceTypeName(id); + if (expectedTypeName != null + && !TextUtils.equals(typeName, expectedTypeName)) { + return input.error(TextUtils.formatSimple( + "There is a resource (%s) in the typedArray (%s) that is not a" + + " %s type.", res.getResourceName(id), typedArrayName, + expectedTypeName)); + } + } catch (Resources.NotFoundException e) { + return input.error(TextUtils.formatSimple( + "There is a resource in the typedArray (%s) that is not found in" + + " the app resources.", typedArrayName)); + } + resourceIdSet.add(id); + } + if (resourceIdSet.isEmpty()) { + return input.success(null); + } + return input.success(resourceIdSet.stream().mapToInt(i -> i).toArray()); + } + } + private static String string(@StyleableRes int attribute, TypedArray sa) { return sa.getString(attribute); } diff --git a/core/java/com/android/server/pm/pkg/AndroidPackage.java b/core/java/com/android/server/pm/pkg/AndroidPackage.java index 53500596f938..d05f5e3950b4 100644 --- a/core/java/com/android/server/pm/pkg/AndroidPackage.java +++ b/core/java/com/android/server/pm/pkg/AndroidPackage.java @@ -91,6 +91,28 @@ import java.util.UUID; public interface AndroidPackage { /** + * An array containing the drawable resources that used for the launcher + * activity icons. + * + * @see R.attr#alternateLauncherIcons + * @hide + */ + @Immutable.Ignore + @Nullable + int[] getAlternateLauncherIconResIds(); + + /** + * An array containing the string resources that used for the launcher + * activity labels. + * + * @see R.attr#alternateLauncherLabels + * @hide + */ + @Immutable.Ignore + @Nullable + int[] getAlternateLauncherLabelResIds(); + + /** * @see ApplicationInfo#className * @see R.styleable#AndroidManifestApplication_name */ diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 25412581303c..a21bf9abdd7b 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -77,6 +77,7 @@ cc_library_shared_for_libandroid_runtime { "android_os_SystemClock.cpp", "android_os_SystemProperties.cpp", "android_text_AndroidCharacter.cpp", + "android_text_Hyphenator.cpp", "android_util_AssetManager.cpp", "android_util_EventLog.cpp", "android_util_Log.cpp", @@ -166,7 +167,6 @@ cc_library_shared_for_libandroid_runtime { "android_view_SurfaceSession.cpp", "android_view_TextureView.cpp", "android_view_TunnelModeEnabledListener.cpp", - "android_text_Hyphenator.cpp", "android_os_Debug.cpp", "android_os_GraphicsEnvironment.cpp", "android_os_HidlMemory.cpp", diff --git a/core/jni/android_hardware_OverlayProperties.cpp b/core/jni/android_hardware_OverlayProperties.cpp index bb4084e8f39e..f64dec8eb215 100644 --- a/core/jni/android_hardware_OverlayProperties.cpp +++ b/core/jni/android_hardware_OverlayProperties.cpp @@ -106,7 +106,7 @@ static jobjectArray android_hardware_OverlayProperties_getLutProperties(JNIEnv* jlong nativeObject) { gui::OverlayProperties* overlayProperties = reinterpret_cast<gui::OverlayProperties*>(nativeObject); - if (overlayProperties->lutProperties.has_value()) { + if (!overlayProperties || !overlayProperties->lutProperties) { return NULL; } auto& lutProperties = overlayProperties->lutProperties.value(); diff --git a/core/jni/android_text_Hyphenator.cpp b/core/jni/android_text_Hyphenator.cpp index 933781c3e924..e45cbaf07876 100644 --- a/core/jni/android_text_Hyphenator.cpp +++ b/core/jni/android_text_Hyphenator.cpp @@ -18,10 +18,17 @@ #include <cutils/trace.h> #include <fcntl.h> #include <minikin/Hyphenator.h> +#ifdef __ANDROID__ #include <sys/mman.h> +#else +#include <android-base/mapped_file.h> +#include <android-base/properties.h> +#endif #include <sys/stat.h> #include <sys/types.h> +#ifdef __ANDROID__ #include <tracing_perfetto.h> +#endif #include <unicode/uloc.h> #include <unistd.h> @@ -30,7 +37,12 @@ namespace android { static std::string buildFileName(const std::string& locale) { +#ifdef __ANDROID__ constexpr char SYSTEM_HYPHENATOR_PREFIX[] = "/system/usr/hyphen-data/hyph-"; +#else + std::string hyphenPath = base::GetProperty("ro.hyphen.data.dir", "/system/usr/hyphen-data"); + std::string SYSTEM_HYPHENATOR_PREFIX = hyphenPath + "/hyph-"; +#endif constexpr char SYSTEM_HYPHENATOR_SUFFIX[] = ".hyb"; std::string lowerLocale; lowerLocale.reserve(locale.size()); @@ -51,11 +63,22 @@ static std::pair<const uint8_t*, size_t> mmapPatternFile(const std::string& loca return std::make_pair(nullptr, 0); } +#ifdef __ANDROID__ void* ptr = mmap(nullptr, st.st_size, PROT_READ, MAP_SHARED, fd, 0 /* offset */); close(fd); if (ptr == MAP_FAILED) { return std::make_pair(nullptr, 0); } +#else + std::unique_ptr<base::MappedFile> patternFile = + base::MappedFile::FromFd(fd, 0, st.st_size, PROT_READ); + close(fd); + if (patternFile == nullptr) { + return std::make_pair(nullptr, 0); + } + auto* mappedPtr = new base::MappedFile(std::move(*patternFile)); + char* ptr = mappedPtr->data(); +#endif return std::make_pair(reinterpret_cast<const uint8_t*>(ptr), st.st_size); } @@ -210,9 +233,13 @@ static void init() { addHyphenatorAlias("und-Taml", "ta"); // Tamil addHyphenatorAlias("und-Telu", "te"); // Telugu +#ifdef __ANDROID__ tracing_perfetto::traceBegin(ATRACE_TAG_VIEW, "CacheUnicodeExtensionSubtagsKeyMap"); +#endif cacheUnicodeExtensionSubtagsKeyMap(); +#ifdef __ANDROID__ tracing_perfetto::traceEnd(ATRACE_TAG_VIEW); // CacheUnicodeExtensionSubtagsKeyMap +#endif } static const JNINativeMethod gMethods[] = { diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 49191ee02ad6..7ef7829c6ba5 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -33,6 +33,7 @@ #include <algorithm> #include <array> +#include <cctype> #include <cstring> #include <limits> #include <memory> @@ -1008,6 +1009,8 @@ jboolean android_os_Process_parseProcLineArray(JNIEnv* env, jobject clazz, } } if ((mode&PROC_OUT_STRING) != 0 && di < NS) { + std::replace_if(buffer+start, buffer+end, + [](unsigned char c){ return !std::isprint(c); }, '?'); jstring str = env->NewStringUTF(buffer+start); env->SetObjectArrayElement(outStrings, di, str); } diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp index f007cc5a23bd..a09c405de1cd 100644 --- a/core/jni/android_view_DisplayEventReceiver.cpp +++ b/core/jni/android_view_DisplayEventReceiver.cpp @@ -67,6 +67,7 @@ static struct { jfieldID preferredFrameTimelineIndex; jfieldID frameTimelinesLength; jfieldID frameTimelines; + jfieldID numberQueuedBuffers; } vsyncEventDataClassInfo; } gDisplayEventReceiverClassInfo; @@ -165,7 +166,8 @@ static jobject createJavaVsyncEventData(JNIEnv* env, VsyncEventData vsyncEventDa return env->NewObject(gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.init, frameTimelineObjs.get(), vsyncEventData.preferredFrameTimelineIndex, - vsyncEventData.frameTimelinesLength, vsyncEventData.frameInterval); + vsyncEventData.frameTimelinesLength, vsyncEventData.frameInterval, + vsyncEventData.numberQueuedBuffers); } void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, @@ -188,6 +190,9 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla env->SetLongField(vsyncEventDataObj.get(), gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.frameInterval, vsyncEventData.frameInterval); + env->SetIntField(vsyncEventDataObj.get(), + gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.numberQueuedBuffers, + vsyncEventData.numberQueuedBuffers); ScopedLocalRef<jobjectArray> frameTimelinesObj(env, @@ -441,7 +446,7 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, "<init>", "([Landroid/view/" - "DisplayEventReceiver$VsyncEventData$FrameTimeline;IIJ)V"); + "DisplayEventReceiver$VsyncEventData$FrameTimeline;IIJI)V"); gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.preferredFrameTimelineIndex = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, @@ -456,6 +461,9 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, "frameTimelines", "[Landroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;"); + gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.numberQueuedBuffers = + GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, + "numberQueuedBuffers", "I"); return res; } diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index d3bf36e60345..450b88bbe218 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -758,54 +758,64 @@ static void nativeSetLuts(JNIEnv* env, jclass clazz, jlong transactionObj, jlong auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject); - ScopedIntArrayRW joffsets(env, joffsetArray); - if (joffsets.get() == nullptr) { - jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from joffsetArray"); - return; - } - ScopedIntArrayRW jdimensions(env, jdimensionArray); - if (jdimensions.get() == nullptr) { - jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jdimensionArray"); - return; - } - ScopedIntArrayRW jsizes(env, jsizeArray); - if (jsizes.get() == nullptr) { - jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jsizeArray"); - return; - } - ScopedIntArrayRW jsamplingKeys(env, jsamplingKeyArray); - if (jsamplingKeys.get() == nullptr) { - jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jsamplingKeyArray"); - return; - } + std::vector<int32_t> offsets; + std::vector<int32_t> dimensions; + std::vector<int32_t> sizes; + std::vector<int32_t> samplingKeys; + int32_t fd = -1; + + if (jdimensionArray) { + jsize numLuts = env->GetArrayLength(jdimensionArray); + ScopedIntArrayRW joffsets(env, joffsetArray); + if (joffsets.get() == nullptr) { + jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from joffsetArray"); + return; + } + ScopedIntArrayRW jdimensions(env, jdimensionArray); + if (jdimensions.get() == nullptr) { + jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jdimensionArray"); + return; + } + ScopedIntArrayRW jsizes(env, jsizeArray); + if (jsizes.get() == nullptr) { + jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jsizeArray"); + return; + } + ScopedIntArrayRW jsamplingKeys(env, jsamplingKeyArray); + if (jsamplingKeys.get() == nullptr) { + jniThrowRuntimeException(env, "Failed to get ScopedIntArrayRW from jsamplingKeyArray"); + return; + } - jsize numLuts = env->GetArrayLength(jdimensionArray); - std::vector<int32_t> offsets(joffsets.get(), joffsets.get() + numLuts); - std::vector<int32_t> dimensions(jdimensions.get(), jdimensions.get() + numLuts); - std::vector<int32_t> sizes(jsizes.get(), jsizes.get() + numLuts); - std::vector<int32_t> samplingKeys(jsamplingKeys.get(), jsamplingKeys.get() + numLuts); + if (numLuts > 0) { + offsets = std::vector<int32_t>(joffsets.get(), joffsets.get() + numLuts); + dimensions = std::vector<int32_t>(jdimensions.get(), jdimensions.get() + numLuts); + sizes = std::vector<int32_t>(jsizes.get(), jsizes.get() + numLuts); + samplingKeys = std::vector<int32_t>(jsamplingKeys.get(), jsamplingKeys.get() + numLuts); - ScopedFloatArrayRW jbuffers(env, jbufferArray); - if (jbuffers.get() == nullptr) { - jniThrowRuntimeException(env, "Failed to get ScopedFloatArrayRW from jbufferArray"); - return; - } + ScopedFloatArrayRW jbuffers(env, jbufferArray); + if (jbuffers.get() == nullptr) { + jniThrowRuntimeException(env, "Failed to get ScopedFloatArrayRW from jbufferArray"); + return; + } - // create the shared memory and copy jbuffers - size_t bufferSize = jbuffers.size() * sizeof(float); - int32_t fd = ashmem_create_region("lut_shread_mem", bufferSize); - if (fd < 0) { - jniThrowRuntimeException(env, "ashmem_create_region() failed"); - return; - } - void* ptr = mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (ptr == MAP_FAILED) { - jniThrowRuntimeException(env, "Failed to map the shared memory"); - return; + // create the shared memory and copy jbuffers + size_t bufferSize = jbuffers.size() * sizeof(float); + fd = ashmem_create_region("lut_shared_mem", bufferSize); + if (fd < 0) { + jniThrowRuntimeException(env, "ashmem_create_region() failed"); + return; + } + void* ptr = mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (ptr == MAP_FAILED) { + jniThrowRuntimeException(env, "Failed to map the shared memory"); + return; + } + memcpy(ptr, jbuffers.get(), bufferSize); + // unmap + munmap(ptr, bufferSize); + } } - memcpy(ptr, jbuffers.get(), bufferSize); - // unmap - munmap(ptr, bufferSize); transaction->setLuts(ctrl, base::unique_fd(fd), offsets, dimensions, sizes, samplingKeys); } @@ -2163,7 +2173,7 @@ static void nativeClearTrustedPresentationCallback(JNIEnv* env, jclass clazz, jl class JankDataListenerWrapper : public JankDataListener { public: - JankDataListenerWrapper(JNIEnv* env, jobject onJankDataListenerObject) { + JankDataListenerWrapper(JNIEnv* env, jobject onJankDataListenerObject) : mRemovedVsyncId(-1) { mOnJankDataListenerWeak = env->NewWeakGlobalRef(onJankDataListenerObject); env->GetJavaVM(&mVm); } @@ -2174,6 +2184,12 @@ public: } bool onJankDataAvailable(const std::vector<gui::JankData>& jankData) override { + // Don't invoke the listener if we've been force removed and got this + // out-of-order callback. + if (mRemovedVsyncId == 0) { + return false; + } + JNIEnv* env = getEnv(); jobject target = env->NewLocalRef(mOnJankDataListenerWeak); @@ -2181,9 +2197,29 @@ public: return false; } - jobjectArray jJankDataArray = env->NewObjectArray(jankData.size(), - gJankDataClassInfo.clazz, nullptr); - for (size_t i = 0; i < jankData.size(); i++) { + // Compute the count of data items we'll actually forward to Java. + size_t count = 0; + if (mRemovedVsyncId <= 0) { + count = jankData.size(); + } else { + for (const gui::JankData& frame : jankData) { + if (frame.frameVsyncId <= mRemovedVsyncId) { + count++; + } + } + } + + if (count == 0) { + return false; + } + + jobjectArray jJankDataArray = env->NewObjectArray(count, gJankDataClassInfo.clazz, nullptr); + for (size_t i = 0, j = 0; i < jankData.size() && j < count; i++) { + // Filter any data for frames past our removal vsync. + if (mRemovedVsyncId > 0 && jankData[i].frameVsyncId > mRemovedVsyncId) { + continue; + } + // The exposed constants in SurfaceControl are simplified, so we need to translate the // jank type we get from SF to what is exposed in Java. int sfJankType = jankData[i].jankType; @@ -2210,7 +2246,7 @@ public: jankData[i].frameVsyncId, javaJankType, jankData[i].frameIntervalNs, jankData[i].scheduledAppFrameTimeNs, jankData[i].actualAppFrameTimeNs); - env->SetObjectArrayElement(jJankDataArray, i, jJankData); + env->SetObjectArrayElement(jJankDataArray, j++, jJankData); env->DeleteLocalRef(jJankData); } @@ -2225,6 +2261,11 @@ public: return true; } + void removeListener(int64_t afterVsyncId) { + mRemovedVsyncId = (afterVsyncId <= 0) ? 0 : afterVsyncId; + JankDataListener::removeListener(afterVsyncId); + } + private: JNIEnv* getEnv() { @@ -2235,6 +2276,7 @@ private: JavaVM* mVm; jobject mOnJankDataListenerWeak; + int64_t mRemovedVsyncId; }; static jlong nativeCreateJankDataListenerWrapper(JNIEnv* env, jclass clazz, diff --git a/core/jni/com_android_internal_content_FileSystemUtils.cpp b/core/jni/com_android_internal_content_FileSystemUtils.cpp index 6c72544a7958..76ead2a3ca31 100644 --- a/core/jni/com_android_internal_content_FileSystemUtils.cpp +++ b/core/jni/com_android_internal_content_FileSystemUtils.cpp @@ -22,7 +22,6 @@ #include <android-base/hex.h> #include <android-base/unique_fd.h> #include <bionic/macros.h> -#include <elf.h> #include <errno.h> #include <fcntl.h> #include <inttypes.h> @@ -204,7 +203,8 @@ bool punchHoles(const char *filePath, const uint64_t offset, return true; } -bool punchHolesInElf64(const char *filePath, const uint64_t offset) { +bool getLoadSegmentPhdrs(const char *filePath, const uint64_t offset, + std::vector<Elf64_Phdr> &programHeaders) { // Open Elf file Elf64_Ehdr ehdr; std::ifstream inputStream(filePath, std::ifstream::in); @@ -227,11 +227,6 @@ bool punchHolesInElf64(const char *filePath, const uint64_t offset) { uint64_t programHeaderOffset = ehdr.e_phoff; uint16_t programHeaderNum = ehdr.e_phnum; - IF_ALOGD() { - ALOGD("Punching holes in file: %s programHeaderOffset: %" PRIu64 " programHeaderNum: %hu", - filePath, programHeaderOffset, programHeaderNum); - } - // if this is a zip file, also consider elf offset inside a file uint64_t phOffset; if (__builtin_add_overflow(offset, programHeaderOffset, &phOffset)) { @@ -240,7 +235,6 @@ bool punchHolesInElf64(const char *filePath, const uint64_t offset) { } inputStream.seekg(phOffset); - std::vector<Elf64_Phdr> programHeaders; for (int headerIndex = 0; headerIndex < programHeaderNum; headerIndex++) { Elf64_Phdr header; inputStream.read((char *)&header, sizeof(header)); @@ -254,6 +248,15 @@ bool punchHolesInElf64(const char *filePath, const uint64_t offset) { programHeaders.push_back(header); } + return true; +} + +bool punchHolesInElf64(const char *filePath, const uint64_t offset) { + std::vector<Elf64_Phdr> programHeaders; + if (!getLoadSegmentPhdrs(filePath, offset, programHeaders)) { + ALOGE("Failed to read program headers from ELF file."); + return false; + } return punchHoles(filePath, offset, programHeaders); } diff --git a/core/jni/com_android_internal_content_FileSystemUtils.h b/core/jni/com_android_internal_content_FileSystemUtils.h index 52445e2b4229..4a95686c5a0c 100644 --- a/core/jni/com_android_internal_content_FileSystemUtils.h +++ b/core/jni/com_android_internal_content_FileSystemUtils.h @@ -15,8 +15,11 @@ */ #pragma once +#include <elf.h> #include <sys/types.h> +#include <vector> + namespace android { /* @@ -35,4 +38,11 @@ bool punchHolesInElf64(const char* filePath, uint64_t offset); */ bool punchHolesInZip(const char* filePath, uint64_t offset, uint16_t extraFieldLen); +/* + * This function reads program headers from ELF file. ELF can be specified with file path directly + * or it should be at offset inside Apk. Program headers passed to function is populated. + */ +bool getLoadSegmentPhdrs(const char* filePath, const uint64_t offset, + std::vector<Elf64_Phdr>& programHeaders); + } // namespace android
\ No newline at end of file diff --git a/core/jni/platform/host/HostRuntime.cpp b/core/jni/platform/host/HostRuntime.cpp index 7fca1175f3d4..1a0328338980 100644 --- a/core/jni/platform/host/HostRuntime.cpp +++ b/core/jni/platform/host/HostRuntime.cpp @@ -88,6 +88,7 @@ extern int register_android_os_Parcel(JNIEnv* env); extern int register_android_os_SystemClock(JNIEnv* env); extern int register_android_os_SystemProperties(JNIEnv* env); extern int register_android_text_AndroidCharacter(JNIEnv* env); +extern int register_android_text_Hyphenator(JNIEnv* env); extern int register_android_util_EventLog(JNIEnv* env); extern int register_android_util_Log(JNIEnv* env); extern int register_android_util_jar_StrictJarFile(JNIEnv* env); @@ -133,6 +134,7 @@ static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = { {"android.os.SystemClock", REG_JNI(register_android_os_SystemClock)}, {"android.os.SystemProperties", REG_JNI(register_android_os_SystemProperties)}, {"android.text.AndroidCharacter", REG_JNI(register_android_text_AndroidCharacter)}, + {"android.text.Hyphenator", REG_JNI(register_android_text_Hyphenator)}, {"android.util.EventLog", REG_JNI(register_android_util_EventLog)}, {"android.util.Log", REG_JNI(register_android_util_Log)}, {"android.util.jar.StrictJarFile", REG_JNI(register_android_util_jar_StrictJarFile)}, diff --git a/core/res/res/values-night/colors_dynamic.xml b/core/res/res/values-night/colors_dynamic.xml deleted file mode 100644 index 7e95ff4f409e..000000000000 --- a/core/res/res/values-night/colors_dynamic.xml +++ /dev/null @@ -1,103 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2024 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<!-- Colors specific to Material themes. --> -<resources> - <color name="materialColorBackground">@color/system_background_dark</color> - <color name="materialColorControlActivated">@color/system_control_activated_dark</color> - <color name="materialColorControlHighlight">@color/system_control_highlight_dark</color> - <color name="materialColorControlNormal">@color/system_control_normal_dark</color> - <color name="materialColorError">@color/system_error_dark</color> - <color name="materialColorErrorContainer">@color/system_error_container_dark</color> - <color name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</color> - <color name="materialColorInversePrimary">@color/system_inverse_primary_dark</color> - <color name="materialColorInverseSurface">@color/system_inverse_surface_dark</color> - <color name="materialColorOnBackground">@color/system_on_background_dark</color> - <color name="materialColorOnError">@color/system_on_error_dark</color> - <color name="materialColorOnErrorContainer">@color/system_on_error_container_dark</color> - <color name="materialColorOnPrimary">@color/system_on_primary_dark</color> - <color name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</color> - <color name="materialColorOnSecondary">@color/system_on_secondary_dark</color> - <color name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</color> - <color name="materialColorOnSurface">@color/system_on_surface_dark</color> - <color name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</color> - <color name="materialColorOnTertiary">@color/system_on_tertiary_dark</color> - <color name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</color> - <color name="materialColorOutline">@color/system_outline_dark</color> - <color name="materialColorOutlineVariant">@color/system_outline_variant_dark</color> - <color name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</color> - <color name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</color> - <color name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</color> - <color name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</color> - <color name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</color> - <color name="materialColorPrimary">@color/system_primary_dark</color> - <color name="materialColorPrimaryContainer">@color/system_primary_container_dark</color> - <color name="materialColorScrim">@color/system_scrim_dark</color> - <color name="materialColorSecondary">@color/system_secondary_dark</color> - <color name="materialColorSecondaryContainer">@color/system_secondary_container_dark</color> - <color name="materialColorShadow">@color/system_shadow_dark</color> - <color name="materialColorSurface">@color/system_surface_dark</color> - <color name="materialColorSurfaceBright">@color/system_surface_bright_dark</color> - <color name="materialColorSurfaceContainer">@color/system_surface_container_dark</color> - <color name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</color> - <color name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</color> - <color name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</color> - <color name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</color> - <color name="materialColorSurfaceDim">@color/system_surface_dim_dark</color> - <color name="materialColorSurfaceTint">@color/system_surface_tint_dark</color> - <color name="materialColorSurfaceVariant">@color/system_surface_variant_dark</color> - <color name="materialColorTertiary">@color/system_tertiary_dark</color> - <color name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</color> - <color name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</color> - <color name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</color> - <color name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</color> - <color name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</color> - <color name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</color> - <color name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</color> - <color name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</color> - <color name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</color> - <color name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</color> - <color name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</color> - <color name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</color> - <color name="materialColorPrimaryFixed">@color/system_primary_fixed</color> - <color name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</color> - <color name="materialColorSecondaryFixed">@color/system_secondary_fixed</color> - <color name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</color> - <color name="materialColorTertiaryFixed">@color/system_tertiary_fixed</color> - <color name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</color> - <color name="customColorBrandA">@color/system_brand_a_dark</color> - <color name="customColorBrandB">@color/system_brand_b_dark</color> - <color name="customColorBrandC">@color/system_brand_c_dark</color> - <color name="customColorBrandD">@color/system_brand_d_dark</color> - <color name="customColorClockHour">@color/system_clock_hour_dark</color> - <color name="customColorClockMinute">@color/system_clock_minute_dark</color> - <color name="customColorClockSecond">@color/system_clock_second_dark</color> - <color name="customColorOnShadeActive">@color/system_on_shade_active_dark</color> - <color name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</color> - <color name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</color> - <color name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</color> - <color name="customColorOnThemeApp">@color/system_on_theme_app_dark</color> - <color name="customColorOverviewBackground">@color/system_overview_background_dark</color> - <color name="customColorShadeActive">@color/system_shade_active_dark</color> - <color name="customColorShadeDisabled">@color/system_shade_disabled_dark</color> - <color name="customColorShadeInactive">@color/system_shade_inactive_dark</color> - <color name="customColorThemeApp">@color/system_theme_app_dark</color> - <color name="customColorThemeAppRing">@color/system_theme_app_ring_dark</color> - <color name="customColorThemeNotif">@color/system_theme_notif_dark</color> - <color name="customColorUnderSurface">@color/system_under_surface_dark</color> - <color name="customColorWeatherTemp">@color/system_weather_temp_dark</color> - <color name="customColorWidgetBackground">@color/system_widget_background_dark</color> -</resources> diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml index 7ac17595a278..4d2085bbe0c7 100644 --- a/core/res/res/values-watch/themes_device_defaults.xml +++ b/core/res/res/values-watch/themes_device_defaults.xml @@ -238,16 +238,16 @@ a similar way. <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorInverseOnSurface">@color/system_on_surface_light</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorInversePrimary">@color/system_primary_light</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorInverseSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index f663fb93cbcb..e6dedce8feaf 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -1218,132 +1218,155 @@ it prevent any 'false' in any of its children. --> <attr name="forceDarkAllowed" format="boolean" /> - <!-- Dynamic Tokens --> - - <!-- @hide --> - <attr name="materialColorBackground" format="color"/> - <!-- @hide --> - <attr name="materialColorControlActivated" format="color"/> - <!-- @hide --> - <attr name="materialColorControlHighlight" format="color"/> - <!-- @hide --> - <attr name="materialColorControlNormal" format="color"/> - <!-- @hide --> - <attr name="materialColorError" format="color"/> - <!-- @hide --> + <!-- A lower-emphasized variant of the color on the fixed secondary branding color. @hide + --> + <attr name="materialColorOnSecondaryFixedVariant" format="color"/> + <!-- A lower-emphasized variant of the color on the fixed tertiary branding color. @hide + --> + <attr name="materialColorOnTertiaryFixedVariant" format="color"/> + <!-- The container color of surface the most lowered. @hide --> + <attr name="materialColorSurfaceContainerLowest" format="color"/> + <!-- A lower-emphasized variant of the color on the fixed primary branding color. @hide --> + <attr name="materialColorOnPrimaryFixedVariant" format="color"/> + <!-- A color that passes accessibility guidelines for text/iconography when drawn on top of + the secondary container color. @hide --> + <attr name="materialColorOnSecondaryContainer" format="color"/> + <!-- A color that passes accessibility guidelines for text/iconography when drawn on top of + the tertiary container color. @hide --> + <attr name="materialColorOnTertiaryContainer" format="color"/> + <!-- The container color of surface slightly lowered, which replaces the previous surface + at elevation level 1. @hide --> + <attr name="materialColorSurfaceContainerLow" format="color"/> + <!-- A color that passes accessibility guidelines for text/iconography when drawn on top of + the primary container color. @hide --> + <attr name="materialColorOnPrimaryContainer" format="color"/> + <!-- A stronger, more emphasized variant of the fixed secondary branding color. @hide --> + <attr name="materialColorSecondaryFixedDim" format="color"/> + <!-- A tonal variation of the on error color that passes accessibility guidelines for + text/iconography when drawn on top of error container. @hide --> + <attr name="materialColorOnErrorContainer" format="color"/> + <!-- The color text/iconography when drawn on top of the fixed secondary branding color. + @hide --> + <attr name="materialColorOnSecondaryFixed" format="color"/> + <!-- The "on surface" inverse color, useful for inverted backgrounds. @hide --> + <attr name="materialColorOnSurfaceInverse" format="color"/> + <!-- A stronger, more emphasized variant of the fixed tertiary branding color. @hide --> + <attr name="materialColorTertiaryFixedDim" format="color"/> + <!-- The color text/iconography when drawn on top of the fixed tertiary branding color. + @hide --> + <attr name="materialColorOnTertiaryFixed" format="color"/> + <!-- A stronger, more emphasized variant of the fixed primary branding color. @hide --> + <attr name="materialColorPrimaryFixedDim" format="color"/> + <!-- A tonal variation of the secondary color suitable for background color of container + views. @hide --> + <attr name="materialColorSecondaryContainer" format="color"/> + <!-- A tonal variation of the error color suitable for background color of container views. + @hide --> <attr name="materialColorErrorContainer" format="color"/> - <!-- @hide --> - <attr name="materialColorInverseOnSurface" format="color"/> - <!-- @hide --> - <attr name="materialColorInversePrimary" format="color"/> - <!-- @hide --> - <attr name="materialColorInverseSurface" format="color"/> - <!-- @hide --> + <!-- The color text/iconography when drawn on top of the fixed primary branding color. + @hide --> + <attr name="materialColorOnPrimaryFixed" format="color"/> + <!-- The inverse color of colorPrimary. @hide --> + <attr name="materialColorPrimaryInverse" format="color"/> + <!-- A secondary branding color for the app, which stays the same between light and dark + themes. @hide --> + <attr name="materialColorSecondaryFixed" format="color"/> + <!-- The surface inverse color, useful for inverted backgrounds. @hide --> + <attr name="materialColorSurfaceInverse" format="color"/> + <!-- A tonal variation of the surface color. @hide --> + <attr name="materialColorSurfaceVariant" format="color"/> + <!-- A tonal variation of the tertiary color suitable for background color of container + views. @hide --> + <attr name="materialColorTertiaryContainer" format="color"/> + <!-- A tertiary branding color for the app, which stays the same between light and dark + themes. @hide --> + <attr name="materialColorTertiaryFixed" format="color"/> + <!-- A tonal variation of the primary color suitable for background color of container + views. @hide --> + <attr name="materialColorPrimaryContainer" format="color"/> + <!-- A color that passes accessibility guidelines for text/iconography when drawn on top of + background. @hide --> <attr name="materialColorOnBackground" format="color"/> - <!-- @hide --> - <attr name="materialColorOnError" format="color"/> - <!-- @hide --> - <attr name="materialColorOnErrorContainer" format="color"/> - <!-- @hide --> - <attr name="materialColorOnPrimary" format="color"/> - <!-- @hide --> - <attr name="materialColorOnPrimaryContainer" format="color"/> - <!-- @hide --> + <!-- A primary branding color for the app, which stays the same between light and dark + themes. @hide --> + <attr name="materialColorPrimaryFixed" format="color"/> + <!-- A color that passes accessibility guidelines for text/iconography when drawn on top of + secondary. @hide --> <attr name="materialColorOnSecondary" format="color"/> - <!-- @hide --> - <attr name="materialColorOnSecondaryContainer" format="color"/> - <!-- @hide --> - <attr name="materialColorOnSurface" format="color"/> - <!-- @hide --> - <attr name="materialColorOnSurfaceVariant" format="color"/> - <!-- @hide --> + <!-- A color that passes accessibility guidelines for text/iconography when drawn on top of + tertiary. @hide --> <attr name="materialColorOnTertiary" format="color"/> - <!-- @hide --> - <attr name="materialColorOnTertiaryContainer" format="color"/> - <!-- @hide --> - <attr name="materialColorOutline" format="color"/> - <!-- @hide --> - <attr name="materialColorOutlineVariant" format="color"/> - <!-- @hide --> - <attr name="materialColorPaletteKeyColorNeutral" format="color"/> - <!-- @hide --> - <attr name="materialColorPaletteKeyColorNeutralVariant" format="color"/> - <!-- @hide --> - <attr name="materialColorPaletteKeyColorPrimary" format="color"/> - <!-- @hide --> - <attr name="materialColorPaletteKeyColorSecondary" format="color"/> - <!-- @hide --> - <attr name="materialColorPaletteKeyColorTertiary" format="color"/> - <!-- @hide --> - <attr name="materialColorPrimary" format="color"/> - <!-- @hide --> - <attr name="materialColorPrimaryContainer" format="color"/> - <!-- @hide --> - <attr name="materialColorScrim" format="color"/> - <!-- @hide --> + <!-- The surface color which always stay the dimmest in either dark or light theme. @hide + --> + <attr name="materialColorSurfaceDim" format="color"/> + <!-- The surface color which always stay the brightest in either dark or light theme. @hide + --> + <attr name="materialColorSurfaceBright" format="color"/> + <!-- The secondary branding color for the app, usually a bright complement to the primary + branding color. @hide --> <attr name="materialColorSecondary" format="color"/> - <!-- @hide --> - <attr name="materialColorSecondaryContainer" format="color"/> - <!-- @hide --> - <attr name="materialColorShadow" format="color"/> - <!-- @hide --> + <!-- A color that passes accessibility guidelines for text/iconography when drawn on top of + error. @hide --> + <attr name="materialColorOnError" format="color"/> + <!-- The color of surfaces such as cards, sheets, menus. @hide --> <attr name="materialColorSurface" format="color"/> - <!-- @hide --> - <attr name="materialColorSurfaceBright" format="color"/> - <!-- @hide --> - <attr name="materialColorSurfaceContainer" format="color"/> - <!-- @hide --> + <!-- The container color of surface slightly elevated, which replaces the previous surface + at elevation level 3. @hide --> <attr name="materialColorSurfaceContainerHigh" format="color"/> - <!-- @hide --> + <!-- The tertiary branding color for the app, usually a bright complement to the primary + branding color. @hide --> + <attr name="materialColorTertiary" format="color"/> + <!-- The container color of surface the most elevated, which replaces the previous surface + variant. @hide --> <attr name="materialColorSurfaceContainerHighest" format="color"/> - <!-- @hide --> - <attr name="materialColorSurfaceContainerLow" format="color"/> - <!-- @hide --> - <attr name="materialColorSurfaceContainerLowest" format="color"/> - <!-- @hide --> - <attr name="materialColorSurfaceDim" format="color"/> - <!-- @hide --> - <attr name="materialColorSurfaceTint" format="color"/> - <!-- @hide --> - <attr name="materialColorSurfaceVariant" format="color"/> - <!-- @hide --> + <!-- A tonal variation of the on surface color that passes accessibility guidelines for + text/iconography when drawn on top of surface variant. @hide --> + <attr name="materialColorOnSurfaceVariant" format="color"/> + <!-- A color meant to be used in element outlines. @hide --> + <attr name="materialColorOutline" format="color"/> + <!-- A color meant to be used in element outlines on the surface-variant color. @hide --> + <attr name="materialColorOutlineVariant" format="color"/> + <!-- A color that passes accessibility guidelines for text/iconography when drawn on top of + primary. @hide --> + <attr name="materialColorOnPrimary" format="color"/> + <!-- A color that passes accessibility guidelines for text/iconography when drawn on top of + surface. @hide --> + <attr name="materialColorOnSurface" format="color"/> + <!-- The container color of surface, which replaces the previous surface at elevation level + 2. @hide --> + <attr name="materialColorSurfaceContainer" format="color"/> + <!-- The container color of surface, which replaces the previous surface at elevation level + 2. @hide --> + <attr name="materialColorSurfaceContainer" format="color"/> + <!-- The primary branding color for the app. By default, this is the color applied to the + action bar background. @hide --> + <attr name="materialColorPrimary" format="color"/> + <!-- The secondary branding color for the app, usually a bright complement to the primary + branding color. @hide --> + <attr name="materialColorSecondary" format="color"/> + <!-- A color that passes accessibility guidelines for text/iconography when drawn on top + of tertiary. @hide --> <attr name="materialColorTertiary" format="color"/> + <!-- The error color for the app, intended to draw attention to error conditions. @hide --> + <attr name="materialColorError" format="color"/> + + <!-- System Custom Tokens--> <!-- @hide --> - <attr name="materialColorTertiaryContainer" format="color"/> - <!-- @hide --> - <attr name="materialColorTextHintInverse" format="color"/> - <!-- @hide --> - <attr name="materialColorTextPrimaryInverse" format="color"/> - <!-- @hide --> - <attr name="materialColorTextPrimaryInverseDisableOnly" format="color"/> - <!-- @hide --> - <attr name="materialColorTextSecondaryAndTertiaryInverse" format="color"/> - <!-- @hide --> - <attr name="materialColorTextSecondaryAndTertiaryInverseDisabled" format="color"/> - <!-- @hide --> - <attr name="materialColorOnPrimaryFixed" format="color"/> - <!-- @hide --> - <attr name="materialColorOnPrimaryFixedVariant" format="color"/> - <!-- @hide --> - <attr name="materialColorOnSecondaryFixed" format="color"/> - <!-- @hide --> - <attr name="materialColorOnSecondaryFixedVariant" format="color"/> - <!-- @hide --> - <attr name="materialColorOnTertiaryFixed" format="color"/> + <attr name="customColorWidgetBackground" format="color"/> <!-- @hide --> - <attr name="materialColorOnTertiaryFixedVariant" format="color"/> + <attr name="customColorClockHour" format="color"/> <!-- @hide --> - <attr name="materialColorPrimaryFixed" format="color"/> + <attr name="customColorClockMinute" format="color"/> <!-- @hide --> - <attr name="materialColorPrimaryFixedDim" format="color"/> + <attr name="customColorClockSecond" format="color"/> <!-- @hide --> - <attr name="materialColorSecondaryFixed" format="color"/> + <attr name="customColorThemeApp" format="color"/> <!-- @hide --> - <attr name="materialColorSecondaryFixedDim" format="color"/> + <attr name="customColorOnThemeApp" format="color"/> <!-- @hide --> - <attr name="materialColorTertiaryFixed" format="color"/> + <attr name="customColorThemeAppRing" format="color"/> <!-- @hide --> - <attr name="materialColorTertiaryFixedDim" format="color"/> + <attr name="customColorThemeNotif" format="color"/> <!-- @hide --> <attr name="customColorBrandA" format="color"/> <!-- @hide --> @@ -1353,41 +1376,23 @@ <!-- @hide --> <attr name="customColorBrandD" format="color"/> <!-- @hide --> - <attr name="customColorClockHour" format="color"/> - <!-- @hide --> - <attr name="customColorClockMinute" format="color"/> + <attr name="customColorUnderSurface" format="color"/> <!-- @hide --> - <attr name="customColorClockSecond" format="color"/> + <attr name="customColorShadeActive" format="color"/> <!-- @hide --> <attr name="customColorOnShadeActive" format="color"/> <!-- @hide --> <attr name="customColorOnShadeActiveVariant" format="color"/> <!-- @hide --> + <attr name="customColorShadeInactive" format="color"/> + <!-- @hide --> <attr name="customColorOnShadeInactive" format="color"/> <!-- @hide --> <attr name="customColorOnShadeInactiveVariant" format="color"/> <!-- @hide --> - <attr name="customColorOnThemeApp" format="color"/> - <!-- @hide --> - <attr name="customColorOverviewBackground" format="color"/> - <!-- @hide --> - <attr name="customColorShadeActive" format="color"/> - <!-- @hide --> <attr name="customColorShadeDisabled" format="color"/> <!-- @hide --> - <attr name="customColorShadeInactive" format="color"/> - <!-- @hide --> - <attr name="customColorThemeApp" format="color"/> - <!-- @hide --> - <attr name="customColorThemeAppRing" format="color"/> - <!-- @hide --> - <attr name="customColorThemeNotif" format="color"/> - <!-- @hide --> - <attr name="customColorUnderSurface" format="color"/> - <!-- @hide --> - <attr name="customColorWeatherTemp" format="color"/> - <!-- @hide --> - <attr name="customColorWidgetBackground" format="color"/> + <attr name="customColorOverviewBackground" format="color"/> </declare-styleable> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 41dec3776b5c..7ef539492aa4 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1855,13 +1855,23 @@ {@link android.R.styleable#AndroidManifestProcess process} tag, or to an {@link android.R.styleable#AndroidManifestApplication application} tag (to supply a default setting for all application components). --> - <attr name="memtagMode"> + <attr name="memtagMode"> <enum name="default" value="-1" /> <enum name="off" value="0" /> <enum name="async" value="1" /> <enum name="sync" value="2" /> </attr> + <!-- This attribute will be used to override app compatibility mode on 16 KB devices. + If set to enabled, Natives lib will be extracted from APK if they are not page aligned on + 16 KB device. 4 KB natives libs will be loaded app-compat mode if they are eligible. + @FlaggedApi(android.content.pm.Flags.FLAG_APP_COMPAT_OPTION_16KB) --> + <attr name="pageSizeCompat"> + <enum name="enabled" value="5" /> + <enum name="disabled" value="6" /> + </attr> + + <!-- Attribution tag to be used for permission sub-attribution if a permission is checked in {@link android.content.Context#sendBroadcast(Intent, String)}. Multiple tags can be specified separated by '|'. @@ -2212,6 +2222,9 @@ <attr name="memtagMode" /> + <!-- @FlaggedApi(android.content.pm.Flags.FLAG_APP_COMPAT_OPTION_16KB) --> + <attr name="pageSizeCompat" /> + <!-- If {@code true} enables automatic zero initialization of all native heap allocations. --> <attr name="nativeHeapZeroInitialized" format="boolean" /> diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index 13dd4a35564c..f5bb554b0b32 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -238,319 +238,393 @@ <color name="conversation_important_highlight">#F9AB00</color> - <!--Lightest shade of the Primary color used by the system. White. This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Lightest shade of the Primary color used by the system. White. + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_0">#FFFFFF</color> - <!--Shade of the Primary system color at 99% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Primary system color at 99% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_10">#FEFBFF</color> - <!--Shade of the Primary system color at 95% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Primary system color at 95% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_50">#EEF0FF</color> - <!--Shade of the Primary system color at 90% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Primary system color at 90% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_100">#D9E2FF</color> - <!--Shade of the Primary system color at 80% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Primary system color at 80% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_200">#B0C6FF</color> - <!--Shade of the Primary system color at 70% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Primary system color at 70% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_300">#94AAE4</color> - <!--Shade of the Primary system color at 60% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Primary system color at 60% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_400">#7A90C8</color> - <!--Shade of the Primary system color at 50% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Primary system color at 50% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_500">#6076AC</color> - <!--Shade of the Primary system color at 40% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Primary system color at 40% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_600">#475D92</color> - <!--Shade of the Primary system color at 30% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Primary system color at 30% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_700">#2F4578</color> - <!--Shade of the Primary system color at 20% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Primary system color at 20% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_800">#152E60</color> - <!--Shade of the Primary system color at 10% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Primary system color at 10% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_900">#001945</color> - <!--Darkest shade of the Primary color used by the system. Black. This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Darkest shade of the Primary color used by the system. Black. + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent1_1000">#000000</color> - <!--Lightest shade of the Secondary color used by the system. White. This value can be overlaid at runtime by OverlayManager RROs.--> + + <!--Lightest shade of the Secondary color used by the system. White. + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_0">#FFFFFF</color> - <!--Shade of the Secondary system color at 99% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary system color at 99% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_10">#FEFBFF</color> - <!--Shade of the Secondary system color at 95% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary system color at 95% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_50">#EEF0FF</color> - <!--Shade of the Secondary system color at 90% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary system color at 90% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_100">#DCE2F9</color> - <!--Shade of the Secondary system color at 80% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary system color at 80% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_200">#C0C6DC</color> - <!--Shade of the Secondary system color at 70% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary system color at 70% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_300">#A4ABC1</color> - <!--Shade of the Secondary system color at 60% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary system color at 60% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_400">#8A90A5</color> - <!--Shade of the Secondary system color at 50% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary system color at 50% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_500">#70778B</color> - <!--Shade of the Secondary system color at 40% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary system color at 40% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_600">#575E71</color> - <!--Shade of the Secondary system color at 30% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary system color at 30% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_700">#404659</color> - <!--Shade of the Secondary system color at 20% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary system color at 20% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_800">#2A3042</color> - <!--Shade of the Secondary system color at 10% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary system color at 10% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_900">#151B2C</color> - <!--Darkest shade of the Secondary color used by the system. Black. This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Darkest shade of the Secondary color used by the system. Black. + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent2_1000">#000000</color> - <!--Lightest shade of the Tertiary color used by the system. White. This value can be overlaid at runtime by OverlayManager RROs.--> + + <!--Lightest shade of the Tertiary color used by the system. White. + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_0">#FFFFFF</color> - <!--Shade of the Tertiary system color at 99% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Tertiary system color at 99% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_10">#FFFBFF</color> - <!--Shade of the Tertiary system color at 95% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Tertiary system color at 95% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_50">#FFEBFA</color> - <!--Shade of the Tertiary system color at 90% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Tertiary system color at 90% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_100">#FDD7FA</color> - <!--Shade of the Tertiary system color at 80% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Tertiary system color at 80% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_200">#E0BBDD</color> - <!--Shade of the Tertiary system color at 70% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Tertiary system color at 70% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_300">#C3A0C1</color> - <!--Shade of the Tertiary system color at 60% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Tertiary system color at 60% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_400">#A886A6</color> - <!--Shade of the Tertiary system color at 50% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Tertiary system color at 50% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_500">#8C6D8C</color> - <!--Shade of the Tertiary system color at 40% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Tertiary system color at 40% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_600">#725572</color> - <!--Shade of the Tertiary system color at 30% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Tertiary system color at 30% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_700">#593D59</color> - <!--Shade of the Tertiary system color at 20% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Tertiary system color at 20% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_800">#412742</color> - <!--Shade of the Tertiary system color at 10% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Tertiary system color at 10% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_900">#2A122C</color> - <!--Darkest shade of the Tertiary color used by the system. Black. This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Darkest shade of the Tertiary color used by the system. Black. + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_accent3_1000">#000000</color> - <!--Lightest shade of the Neutral color used by the system. White. This value can be overlaid at runtime by OverlayManager RROs.--> + + <!--Lightest shade of the Neutral color used by the system. White. + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_0">#FFFFFF</color> - <!--Shade of the Neutral system color at 99% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Neutral system color at 99% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_10">#FEFBFF</color> - <!--Shade of the Neutral system color at 95% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Neutral system color at 95% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_50">#F1F0F7</color> - <!--Shade of the Neutral system color at 90% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Neutral system color at 90% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_100">#E2E2E9</color> - <!--Shade of the Neutral system color at 80% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Neutral system color at 80% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_200">#C6C6CD</color> - <!--Shade of the Neutral system color at 70% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Neutral system color at 70% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_300">#ABABB1</color> - <!--Shade of the Neutral system color at 60% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Neutral system color at 60% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_400">#909097</color> - <!--Shade of the Neutral system color at 50% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Neutral system color at 50% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_500">#76777D</color> - <!--Shade of the Neutral system color at 40% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Neutral system color at 40% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_600">#5D5E64</color> - <!--Shade of the Neutral system color at 30% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Neutral system color at 30% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_700">#45464C</color> - <!--Shade of the Neutral system color at 20% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Neutral system color at 20% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_800">#2F3036</color> - <!--Shade of the Neutral system color at 10% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Neutral system color at 10% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_900">#1A1B20</color> - <!--Darkest shade of the Neutral color used by the system. Black. This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Darkest shade of the Neutral color used by the system. Black. + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral1_1000">#000000</color> - <!--Lightest shade of the Secondary Neutral color used by the system. White. This value can be overlaid at runtime by OverlayManager RROs.--> + + <!--Lightest shade of the Secondary Neutral color used by the system. White. + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_0">#FFFFFF</color> - <!--Shade of the Secondary Neutral system color at 99% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary Neutral system color at 99% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_10">#FEFBFF</color> - <!--Shade of the Secondary Neutral system color at 95% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary Neutral system color at 95% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_50">#F0F0FA</color> - <!--Shade of the Secondary Neutral system color at 90% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary Neutral system color at 90% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_100">#E1E2EC</color> - <!--Shade of the Secondary Neutral system color at 80% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary Neutral system color at 80% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_200">#C5C6D0</color> - <!--Shade of the Secondary Neutral system color at 70% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary Neutral system color at 70% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_300">#A9ABB4</color> - <!--Shade of the Secondary Neutral system color at 60% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary Neutral system color at 60% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_400">#8F9099</color> - <!--Shade of the Secondary Neutral system color at 50% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary Neutral system color at 50% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_500">#757780</color> - <!--Shade of the Secondary Neutral system color at 40% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary Neutral system color at 40% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_600">#5C5E67</color> - <!--Shade of the Secondary Neutral system color at 30% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary Neutral system color at 30% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_700">#44464F</color> - <!--Shade of the Secondary Neutral system color at 20% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary Neutral system color at 20% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_800">#2E3038</color> - <!--Shade of the Secondary Neutral system color at 10% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Shade of the Secondary Neutral system color at 10% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_900">#191B23</color> - <!--Darkest shade of the Secondary Neutral color used by the system. Black. This value can be overlaid at runtime by OverlayManager RROs.--> + <!--Darkest shade of the Secondary Neutral color used by the system. Black. + This value can be overlaid at runtime by OverlayManager RROs.--> <color name="system_neutral2_1000">#000000</color> - <!--Lightest shade of the Error color used by the system. White. This value can be overlaid at runtime by OverlayManager RROs.--> - <color name="system_error_0">#FFFFFF</color> - <!--Shade of the Error system color at 99% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> - <color name="system_error_10">#FFFBFF</color> - <!--Shade of the Error system color at 95% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> - <color name="system_error_50">#FFEDEA</color> - <!--Shade of the Error system color at 90% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> - <color name="system_error_100">#FFDAD6</color> - <!--Shade of the Error system color at 80% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> - <color name="system_error_200">#FFB4AB</color> - <!--Shade of the Error system color at 70% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> - <color name="system_error_300">#FF897D</color> - <!--Shade of the Error system color at 60% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> - <color name="system_error_400">#FF5449</color> - <!--Shade of the Error system color at 50% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> - <color name="system_error_500">#DE3730</color> - <!--Shade of the Error system color at 40% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> - <color name="system_error_600">#BA1A1A</color> - <!--Shade of the Error system color at 30% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> - <color name="system_error_700">#93000A</color> - <!--Shade of the Error system color at 20% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> - <color name="system_error_800">#690005</color> - <!--Shade of the Error system color at 10% perceptual luminance (L* in L*a*b* color space). This value can be overlaid at runtime by OverlayManager RROs.--> - <color name="system_error_900">#410002</color> - <!--Darkest shade of the Error color used by the system. Black. This value can be overlaid at runtime by OverlayManager RROs.--> + + <!-- Lightest shade of the error color used by the system. White. + This value can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_error_0">#ffffff</color> + <!-- Shade of the error system color at 99% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_error_10">#FFFBF9</color> + <!-- Shade of the error system color at 95% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_error_50">#FCEEEE</color> + <!-- Shade of the error system color at 90% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_error_100">#F9DEDC</color> + <!-- Shade of the error system color at 80% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_error_200">#F2B8B5</color> + <!-- Shade of the error system color at 70% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_error_300">#EC928E</color> + <!-- Shade of the error system color at 60% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_error_400">#E46962</color> + <!-- Shade of the error system color at 49% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_error_500">#DC362E</color> + <!-- Shade of the error system color at 40% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_error_600">#B3261E</color> + <!-- Shade of the error system color at 30% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_error_700">#8C1D18</color> + <!-- Shade of the error system color at 20% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_error_800">#601410</color> + <!-- Shade of the error system color at 10% perceptual luminance (L* in L*a*b* color space). + This value can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_error_900">#410E0B</color> + <!-- Darkest shade of the error color used by the system. Black. + This value can be overlaid at runtime by OverlayManager RROs. --> <color name="system_error_1000">#000000</color> - <!--Colors used in Android system, from design system. These values can be overlaid at runtime by OverlayManager RROs.--><color name="system_background_light">#FAF8FF</color> - <color name="system_control_activated_light">#D9E2FF</color> - <color name="system_control_highlight_light">#000000</color> - <color name="system_control_normal_light">#44464F</color> - <color name="system_error_light">#BA1A1A</color> - <color name="system_error_container_light">#FFDAD6</color> - <color name="system_inverse_on_surface_light">#F1F0F7</color> - <color name="system_inverse_primary_light">#B0C6FF</color> - <color name="system_inverse_surface_light">#2F3036</color> - <color name="system_on_background_light">#1A1B20</color> - <color name="system_on_error_light">#FFFFFF</color> - <color name="system_on_error_container_light">#93000A</color> + <!-- Colors used in Android system, from design system. + These values can be overlaid at runtime by OverlayManager RROs. --> + <color name="system_primary_container_light">#D9E2FF</color> + <color name="system_on_primary_container_light">#001945</color> + <color name="system_primary_light">#475D92</color> <color name="system_on_primary_light">#FFFFFF</color> - <color name="system_on_primary_container_light">#2F4578</color> + <color name="system_secondary_container_light">#DCE2F9</color> + <color name="system_on_secondary_container_light">#151B2C</color> + <color name="system_secondary_light">#575E71</color> <color name="system_on_secondary_light">#FFFFFF</color> - <color name="system_on_secondary_container_light">#404659</color> - <color name="system_on_surface_light">#1A1B20</color> - <color name="system_on_surface_variant_light">#44464F</color> + <color name="system_tertiary_container_light">#FDD7FA</color> + <color name="system_on_tertiary_container_light">#2A122C</color> + <color name="system_tertiary_light">#725572</color> <color name="system_on_tertiary_light">#FFFFFF</color> - <color name="system_on_tertiary_container_light">#593D59</color> - <color name="system_outline_light">#757780</color> - <color name="system_outline_variant_light">#C5C6D0</color> - <color name="system_palette_key_color_neutral_light">#76777D</color> - <color name="system_palette_key_color_neutral_variant_light">#757780</color> - <color name="system_palette_key_color_primary_light">#6076AC</color> - <color name="system_palette_key_color_secondary_light">#70778B</color> - <color name="system_palette_key_color_tertiary_light">#8C6D8C</color> - <color name="system_primary_light">#475D92</color> - <color name="system_primary_container_light">#D9E2FF</color> - <color name="system_scrim_light">#000000</color> - <color name="system_secondary_light">#575E71</color> - <color name="system_secondary_container_light">#DCE2F9</color> - <color name="system_shadow_light">#000000</color> + <color name="system_background_light">#FAF8FF</color> + <color name="system_on_background_light">#1A1B20</color> <color name="system_surface_light">#FAF8FF</color> - <color name="system_surface_bright_light">#FAF8FF</color> + <color name="system_on_surface_light">#1A1B20</color> + <color name="system_surface_container_low_light">#F4F3FA</color> + <color name="system_surface_container_lowest_light">#FFFFFF</color> <color name="system_surface_container_light">#EEEDF4</color> <color name="system_surface_container_high_light">#E8E7EF</color> <color name="system_surface_container_highest_light">#E2E2E9</color> - <color name="system_surface_container_low_light">#F4F3FA</color> - <color name="system_surface_container_lowest_light">#FFFFFF</color> + <color name="system_surface_bright_light">#FAF8FF</color> <color name="system_surface_dim_light">#DAD9E0</color> - <color name="system_surface_tint_light">#475D92</color> <color name="system_surface_variant_light">#E1E2EC</color> - <color name="system_tertiary_light">#725572</color> - <color name="system_tertiary_container_light">#FDD7FA</color> - <color name="system_text_hint_inverse_light">#E2E2E9</color> - <color name="system_text_primary_inverse_light">#E2E2E9</color> - <color name="system_text_primary_inverse_disable_only_light">#E2E2E9</color> + <color name="system_on_surface_variant_light">#44464F</color> + <color name="system_outline_light">#757780</color> + <color name="system_outline_variant_light">#C5C6D0</color> + <color name="system_error_light">#BA1A1A</color> + <color name="system_on_error_light">#FFFFFF</color> + <color name="system_error_container_light">#FFDAD6</color> + <color name="system_on_error_container_light">#410002</color> + <color name="system_control_activated_light">#D9E2FF</color> + <color name="system_control_normal_light">#44464F</color> + <color name="system_control_highlight_light">#000000</color> +<color name="system_text_primary_inverse_light">#E2E2E9</color> <color name="system_text_secondary_and_tertiary_inverse_light">#C5C6D0</color> + <color name="system_text_primary_inverse_disable_only_light">#E2E2E9</color> <color name="system_text_secondary_and_tertiary_inverse_disabled_light">#E2E2E9</color> - <color name="system_background_dark">#121318</color> - <color name="system_control_activated_dark">#2F4578</color> - <color name="system_control_highlight_dark">#FFFFFF</color> - <color name="system_control_normal_dark">#C5C6D0</color> - <color name="system_error_dark">#FFB4AB</color> - <color name="system_error_container_dark">#93000A</color> - <color name="system_inverse_on_surface_dark">#2F3036</color> - <color name="system_inverse_primary_dark">#475D92</color> - <color name="system_inverse_surface_dark">#E2E2E9</color> - <color name="system_on_background_dark">#E2E2E9</color> - <color name="system_on_error_dark">#690005</color> - <color name="system_on_error_container_dark">#FFDAD6</color> - <color name="system_on_primary_dark">#152E60</color> + <color name="system_text_hint_inverse_light">#E2E2E9</color> + <color name="system_palette_key_color_primary_light">#6076AC</color> + <color name="system_palette_key_color_secondary_light">#70778B</color> + <color name="system_palette_key_color_tertiary_light">#8C6D8C</color> + <color name="system_palette_key_color_neutral_light">#76777D</color> + <color name="system_palette_key_color_neutral_variant_light">#757780</color> + <color name="system_primary_container_dark">#2F4578</color> <color name="system_on_primary_container_dark">#D9E2FF</color> - <color name="system_on_secondary_dark">#2A3042</color> - <color name="system_on_secondary_container_dark">#DCE2F9</color> - <color name="system_on_surface_dark">#E2E2E9</color> - <color name="system_on_surface_variant_dark">#C5C6D0</color> - <color name="system_on_tertiary_dark">#412742</color> - <color name="system_on_tertiary_container_dark">#FDD7FA</color> - <color name="system_outline_dark">#8F9099</color> - <color name="system_outline_variant_dark">#44464F</color> - <color name="system_palette_key_color_neutral_dark">#76777D</color> - <color name="system_palette_key_color_neutral_variant_dark">#757780</color> - <color name="system_palette_key_color_primary_dark">#6076AC</color> - <color name="system_palette_key_color_secondary_dark">#70778B</color> - <color name="system_palette_key_color_tertiary_dark">#8C6D8C</color> <color name="system_primary_dark">#B0C6FF</color> - <color name="system_primary_container_dark">#2F4578</color> - <color name="system_scrim_dark">#000000</color> - <color name="system_secondary_dark">#C0C6DC</color> + <color name="system_on_primary_dark">#152E60</color> <color name="system_secondary_container_dark">#404659</color> - <color name="system_shadow_dark">#000000</color> + <color name="system_on_secondary_container_dark">#DCE2F9</color> + <color name="system_secondary_dark">#C0C6DC</color> + <color name="system_on_secondary_dark">#2A3042</color> + <color name="system_tertiary_container_dark">#593D59</color> + <color name="system_on_tertiary_container_dark">#FDD7FA</color> + <color name="system_tertiary_dark">#E0BBDD</color> + <color name="system_on_tertiary_dark">#412742</color> + <color name="system_background_dark">#121318</color> + <color name="system_on_background_dark">#E2E2E9</color> <color name="system_surface_dark">#121318</color> - <color name="system_surface_bright_dark">#38393F</color> + <color name="system_on_surface_dark">#E2E2E9</color> + <color name="system_surface_container_low_dark">#1A1B20</color> + <color name="system_surface_container_lowest_dark">#0C0E13</color> <color name="system_surface_container_dark">#1E1F25</color> <color name="system_surface_container_high_dark">#282A2F</color> <color name="system_surface_container_highest_dark">#33343A</color> - <color name="system_surface_container_low_dark">#1A1B20</color> - <color name="system_surface_container_lowest_dark">#0C0E13</color> + <color name="system_surface_bright_dark">#38393F</color> <color name="system_surface_dim_dark">#121318</color> - <color name="system_surface_tint_dark">#B0C6FF</color> <color name="system_surface_variant_dark">#44464F</color> - <color name="system_tertiary_dark">#E0BBDD</color> - <color name="system_tertiary_container_dark">#593D59</color> - <color name="system_text_hint_inverse_dark">#1A1B20</color> + <color name="system_on_surface_variant_dark">#C5C6D0</color> + <color name="system_outline_dark">#8F9099</color> + <color name="system_outline_variant_dark">#44464F</color> + <color name="system_error_dark">#FFB4AB</color> + <color name="system_on_error_dark">#690005</color> + <color name="system_error_container_dark">#93000A</color> + <color name="system_on_error_container_dark">#FFDAD6</color> + <color name="system_control_activated_dark">#2F4578</color> + <color name="system_control_normal_dark">#C5C6D0</color> + <color name="system_control_highlight_dark">#FFFFFF</color> <color name="system_text_primary_inverse_dark">#1A1B20</color> - <color name="system_text_primary_inverse_disable_only_dark">#1A1B20</color> <color name="system_text_secondary_and_tertiary_inverse_dark">#44464F</color> + <color name="system_text_primary_inverse_disable_only_dark">#1A1B20</color> <color name="system_text_secondary_and_tertiary_inverse_disabled_dark">#1A1B20</color> - <color name="system_on_primary_fixed">#001945</color> - <color name="system_on_primary_fixed_variant">#2F4578</color> - <color name="system_on_secondary_fixed">#151B2C</color> - <color name="system_on_secondary_fixed_variant">#404659</color> - <color name="system_on_tertiary_fixed">#2A122C</color> - <color name="system_on_tertiary_fixed_variant">#593D59</color> + <color name="system_text_hint_inverse_dark">#1A1B20</color> + <color name="system_palette_key_color_primary_dark">#6076AC</color> + <color name="system_palette_key_color_secondary_dark">#70778B</color> + <color name="system_palette_key_color_tertiary_dark">#8C6D8C</color> + <color name="system_palette_key_color_neutral_dark">#76777D</color> + <color name="system_palette_key_color_neutral_variant_dark">#757780</color> <color name="system_primary_fixed">#D9E2FF</color> <color name="system_primary_fixed_dim">#B0C6FF</color> + <color name="system_on_primary_fixed">#001945</color> + <color name="system_on_primary_fixed_variant">#2F4578</color> <color name="system_secondary_fixed">#DCE2F9</color> <color name="system_secondary_fixed_dim">#C0C6DC</color> + <color name="system_on_secondary_fixed">#151B2C</color> + <color name="system_on_secondary_fixed_variant">#404659</color> <color name="system_tertiary_fixed">#FDD7FA</color> <color name="system_tertiary_fixed_dim">#E0BBDD</color> + <color name="system_on_tertiary_fixed">#2A122C</color> + <color name="system_on_tertiary_fixed_variant">#593D59</color> + + <!--Colors used in Android system, from design system. These values can be overlaid at runtime + by OverlayManager RROs.--> + <color name="system_widget_background_light">#EEF0FF</color> + <color name="system_clock_hour_light">#373D50</color> + <color name="system_clock_minute_light">#3D5487</color> + <color name="system_clock_second_light">#4F659A</color> + <color name="system_theme_app_light">#D9E2FF</color> + <color name="system_on_theme_app_light">#475D92</color> + <color name="system_theme_app_ring_light">#94AAE4</color> + <color name="system_theme_notif_light">#E0BBDD</color> <color name="system_brand_a_light">#475D92</color> <color name="system_brand_b_light">#6E7488</color> <color name="system_brand_c_light">#5E73A9</color> <color name="system_brand_d_light">#8A6A89</color> - <color name="system_clock_hour_light">#373D50</color> - <color name="system_clock_minute_light">#3D5487</color> - <color name="system_clock_second_light">#725572</color> + <color name="system_under_surface_light">#000000</color> +<color name="system_shade_active_light">#D9E2FF</color> <color name="system_on_shade_active_light">#152E60</color> <color name="system_on_shade_active_variant_light">#2F4578</color> + <color name="system_shade_inactive_light">#2F3036</color> <color name="system_on_shade_inactive_light">#E1E2EC</color> <color name="system_on_shade_inactive_variant_light">#C5C6D0</color> - <color name="system_on_theme_app_light">#475D92</color> - <color name="system_overview_background_light">#C5C6D0</color> - <color name="system_shade_active_light">#D9E2FF</color> <color name="system_shade_disabled_light">#0C0E13</color> - <color name="system_shade_inactive_light">#2F3036</color> - <color name="system_theme_app_light">#D9E2FF</color> - <color name="system_theme_app_ring_light">#94AAE4</color> - <color name="system_theme_notif_light">#E0BBDD</color> - <color name="system_under_surface_light">#000000</color> - <color name="system_weather_temp_light">#4F659A</color> - <color name="system_widget_background_light">#EEF0FF</color> + <color name="system_overview_background_light">#C5C6D0</color> + <color name="system_widget_background_dark">#152E60</color> + <color name="system_clock_hour_dark">#8A90A5</color> + <color name="system_clock_minute_dark">#D9E2FF</color> + <color name="system_clock_second_dark">#B0C6FF</color> + <color name="system_theme_app_dark">#2F4578</color> + <color name="system_on_theme_app_dark">#B0C6FF</color> + <color name="system_theme_app_ring_dark">#94AAE4</color> + <color name="system_theme_notif_dark">#FDD7FA</color> <color name="system_brand_a_dark">#B0C6FF</color> <color name="system_brand_b_dark">#DCE2F9</color> <color name="system_brand_c_dark">#7A90C8</color> <color name="system_brand_d_dark">#FDD7FA</color> - <color name="system_clock_hour_dark">#8A90A5</color> - <color name="system_clock_minute_dark">#D9E2FF</color> - <color name="system_clock_second_dark">#FDD7FA</color> + <color name="system_under_surface_dark">#000000</color> +<color name="system_shade_active_dark">#D9E2FF</color> <color name="system_on_shade_active_dark">#001945</color> <color name="system_on_shade_active_variant_dark">#2F4578</color> + <color name="system_shade_inactive_dark">#2F3036</color> <color name="system_on_shade_inactive_dark">#E1E2EC</color> <color name="system_on_shade_inactive_variant_dark">#C5C6D0</color> - <color name="system_on_theme_app_dark">#B0C6FF</color> - <color name="system_overview_background_dark">#50525A</color> - <color name="system_shade_active_dark">#D9E2FF</color> <color name="system_shade_disabled_dark">#0C0E13</color> - <color name="system_shade_inactive_dark">#2F3036</color> - <color name="system_theme_app_dark">#2F4578</color> - <color name="system_theme_app_ring_dark">#94AAE4</color> - <color name="system_theme_notif_dark">#FDD7FA</color> - <color name="system_under_surface_dark">#000000</color> - <color name="system_weather_temp_dark">#B0C6FF</color> - <color name="system_widget_background_dark">#152E60</color> + <color name="system_overview_background_dark">#50525A</color> <!-- Accessibility shortcut icon background color --> <color name="accessibility_feature_background">#5F6368</color> <!-- Google grey 700 --> diff --git a/core/res/res/values/colors_dynamic.xml b/core/res/res/values/colors_dynamic.xml deleted file mode 100644 index ab283eb3c6c8..000000000000 --- a/core/res/res/values/colors_dynamic.xml +++ /dev/null @@ -1,103 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2024 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<!-- Colors specific to Material themes. --> -<resources> - <color name="materialColorBackground">@color/system_background_light</color> - <color name="materialColorControlActivated">@color/system_control_activated_light</color> - <color name="materialColorControlHighlight">@color/system_control_highlight_light</color> - <color name="materialColorControlNormal">@color/system_control_normal_light</color> - <color name="materialColorError">@color/system_error_light</color> - <color name="materialColorErrorContainer">@color/system_error_container_light</color> - <color name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</color> - <color name="materialColorInversePrimary">@color/system_inverse_primary_light</color> - <color name="materialColorInverseSurface">@color/system_inverse_surface_light</color> - <color name="materialColorOnBackground">@color/system_on_background_light</color> - <color name="materialColorOnError">@color/system_on_error_light</color> - <color name="materialColorOnErrorContainer">@color/system_on_error_container_light</color> - <color name="materialColorOnPrimary">@color/system_on_primary_light</color> - <color name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</color> - <color name="materialColorOnSecondary">@color/system_on_secondary_light</color> - <color name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</color> - <color name="materialColorOnSurface">@color/system_on_surface_light</color> - <color name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</color> - <color name="materialColorOnTertiary">@color/system_on_tertiary_light</color> - <color name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</color> - <color name="materialColorOutline">@color/system_outline_light</color> - <color name="materialColorOutlineVariant">@color/system_outline_variant_light</color> - <color name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</color> - <color name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</color> - <color name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</color> - <color name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</color> - <color name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</color> - <color name="materialColorPrimary">@color/system_primary_light</color> - <color name="materialColorPrimaryContainer">@color/system_primary_container_light</color> - <color name="materialColorScrim">@color/system_scrim_light</color> - <color name="materialColorSecondary">@color/system_secondary_light</color> - <color name="materialColorSecondaryContainer">@color/system_secondary_container_light</color> - <color name="materialColorShadow">@color/system_shadow_light</color> - <color name="materialColorSurface">@color/system_surface_light</color> - <color name="materialColorSurfaceBright">@color/system_surface_bright_light</color> - <color name="materialColorSurfaceContainer">@color/system_surface_container_light</color> - <color name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</color> - <color name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</color> - <color name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</color> - <color name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</color> - <color name="materialColorSurfaceDim">@color/system_surface_dim_light</color> - <color name="materialColorSurfaceTint">@color/system_surface_tint_light</color> - <color name="materialColorSurfaceVariant">@color/system_surface_variant_light</color> - <color name="materialColorTertiary">@color/system_tertiary_light</color> - <color name="materialColorTertiaryContainer">@color/system_tertiary_container_light</color> - <color name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</color> - <color name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</color> - <color name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</color> - <color name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</color> - <color name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</color> - <color name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</color> - <color name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</color> - <color name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</color> - <color name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</color> - <color name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</color> - <color name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</color> - <color name="materialColorPrimaryFixed">@color/system_primary_fixed</color> - <color name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</color> - <color name="materialColorSecondaryFixed">@color/system_secondary_fixed</color> - <color name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</color> - <color name="materialColorTertiaryFixed">@color/system_tertiary_fixed</color> - <color name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</color> - <color name="customColorBrandA">@color/system_brand_a_light</color> - <color name="customColorBrandB">@color/system_brand_b_light</color> - <color name="customColorBrandC">@color/system_brand_c_light</color> - <color name="customColorBrandD">@color/system_brand_d_light</color> - <color name="customColorClockHour">@color/system_clock_hour_light</color> - <color name="customColorClockMinute">@color/system_clock_minute_light</color> - <color name="customColorClockSecond">@color/system_clock_second_light</color> - <color name="customColorOnShadeActive">@color/system_on_shade_active_light</color> - <color name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</color> - <color name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</color> - <color name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</color> - <color name="customColorOnThemeApp">@color/system_on_theme_app_light</color> - <color name="customColorOverviewBackground">@color/system_overview_background_light</color> - <color name="customColorShadeActive">@color/system_shade_active_light</color> - <color name="customColorShadeDisabled">@color/system_shade_disabled_light</color> - <color name="customColorShadeInactive">@color/system_shade_inactive_light</color> - <color name="customColorThemeApp">@color/system_theme_app_light</color> - <color name="customColorThemeAppRing">@color/system_theme_app_ring_light</color> - <color name="customColorThemeNotif">@color/system_theme_notif_light</color> - <color name="customColorUnderSurface">@color/system_under_surface_light</color> - <color name="customColorWeatherTemp">@color/system_weather_temp_light</color> - <color name="customColorWidgetBackground">@color/system_widget_background_light</color> -</resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index dc054a4a48ea..969ee2e16deb 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1849,6 +1849,10 @@ <item>-1</item> </integer-array> + <!-- Specifies the delay in milliseconds after the last user input before turning off the + keyboard backlight. + --> + <integer name="config_keyboardBacklightTimeoutMs">30000</integer> <!-- An array describing the screen's backlight values corresponding to the brightness values in the config_screenBrightnessNits array. diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml index 612c72fc73a1..a0bf89d66923 100644 --- a/core/res/res/values/public-staging.xml +++ b/core/res/res/values/public-staging.xml @@ -131,6 +131,8 @@ <public name="alternateLauncherIcons"/> <!-- @FlaggedApi(android.content.pm.Flags.FLAG_CHANGE_LAUNCHER_BADGING) --> <public name="alternateLauncherLabels"/> + <!-- @FlaggedApi(android.content.pm.Flags.FLAG_APP_COMPAT_OPTION_16KB) --> + <public name="pageSizeCompat" /> </staging-public-group> <staging-public-group type="id" first-id="0x01b60000"> @@ -146,30 +148,6 @@ </staging-public-group> <staging-public-group type="color" first-id="0x01b20000"> - <!-- @FlaggedApi("com.android.systemui.material_colors_10_2024")--> - <public name="system_inverse_on_surface_light"/> - <!-- @FlaggedApi("com.android.systemui.material_colors_10_2024")--> - <public name="system_inverse_primary_light"/> - <!-- @FlaggedApi("com.android.systemui.material_colors_10_2024")--> - <public name="system_inverse_surface_light"/> - <!-- @FlaggedApi("com.android.systemui.material_colors_10_2024")--> - <public name="system_scrim_light"/> - <!-- @FlaggedApi("com.android.systemui.material_colors_10_2024")--> - <public name="system_shadow_light"/> - <!-- @FlaggedApi("com.android.systemui.material_colors_10_2024")--> - <public name="system_surface_tint_light"/> - <!-- @FlaggedApi("com.android.systemui.material_colors_10_2024")--> - <public name="system_inverse_on_surface_dark"/> - <!-- @FlaggedApi("com.android.systemui.material_colors_10_2024")--> - <public name="system_inverse_primary_dark"/> - <!-- @FlaggedApi("com.android.systemui.material_colors_10_2024")--> - <public name="system_inverse_surface_dark"/> - <!-- @FlaggedApi("com.android.systemui.material_colors_10_2024")--> - <public name="system_scrim_dark"/> - <!-- @FlaggedApi("com.android.systemui.material_colors_10_2024")--> - <public name="system_shadow_dark"/> - <!-- @FlaggedApi("com.android.systemui.material_colors_10_2024")--> - <public name="system_surface_tint_dark"/> </staging-public-group> <staging-public-group type="array" first-id="0x01b10000"> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index c792153d1e6f..9dd302784c2c 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2098,6 +2098,7 @@ <java-symbol type="integer" name="config_autoBrightnessDarkeningLightDebounce"/> <java-symbol type="integer" name="config_autoBrightnessInitialLightSensorRate"/> <java-symbol type="integer" name="config_autoBrightnessLightSensorRate"/> + <java-symbol type="integer" name="config_keyboardBacklightTimeoutMs" /> <java-symbol type="integer" name="config_carDockKeepsScreenOn" /> <java-symbol type="integer" name="config_criticalBatteryWarningLevel" /> <java-symbol type="integer" name="config_datause_notification_type" /> @@ -5310,91 +5311,73 @@ <java-symbol type="integer" name="config_aggregatedPowerStatsSpanDuration" /> <java-symbol type="integer" name="config_accumulatedBatteryUsageStatsSpanSize" /> - <!--Dynamic Tokens--> - <java-symbol type="attr" name="materialColorBackground"/> - <java-symbol type="attr" name="materialColorControlActivated"/> - <java-symbol type="attr" name="materialColorControlHighlight"/> - <java-symbol type="attr" name="materialColorControlNormal"/> - <java-symbol type="attr" name="materialColorError"/> - <java-symbol type="attr" name="materialColorErrorContainer"/> - <java-symbol type="attr" name="materialColorInverseOnSurface"/> - <java-symbol type="attr" name="materialColorInversePrimary"/> - <java-symbol type="attr" name="materialColorInverseSurface"/> - <java-symbol type="attr" name="materialColorOnBackground"/> - <java-symbol type="attr" name="materialColorOnError"/> - <java-symbol type="attr" name="materialColorOnErrorContainer"/> - <java-symbol type="attr" name="materialColorOnPrimary"/> - <java-symbol type="attr" name="materialColorOnPrimaryContainer"/> - <java-symbol type="attr" name="materialColorOnSecondary"/> - <java-symbol type="attr" name="materialColorOnSecondaryContainer"/> - <java-symbol type="attr" name="materialColorOnSurface"/> - <java-symbol type="attr" name="materialColorOnSurfaceVariant"/> - <java-symbol type="attr" name="materialColorOnTertiary"/> - <java-symbol type="attr" name="materialColorOnTertiaryContainer"/> - <java-symbol type="attr" name="materialColorOutline"/> - <java-symbol type="attr" name="materialColorOutlineVariant"/> - <java-symbol type="attr" name="materialColorPaletteKeyColorNeutral"/> - <java-symbol type="attr" name="materialColorPaletteKeyColorNeutralVariant"/> - <java-symbol type="attr" name="materialColorPaletteKeyColorPrimary"/> - <java-symbol type="attr" name="materialColorPaletteKeyColorSecondary"/> - <java-symbol type="attr" name="materialColorPaletteKeyColorTertiary"/> - <java-symbol type="attr" name="materialColorPrimary"/> - <java-symbol type="attr" name="materialColorPrimaryContainer"/> - <java-symbol type="attr" name="materialColorScrim"/> - <java-symbol type="attr" name="materialColorSecondary"/> - <java-symbol type="attr" name="materialColorSecondaryContainer"/> - <java-symbol type="attr" name="materialColorShadow"/> - <java-symbol type="attr" name="materialColorSurface"/> - <java-symbol type="attr" name="materialColorSurfaceBright"/> - <java-symbol type="attr" name="materialColorSurfaceContainer"/> - <java-symbol type="attr" name="materialColorSurfaceContainerHigh"/> - <java-symbol type="attr" name="materialColorSurfaceContainerHighest"/> - <java-symbol type="attr" name="materialColorSurfaceContainerLow"/> - <java-symbol type="attr" name="materialColorSurfaceContainerLowest"/> - <java-symbol type="attr" name="materialColorSurfaceDim"/> - <java-symbol type="attr" name="materialColorSurfaceTint"/> - <java-symbol type="attr" name="materialColorSurfaceVariant"/> - <java-symbol type="attr" name="materialColorTertiary"/> - <java-symbol type="attr" name="materialColorTertiaryContainer"/> - <java-symbol type="attr" name="materialColorTextHintInverse"/> - <java-symbol type="attr" name="materialColorTextPrimaryInverse"/> - <java-symbol type="attr" name="materialColorTextPrimaryInverseDisableOnly"/> - <java-symbol type="attr" name="materialColorTextSecondaryAndTertiaryInverse"/> - <java-symbol type="attr" name="materialColorTextSecondaryAndTertiaryInverseDisabled"/> - <java-symbol type="attr" name="materialColorOnPrimaryFixed"/> - <java-symbol type="attr" name="materialColorOnPrimaryFixedVariant"/> - <java-symbol type="attr" name="materialColorOnSecondaryFixed"/> - <java-symbol type="attr" name="materialColorOnSecondaryFixedVariant"/> - <java-symbol type="attr" name="materialColorOnTertiaryFixed"/> - <java-symbol type="attr" name="materialColorOnTertiaryFixedVariant"/> - <java-symbol type="attr" name="materialColorPrimaryFixed"/> - <java-symbol type="attr" name="materialColorPrimaryFixedDim"/> - <java-symbol type="attr" name="materialColorSecondaryFixed"/> - <java-symbol type="attr" name="materialColorSecondaryFixedDim"/> - <java-symbol type="attr" name="materialColorTertiaryFixed"/> - <java-symbol type="attr" name="materialColorTertiaryFixedDim"/> - <java-symbol type="attr" name="customColorBrandA"/> - <java-symbol type="attr" name="customColorBrandB"/> - <java-symbol type="attr" name="customColorBrandC"/> - <java-symbol type="attr" name="customColorBrandD"/> - <java-symbol type="attr" name="customColorClockHour"/> - <java-symbol type="attr" name="customColorClockMinute"/> - <java-symbol type="attr" name="customColorClockSecond"/> - <java-symbol type="attr" name="customColorOnShadeActive"/> - <java-symbol type="attr" name="customColorOnShadeActiveVariant"/> - <java-symbol type="attr" name="customColorOnShadeInactive"/> - <java-symbol type="attr" name="customColorOnShadeInactiveVariant"/> - <java-symbol type="attr" name="customColorOnThemeApp"/> - <java-symbol type="attr" name="customColorOverviewBackground"/> - <java-symbol type="attr" name="customColorShadeActive"/> - <java-symbol type="attr" name="customColorShadeDisabled"/> - <java-symbol type="attr" name="customColorShadeInactive"/> - <java-symbol type="attr" name="customColorThemeApp"/> - <java-symbol type="attr" name="customColorThemeAppRing"/> - <java-symbol type="attr" name="customColorThemeNotif"/> - <java-symbol type="attr" name="customColorUnderSurface"/> - <java-symbol type="attr" name="customColorWeatherTemp"/> - <java-symbol type="attr" name="customColorWidgetBackground"/> + <java-symbol name="materialColorOnSecondaryFixedVariant" type="attr"/> + <java-symbol name="materialColorOnTertiaryFixedVariant" type="attr"/> + <java-symbol name="materialColorSurfaceContainerLowest" type="attr"/> + <java-symbol name="materialColorOnPrimaryFixedVariant" type="attr"/> + <java-symbol name="materialColorOnSecondaryContainer" type="attr"/> + <java-symbol name="materialColorOnTertiaryContainer" type="attr"/> + <java-symbol name="materialColorSurfaceContainerLow" type="attr"/> + <java-symbol name="materialColorOnPrimaryContainer" type="attr"/> + <java-symbol name="materialColorSecondaryFixedDim" type="attr"/> + <java-symbol name="materialColorOnErrorContainer" type="attr"/> + <java-symbol name="materialColorOnSecondaryFixed" type="attr"/> + <java-symbol name="materialColorOnSurfaceInverse" type="attr"/> + <java-symbol name="materialColorTertiaryFixedDim" type="attr"/> + <java-symbol name="materialColorOnTertiaryFixed" type="attr"/> + <java-symbol name="materialColorPrimaryFixedDim" type="attr"/> + <java-symbol name="materialColorSecondaryContainer" type="attr"/> + <java-symbol name="materialColorErrorContainer" type="attr"/> + <java-symbol name="materialColorOnPrimaryFixed" type="attr"/> + <java-symbol name="materialColorPrimaryInverse" type="attr"/> + <java-symbol name="materialColorSecondaryFixed" type="attr"/> + <java-symbol name="materialColorSurfaceInverse" type="attr"/> + <java-symbol name="materialColorSurfaceVariant" type="attr"/> + <java-symbol name="materialColorTertiaryContainer" type="attr"/> + <java-symbol name="materialColorTertiaryFixed" type="attr"/> + <java-symbol name="materialColorPrimaryContainer" type="attr"/> + <java-symbol name="materialColorOnBackground" type="attr"/> + <java-symbol name="materialColorPrimaryFixed" type="attr"/> + <java-symbol name="materialColorOnSecondary" type="attr"/> + <java-symbol name="materialColorOnTertiary" type="attr"/> + <java-symbol name="materialColorSurfaceDim" type="attr"/> + <java-symbol name="materialColorSurfaceBright" type="attr"/> + <java-symbol name="materialColorOnError" type="attr"/> + <java-symbol name="materialColorSurface" type="attr"/> + <java-symbol name="materialColorSurfaceContainerHigh" type="attr"/> + <java-symbol name="materialColorSurfaceContainerHighest" type="attr"/> + <java-symbol name="materialColorOnSurfaceVariant" type="attr"/> + <java-symbol name="materialColorOutline" type="attr"/> + <java-symbol name="materialColorOutlineVariant" type="attr"/> + <java-symbol name="materialColorOnPrimary" type="attr"/> + <java-symbol name="materialColorOnSurface" type="attr"/> + <java-symbol name="materialColorSurfaceContainer" type="attr"/> + <java-symbol name="materialColorPrimary" type="attr"/> + <java-symbol name="materialColorSecondary" type="attr"/> + <java-symbol name="materialColorTertiary" type="attr"/> + <java-symbol name="materialColorError" type="attr"/> + + <java-symbol name="customColorWidgetBackground" type="attr"/> + <java-symbol name="customColorClockHour" type="attr"/> + <java-symbol name="customColorClockMinute" type="attr"/> + <java-symbol name="customColorClockSecond" type="attr"/> + <java-symbol name="customColorThemeApp" type="attr"/> + <java-symbol name="customColorOnThemeApp" type="attr"/> + <java-symbol name="customColorThemeAppRing" type="attr"/> + <java-symbol name="customColorThemeNotif" type="attr"/> + <java-symbol name="customColorBrandA" type="attr"/> + <java-symbol name="customColorBrandB" type="attr"/> + <java-symbol name="customColorBrandC" type="attr"/> + <java-symbol name="customColorBrandD" type="attr"/> + <java-symbol name="customColorUnderSurface" type="attr"/> + <java-symbol name="customColorShadeActive" type="attr"/> + <java-symbol name="customColorOnShadeActive" type="attr"/> + <java-symbol name="customColorOnShadeActiveVariant" type="attr"/> + <java-symbol name="customColorShadeInactive" type="attr"/> + <java-symbol name="customColorOnShadeInactive" type="attr"/> + <java-symbol name="customColorOnShadeInactiveVariant" type="attr"/> + <java-symbol name="customColorShadeDisabled" type="attr"/> + <java-symbol name="customColorOverviewBackground" type="attr"/> <java-symbol name="system_widget_background_light" type="color"/> <java-symbol name="system_clock_hour_light" type="color"/> diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml index d8346d87f624..352c3904406c 100644 --- a/core/res/res/values/themes_device_defaults.xml +++ b/core/res/res/values/themes_device_defaults.xml @@ -239,90 +239,73 @@ easier. <item name="colorForeground">@color/foreground_device_default_dark</item> <item name="colorForegroundInverse">@color/foreground_device_default_light</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <style name="Theme.DeviceDefault" parent="Theme.DeviceDefaultBase" /> @@ -374,90 +357,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar. This theme @@ -508,90 +474,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar and @@ -644,90 +593,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- Variant of {@link #Theme_DeviceDefault} that has no title bar and translucent @@ -779,90 +711,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- DeviceDefault theme for dialog windows and activities. This changes the window to be @@ -922,90 +837,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- Variant of {@link #Theme_DeviceDefault_Dialog} that has a nice minimum width for a @@ -1056,90 +954,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- Variant of {@link #Theme_DeviceDefault_Dialog} without an action bar --> @@ -1189,90 +1070,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- Variant of {@link #Theme_DeviceDefault_Dialog_NoActionBar} that has a nice minimum width @@ -1323,90 +1187,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. --> @@ -1473,90 +1320,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- DeviceDefault theme for a window without an action bar that will be displayed either @@ -1608,90 +1438,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- DeviceDefault theme for a presentation window on a secondary display. --> @@ -1741,90 +1554,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- DeviceDefault theme for panel windows. This removes all extraneous window @@ -1876,90 +1672,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear @@ -2010,90 +1789,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear @@ -2144,90 +1906,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- DeviceDefault style for input methods, which is used by the @@ -2278,90 +2023,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- DeviceDefault style for input methods, which is used by the @@ -2412,90 +2140,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Material.Dialog.Alert"> @@ -2546,90 +2257,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- Theme for the dialog shown when an app crashes or ANRs. --> @@ -2685,90 +2379,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <style name="Theme.DeviceDefault.Dialog.NoFrame" parent="Theme.Material.Dialog.NoFrame"> @@ -2817,90 +2494,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <!-- Variant of {@link #Theme_DeviceDefault} with a light-colored style --> @@ -3087,90 +2747,73 @@ easier. <item name="colorPopupBackground">?attr/colorBackgroundFloating</item> <item name="panelColorBackground">?attr/colorBackgroundFloating</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- Variant of the DeviceDefault (light) theme that has a solid (opaque) action bar with an @@ -3221,90 +2864,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar --> @@ -3354,90 +2980,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar. @@ -3488,90 +3097,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar @@ -3624,90 +3216,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- Variant of {@link #Theme_DeviceDefault_Light} that has no title bar and translucent @@ -3759,90 +3334,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- DeviceDefault light theme for dialog windows and activities. This changes the window to be @@ -3900,90 +3458,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} that has a nice minimum width for a @@ -4037,90 +3578,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} without an action bar --> @@ -4173,90 +3697,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog_NoActionBar} that has a nice minimum @@ -4310,90 +3817,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. --> @@ -4428,90 +3918,73 @@ easier. <item name="colorForeground">@color/foreground_device_default_light</item> <item name="colorForegroundInverse">@color/foreground_device_default_dark</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- Variant of Theme.DeviceDefault.Dialog.NoActionBar that has a fixed size. --> @@ -4546,90 +4019,73 @@ easier. <item name="colorForeground">@color/foreground_device_default_light</item> <item name="colorForegroundInverse">@color/foreground_device_default_dark</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- DeviceDefault light theme for a window that will be displayed either full-screen on smaller @@ -4683,90 +4139,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- DeviceDefault light theme for a window without an action bar that will be displayed either @@ -4821,90 +4260,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- DeviceDefault light theme for a presentation window on a secondary display. --> @@ -4957,90 +4379,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- DeviceDefault light theme for panel windows. This removes all extraneous window @@ -5092,90 +4497,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Material.Light.Dialog.Alert"> @@ -5226,90 +4614,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <style name="Theme.DeviceDefault.Dialog.Alert.DayNight" parent="Theme.DeviceDefault.Light.Dialog.Alert" /> @@ -5360,90 +4731,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <style name="Theme.DeviceDefault.Light.Voice" parent="Theme.Material.Light.Voice"> @@ -5492,90 +4846,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- DeviceDefault theme for a window that should look like the Settings app. --> @@ -5631,90 +4968,74 @@ easier. <item name="colorListDivider">@color/list_divider_color_light</item> <item name="opacityListDivider">@color/list_divider_opacity_device_default_light</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> + <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <style name="Theme.DeviceDefault.SystemUI" parent="Theme.DeviceDefault.Light"> @@ -5751,90 +5072,74 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> + <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <style name="Theme.DeviceDefault.SystemUI.Dialog" parent="Theme.DeviceDefault.Light.Dialog"> @@ -5863,90 +5168,74 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> + <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- Variant of {@link #Theme_DeviceDefault_Settings_Dark} with no action bar --> @@ -5997,90 +5286,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <style name="Theme.DeviceDefault.Settings.DialogBase" parent="Theme.Material.Light.BaseDialog"> @@ -6115,90 +5387,73 @@ easier. <!-- Dialog attributes --> <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <style name="Theme.DeviceDefault.Settings.Dialog" parent="Theme.DeviceDefault.Settings.DialogBase"> @@ -6273,90 +5528,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <style name="Theme.DeviceDefault.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.Alert"> @@ -6409,90 +5647,73 @@ easier. <!-- Toolbar attributes --> <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <style name="Theme.DeviceDefault.Settings.Dialog.NoActionBar" parent="Theme.DeviceDefault.Light.Dialog.NoActionBar" /> @@ -6571,90 +5792,73 @@ easier. <item name="colorAccentSecondary">@color/system_secondary_dark</item> <item name="colorAccentTertiary">@color/system_tertiary_dark</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <style name="ThemeOverlay.DeviceDefault.Accent.Light"> @@ -6663,90 +5867,73 @@ easier. <item name="colorAccentSecondary">@color/system_secondary_dark</item> <item name="colorAccentTertiary">@color/system_tertiary_dark</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <!-- Theme overlay that replaces colorAccent with the colorAccent from {@link #Theme_DeviceDefault_DayNight}. --> @@ -6759,90 +5946,73 @@ easier. <item name="colorAccentSecondary">@color/system_secondary_dark</item> <item name="colorAccentTertiary">@color/system_tertiary_dark</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <style name="Theme.DeviceDefault.Light.Dialog.Alert.UserSwitchingDialog" parent="Theme.DeviceDefault.NoActionBar.Fullscreen"> @@ -6851,90 +6021,73 @@ easier. <item name="layout_gravity">center</item> <item name="windowAnimationStyle">@style/Animation.DeviceDefault.Dialog</item> - <item name="materialColorBackground">@color/system_background_light</item> - <item name="materialColorControlActivated">@color/system_control_activated_light</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_light</item> - <item name="materialColorControlNormal">@color/system_control_normal_light</item> - <item name="materialColorError">@color/system_error_light</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_dark</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> <item name="materialColorErrorContainer">@color/system_error_container_light</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_light</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_light</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_light</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_dark</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_dark</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> <item name="materialColorOnBackground">@color/system_on_background_light</item> - <item name="materialColorOnError">@color/system_on_error_light</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_light</item> - <item name="materialColorOnPrimary">@color/system_on_primary_light</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_light</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_light</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_light</item> - <item name="materialColorOnSurface">@color/system_on_surface_light</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_light</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> + <item name="materialColorOnError">@color/system_on_error_light</item> + <item name="materialColorSurface">@color/system_surface_light</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item> <item name="materialColorOutline">@color/system_outline_light</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_light</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_light</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_light</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_light</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_light</item> + <item name="materialColorOnPrimary">@color/system_on_primary_light</item> + <item name="materialColorOnSurface">@color/system_on_surface_light</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> <item name="materialColorPrimary">@color/system_primary_light</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_light</item> - <item name="materialColorScrim">@color/system_scrim_light</item> <item name="materialColorSecondary">@color/system_secondary_light</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_light</item> - <item name="materialColorShadow">@color/system_shadow_light</item> - <item name="materialColorSurface">@color/system_surface_light</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_light</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_light</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_light</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_light</item> <item name="materialColorTertiary">@color/system_tertiary_light</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_light</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_light</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_light</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_light</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_light</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_light</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorClockHour">@color/system_clock_hour_light</item> + <item name="customColorClockMinute">@color/system_clock_minute_light</item> + <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorThemeApp">@color/system_theme_app_light</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> + <item name="customColorThemeNotif">@color/system_theme_notif_light</item> <item name="customColorBrandA">@color/system_brand_a_light</item> <item name="customColorBrandB">@color/system_brand_b_light</item> <item name="customColorBrandC">@color/system_brand_c_light</item> <item name="customColorBrandD">@color/system_brand_d_light</item> - <item name="customColorClockHour">@color/system_clock_hour_light</item> - <item name="customColorClockMinute">@color/system_clock_minute_light</item> - <item name="customColorClockSecond">@color/system_clock_second_light</item> + <item name="customColorUnderSurface">@color/system_under_surface_light</item> + <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item> - <item name="customColorOverviewBackground">@color/system_overview_background_light</item> - <item name="customColorShadeActive">@color/system_shade_active_light</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_light</item> - <item name="customColorThemeApp">@color/system_theme_app_light</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item> - <item name="customColorThemeNotif">@color/system_theme_notif_light</item> - <item name="customColorUnderSurface">@color/system_under_surface_light</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_light</item> - <item name="customColorWidgetBackground">@color/system_widget_background_light</item> + <item name="customColorOverviewBackground">@color/system_overview_background_light</item> </style> <style name="Theme.DeviceDefault.Notification" parent="@style/Theme.Material.Notification"> @@ -6954,90 +6107,73 @@ easier. <item name="textColorPrimary">@color/system_neutral1_900</item> <item name="textColorSecondary">@color/system_neutral2_700</item> - <item name="materialColorBackground">@color/system_background_dark</item> - <item name="materialColorControlActivated">@color/system_control_activated_dark</item> - <item name="materialColorControlHighlight">@color/system_control_highlight_dark</item> - <item name="materialColorControlNormal">@color/system_control_normal_dark</item> - <item name="materialColorError">@color/system_error_dark</item> + <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> + <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> + <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> + <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> + <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> + <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> + <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> + <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> + <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> + <item name="materialColorOnSurfaceInverse">@color/system_on_surface_light</item> + <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> + <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> + <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> <item name="materialColorErrorContainer">@color/system_error_container_dark</item> - <item name="materialColorInverseOnSurface">@color/system_inverse_on_surface_dark</item> - <item name="materialColorInversePrimary">@color/system_inverse_primary_dark</item> - <item name="materialColorInverseSurface">@color/system_inverse_surface_dark</item> + <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> + <item name="materialColorPrimaryInverse">@color/system_primary_light</item> + <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> + <item name="materialColorSurfaceInverse">@color/system_surface_light</item> + <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> + <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> + <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> + <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> <item name="materialColorOnBackground">@color/system_on_background_dark</item> - <item name="materialColorOnError">@color/system_on_error_dark</item> - <item name="materialColorOnErrorContainer">@color/system_on_error_container_dark</item> - <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> - <item name="materialColorOnPrimaryContainer">@color/system_on_primary_container_dark</item> + <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item> - <item name="materialColorOnSecondaryContainer">@color/system_on_secondary_container_dark</item> - <item name="materialColorOnSurface">@color/system_on_surface_dark</item> - <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item> - <item name="materialColorOnTertiaryContainer">@color/system_on_tertiary_container_dark</item> + <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> + <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> + <item name="materialColorOnError">@color/system_on_error_dark</item> + <item name="materialColorSurface">@color/system_surface_dark</item> + <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> + <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> + <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item> <item name="materialColorOutline">@color/system_outline_dark</item> <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item> - <item name="materialColorPaletteKeyColorNeutral">@color/system_palette_key_color_neutral_dark</item> - <item name="materialColorPaletteKeyColorNeutralVariant">@color/system_palette_key_color_neutral_variant_dark</item> - <item name="materialColorPaletteKeyColorPrimary">@color/system_palette_key_color_primary_dark</item> - <item name="materialColorPaletteKeyColorSecondary">@color/system_palette_key_color_secondary_dark</item> - <item name="materialColorPaletteKeyColorTertiary">@color/system_palette_key_color_tertiary_dark</item> + <item name="materialColorOnPrimary">@color/system_on_primary_dark</item> + <item name="materialColorOnSurface">@color/system_on_surface_dark</item> + <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> <item name="materialColorPrimary">@color/system_primary_dark</item> - <item name="materialColorPrimaryContainer">@color/system_primary_container_dark</item> - <item name="materialColorScrim">@color/system_scrim_dark</item> <item name="materialColorSecondary">@color/system_secondary_dark</item> - <item name="materialColorSecondaryContainer">@color/system_secondary_container_dark</item> - <item name="materialColorShadow">@color/system_shadow_dark</item> - <item name="materialColorSurface">@color/system_surface_dark</item> - <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item> - <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item> - <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item> - <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item> - <item name="materialColorSurfaceContainerLow">@color/system_surface_container_low_dark</item> - <item name="materialColorSurfaceContainerLowest">@color/system_surface_container_lowest_dark</item> - <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item> - <item name="materialColorSurfaceTint">@color/system_surface_tint_dark</item> - <item name="materialColorSurfaceVariant">@color/system_surface_variant_dark</item> <item name="materialColorTertiary">@color/system_tertiary_dark</item> - <item name="materialColorTertiaryContainer">@color/system_tertiary_container_dark</item> - <item name="materialColorTextHintInverse">@color/system_text_hint_inverse_dark</item> - <item name="materialColorTextPrimaryInverse">@color/system_text_primary_inverse_dark</item> - <item name="materialColorTextPrimaryInverseDisableOnly">@color/system_text_primary_inverse_disable_only_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverse">@color/system_text_secondary_and_tertiary_inverse_dark</item> - <item name="materialColorTextSecondaryAndTertiaryInverseDisabled">@color/system_text_secondary_and_tertiary_inverse_disabled_dark</item> - <item name="materialColorOnPrimaryFixed">@color/system_on_primary_fixed</item> - <item name="materialColorOnPrimaryFixedVariant">@color/system_on_primary_fixed_variant</item> - <item name="materialColorOnSecondaryFixed">@color/system_on_secondary_fixed</item> - <item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item> - <item name="materialColorOnTertiaryFixed">@color/system_on_tertiary_fixed</item> - <item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item> - <item name="materialColorPrimaryFixed">@color/system_primary_fixed</item> - <item name="materialColorPrimaryFixedDim">@color/system_primary_fixed_dim</item> - <item name="materialColorSecondaryFixed">@color/system_secondary_fixed</item> - <item name="materialColorSecondaryFixedDim">@color/system_secondary_fixed_dim</item> - <item name="materialColorTertiaryFixed">@color/system_tertiary_fixed</item> - <item name="materialColorTertiaryFixedDim">@color/system_tertiary_fixed_dim</item> + <item name="materialColorError">@color/system_error_dark</item> + + <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorClockHour">@color/system_clock_hour_dark</item> + <item name="customColorClockMinute">@color/system_clock_minute_dark</item> + <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorThemeApp">@color/system_theme_app_dark</item> + <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> + <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> + <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> <item name="customColorBrandA">@color/system_brand_a_dark</item> <item name="customColorBrandB">@color/system_brand_b_dark</item> <item name="customColorBrandC">@color/system_brand_c_dark</item> <item name="customColorBrandD">@color/system_brand_d_dark</item> - <item name="customColorClockHour">@color/system_clock_hour_dark</item> - <item name="customColorClockMinute">@color/system_clock_minute_dark</item> - <item name="customColorClockSecond">@color/system_clock_second_dark</item> + <item name="customColorUnderSurface">@color/system_under_surface_dark</item> + <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item> <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item> + <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item> <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item> - <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item> - <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> - <item name="customColorShadeActive">@color/system_shade_active_dark</item> <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item> - <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item> - <item name="customColorThemeApp">@color/system_theme_app_dark</item> - <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item> - <item name="customColorThemeNotif">@color/system_theme_notif_dark</item> - <item name="customColorUnderSurface">@color/system_under_surface_dark</item> - <item name="customColorWeatherTemp">@color/system_weather_temp_dark</item> - <item name="customColorWidgetBackground">@color/system_widget_background_dark</item> + <item name="customColorOverviewBackground">@color/system_overview_background_dark</item> </style> <style name="Theme.DeviceDefault.AutofillHalfScreenDialogList" parent="Theme.DeviceDefault.DayNight"> <item name="colorListDivider">@color/list_divider_opacity_device_default_light</item> diff --git a/core/tests/InputMethodCoreTests/src/android/view/inputmethod/EditorInfoTest.java b/core/tests/InputMethodCoreTests/src/android/view/inputmethod/EditorInfoTest.java index 1721e1e2e935..f62d420510c3 100644 --- a/core/tests/InputMethodCoreTests/src/android/view/inputmethod/EditorInfoTest.java +++ b/core/tests/InputMethodCoreTests/src/android/view/inputmethod/EditorInfoTest.java @@ -79,7 +79,7 @@ public class EditorInfoTest { TEST_EDITOR_INFO.label = "testLabel"; TEST_EDITOR_INFO.packageName = "android.view.inputmethod"; TEST_EDITOR_INFO.fieldId = 0; - TEST_EDITOR_INFO.autofillId = AutofillId.NO_AUTOFILL_ID; + TEST_EDITOR_INFO.setAutofillId(AutofillId.NO_AUTOFILL_ID); TEST_EDITOR_INFO.fieldName = "testField"; TEST_EDITOR_INFO.extras = new Bundle(); TEST_EDITOR_INFO.extras.putString("testKey", "testValue"); @@ -507,7 +507,8 @@ public class EditorInfoTest { + "prefix: supportedHandwritingGestureTypes=(none)\n" + "prefix: supportedHandwritingGesturePreviewTypes=(none)\n" + "prefix: isStylusHandwritingEnabled=false\n" - + "prefix: contentMimeTypes=null\n"); + + "prefix: contentMimeTypes=null\n" + + "prefix: writingToolsEnabled=true\n"); } @Test @@ -531,7 +532,7 @@ public class EditorInfoTest { info.setStylusHandwritingEnabled(true); } info.packageName = "android.view.inputmethod"; - info.autofillId = new AutofillId(123); + info.setAutofillId(new AutofillId(123)); info.fieldId = 456; info.fieldName = "testField"; info.extras = new Bundle(); @@ -539,6 +540,7 @@ public class EditorInfoTest { info.hintLocales = LocaleList.forLanguageTags("en,es,zh"); info.contentMimeTypes = new String[] {"image/png"}; info.targetInputMethodUser = UserHandle.of(10); + info.setWritingToolsEnabled(false); final StringBuilder sb = new StringBuilder(); info.dump(new StringBuilderPrinter(sb), "prefix2: "); assertThat(sb.toString()).isEqualTo( @@ -555,7 +557,8 @@ public class EditorInfoTest { + "prefix2: supportedHandwritingGesturePreviewTypes=SELECT\n" + "prefix2: isStylusHandwritingEnabled=" + isStylusHandwritingEnabled + "\n" + "prefix2: contentMimeTypes=[image/png]\n" - + "prefix2: targetInputMethodUserId=10\n"); + + "prefix2: targetInputMethodUserId=10\n" + + "prefix2: writingToolsEnabled=false\n"); } @Test @@ -576,7 +579,8 @@ public class EditorInfoTest { + "prefix: supportedHandwritingGestureTypes=(none)\n" + "prefix: supportedHandwritingGesturePreviewTypes=(none)\n" + "prefix: isStylusHandwritingEnabled=false\n" - + "prefix: contentMimeTypes=null\n"); + + "prefix: contentMimeTypes=null\n" + + "prefix: writingToolsEnabled=true\n"); } @Test @@ -597,7 +601,7 @@ public class EditorInfoTest { @Test public void testKindofEqualsComparesAutofillId() { final EditorInfo infoCopy = TEST_EDITOR_INFO.createCopyInternal(); - infoCopy.autofillId = new AutofillId(42); + infoCopy.setAutofillId(new AutofillId(42)); assertFalse(TEST_EDITOR_INFO.kindofEquals(infoCopy)); } @@ -621,4 +625,9 @@ public class EditorInfoTest { infoCopy.extras.putString("testKey2", "testValue"); assertFalse(TEST_EDITOR_INFO.kindofEquals(infoCopy)); } + + @Test + public void testWritingToolsEnabledbyDefault() { + assertTrue(TEST_EDITOR_INFO.isWritingToolsEnabled()); + } } diff --git a/core/tests/coretests/src/android/app/activity/ActivityTestsBase.java b/core/tests/coretests/src/android/app/activity/ActivityTestsBase.java index 232abe281e0f..7f069ad3cab8 100644 --- a/core/tests/coretests/src/android/app/activity/ActivityTestsBase.java +++ b/core/tests/coretests/src/android/app/activity/ActivityTestsBase.java @@ -22,7 +22,7 @@ import android.content.Intent; import android.test.AndroidTestCase; import android.test.PerformanceTestCase; -public class ActivityTestsBase extends AndroidTestCase +public class ActivityTestsBase extends AndroidTestCase implements PerformanceTestCase, LaunchpadActivity.CallingTest { public static final String PERMISSION_GRANTED = "com.android.frameworks.coretests.permission.TEST_GRANTED"; @@ -111,7 +111,6 @@ public class ActivityTestsBase extends AndroidTestCase public void finishWithResult(int resultCode, Intent data) { RuntimeException where = new RuntimeException("Original error was here"); - where.fillInStackTrace(); finishWithResult(resultCode, data, where); } @@ -194,15 +193,15 @@ public class ActivityTestsBase extends AndroidTestCase public int getResultCode() { return mResultCode; } - + public Intent getResultData() { return mData; } - + public RuntimeException getResultStack() { return mResultStack; } - + public void onTimeout() { String msg = mExpecting == null ? "Timeout" : ("Timeout while expecting " + mExpecting); diff --git a/core/tests/coretests/src/android/app/activity/LaunchpadActivity.java b/core/tests/coretests/src/android/app/activity/LaunchpadActivity.java index fda249f3c6ae..9b358e0a7954 100644 --- a/core/tests/coretests/src/android/app/activity/LaunchpadActivity.java +++ b/core/tests/coretests/src/android/app/activity/LaunchpadActivity.java @@ -461,7 +461,6 @@ public class LaunchpadActivity extends Activity { mResultCode = resultCode; mData = data; mResultStack = new RuntimeException("Original error was here"); - mResultStack.fillInStackTrace(); } private void registerMyReceiver(IntentFilter filter) { diff --git a/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java b/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java index 9552c887443b..6a5224d4524b 100644 --- a/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java +++ b/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java @@ -16,6 +16,11 @@ package android.hardware.display; +import static android.hardware.display.DisplayManagerGlobal.EVENT_DISPLAY_STATE_CHANGED; +import static android.hardware.display.DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE; +import static android.hardware.display.DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_STATE; + +import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; @@ -28,13 +33,19 @@ import android.content.Context; import android.os.Handler; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.view.DisplayInfo; import androidx.test.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.server.display.feature.flags.Flags; + import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -55,6 +66,10 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class DisplayManagerGlobalTest { + @Rule + public final CheckFlagsRule mCheckFlagsRule = + DeviceFlagsValueProvider.createCheckFlagsRule(); + private static final long ALL_DISPLAY_EVENTS = DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED @@ -117,6 +132,33 @@ public class DisplayManagerGlobalTest { } @Test + @RequiresFlagsEnabled(Flags.FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS) + public void testDisplayListenerIsCalled_WhenDisplayPropertyChangeEventOccurs() + throws RemoteException { + mDisplayManagerGlobal.registerDisplayListener(mListener, mHandler, + INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE + | INTERNAL_EVENT_FLAG_DISPLAY_STATE, + null); + Mockito.verify(mDisplayManager) + .registerCallbackWithEventMask(mCallbackCaptor.capture(), anyLong()); + IDisplayManagerCallback callback = mCallbackCaptor.getValue(); + + int displayId = 1; + + Mockito.reset(mListener); + callback.onDisplayEvent(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REFRESH_RATE_CHANGED); + waitForHandler(); + Mockito.verify(mListener).onDisplayChanged(eq(displayId)); + Mockito.verifyNoMoreInteractions(mListener); + + Mockito.reset(mListener); + callback.onDisplayEvent(displayId, EVENT_DISPLAY_STATE_CHANGED); + waitForHandler(); + Mockito.verify(mListener).onDisplayChanged(eq(displayId)); + Mockito.verifyNoMoreInteractions(mListener); + } + + @Test public void testDisplayListenerIsNotCalled_WhenClientIsNotSubscribed() throws RemoteException { // First we subscribe to all events in order to test that the subsequent calls to // registerDisplayListener will update the event mask. @@ -231,6 +273,53 @@ public class DisplayManagerGlobalTest { verify(mListener2, never()).onDisplayChanged(anyInt()); } + @Test + @RequiresFlagsEnabled(Flags.FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS) + public void testMapFlagsToInternalEventFlag() { + // Test public flags mapping + assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED, + mDisplayManagerGlobal + .mapFlagsToInternalEventFlag(DisplayManager.EVENT_FLAG_DISPLAY_ADDED, 0)); + assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED, + mDisplayManagerGlobal + .mapFlagsToInternalEventFlag(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED, 0)); + assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED, + mDisplayManagerGlobal + .mapFlagsToInternalEventFlag(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED, 0)); + assertEquals(INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE, + mDisplayManagerGlobal + .mapFlagsToInternalEventFlag( + DisplayManager.EVENT_FLAG_DISPLAY_REFRESH_RATE, + 0)); + assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_STATE, + mDisplayManagerGlobal + .mapFlagsToInternalEventFlag( + DisplayManager.EVENT_FLAG_DISPLAY_STATE, + 0)); + + // test private flags mapping + assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED, + mDisplayManagerGlobal + .mapFlagsToInternalEventFlag(0, + DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED)); + assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED, + mDisplayManagerGlobal + .mapFlagsToInternalEventFlag(0, + DisplayManager.PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED)); + assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED, + mDisplayManagerGlobal + .mapFlagsToInternalEventFlag(0, + DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS)); + + // Test both public and private flags mapping + assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED + | INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE, + mDisplayManagerGlobal + .mapFlagsToInternalEventFlag( + DisplayManager.EVENT_FLAG_DISPLAY_REFRESH_RATE, + DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS)); + } + private void waitForHandler() { mHandler.runWithScissors(() -> { }, 0); diff --git a/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt b/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt index a6de611cc077..8969b2b72e77 100644 --- a/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt +++ b/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt @@ -16,7 +16,10 @@ package android.hardware.display +import android.graphics.PointF +import android.graphics.RectF import android.hardware.display.DisplayTopology.TreeNode.POSITION_BOTTOM +import android.hardware.display.DisplayTopology.TreeNode.POSITION_LEFT import android.hardware.display.DisplayTopology.TreeNode.POSITION_TOP import android.hardware.display.DisplayTopology.TreeNode.POSITION_RIGHT import android.view.Display @@ -469,4 +472,205 @@ class DisplayTopologyTest { assertThat(actualDisplay4.offset).isEqualTo(-400f) assertThat(actualDisplay4.children).isEmpty() } -}
\ No newline at end of file + + @Test + fun rearrange_twoDisplays() { + val nodes = rearrangeRects( + // Arrange in staggered manner, connected vertically. + RectF(100f, 100f, 250f, 200f), + RectF(150f, 200f, 300f, 300f), + ) + + assertThat(nodes[0].children).containsExactly(nodes[1]) + assertThat(nodes[1].children).isEmpty() + assertPositioning(nodes, Pair(POSITION_BOTTOM, 50f)) + } + + @Test + fun rearrange_reverseOrderOfSeveralDisplays() { + val nodes = rearrangeRects( + RectF(0f, 0f, 150f, 100f), + RectF(-150f, 0f, 0f, 100f), + RectF(-300f, 0f, -150f, 100f), + RectF(-450f, 0f, -300f, 100f), + ) + + assertPositioning( + nodes, + Pair(POSITION_LEFT, 0f), + Pair(POSITION_LEFT, 0f), + Pair(POSITION_LEFT, 0f), + ) + + assertThat(nodes[0].children).containsExactly(nodes[1]) + assertThat(nodes[1].children).containsExactly(nodes[2]) + assertThat(nodes[2].children).containsExactly(nodes[3]) + assertThat(nodes[3].children).isEmpty() + } + + @Test + fun rearrange_crossWithRootInCenter() { + val nodes = rearrangeRects( + RectF(0f, 0f, 150f, 100f), + RectF(-150f, 0f, 0f, 100f), + RectF(0f,-100f, 150f, 0f), + RectF(150f, 0f, 300f, 100f), + RectF(0f, 100f, 150f, 200f), + ) + + assertPositioning( + nodes, + Pair(POSITION_LEFT, 0f), + Pair(POSITION_TOP, 0f), + Pair(POSITION_RIGHT, 0f), + Pair(POSITION_BOTTOM, 0f), + ) + + assertThat(nodes[0].children) + .containsExactly(nodes[1], nodes[2], nodes[3], nodes[4]) + } + + @Test + fun rearrange_elbowArrangementDoesNotUseCornerAdjacency1() { + val nodes = rearrangeRects( + // 2 + // | + // 0 - 1 + + RectF(0f, 0f, 100f, 100f), + RectF(100f, 0f, 200f, 100f), + RectF(100f, -100f, 200f, 0f), + ) + + assertThat(nodes[0].children).containsExactly(nodes[1]) + assertThat(nodes[1].children).containsExactly(nodes[2]) + assertThat(nodes[2].children).isEmpty() + + assertPositioning( + nodes, + Pair(POSITION_RIGHT, 0f), + Pair(POSITION_TOP, 0f), + ) + } + + @Test + fun rearrange_elbowArrangementDoesNotUseCornerAdjacency2() { + val nodes = rearrangeRects( + // 0 + // | + // 1 + // | + // 3 - 2 + + RectF(0f, 0f, 100f, 100f), + RectF(0f, 100f, 100f, 200f), + RectF(0f, 200f, 100f, 300f), + RectF(-100f, 200f, 0f, 300f), + ) + + assertThat(nodes[0].children).containsExactly(nodes[1]) + assertThat(nodes[1].children).containsExactly(nodes[2]) + assertThat(nodes[2].children).containsExactly(nodes[3]) + assertThat(nodes[3].children).isEmpty() + + assertPositioning( + nodes, + Pair(POSITION_BOTTOM, 0f), + Pair(POSITION_BOTTOM, 0f), + Pair(POSITION_LEFT, 0f), + ) + } + + @Test + fun rearrange_useLargerEdge() { + val nodes = rearrangeRects( + //444111 + //444111 + //444111 + // 000222 + // 000222 + // 000222 + // 333 + // 333 + // 333 + RectF(20f, 30f, 50f, 60f), + RectF(30f, 0f, 60f, 30f), + RectF(50f, 30f, 80f, 60f), + RectF(40f, 60f, 70f, 90f), + RectF(0f, 0f, 30f, 30f), + ) + + assertPositioning( + nodes, + Pair(POSITION_TOP, 10f), + Pair(POSITION_RIGHT, 0f), + Pair(POSITION_BOTTOM, -10f), + Pair(POSITION_LEFT, 0f), + ) + + assertThat(nodes[0].children).containsExactly(nodes[1], nodes[2]) + assertThat(nodes[1].children).containsExactly(nodes[4]) + assertThat(nodes[2].children).containsExactly(nodes[3]) + (3..4).forEach { assertThat(nodes[it].children).isEmpty() } + } + + @Test + fun rearrange_closeGaps() { + val nodes = rearrangeRects( + //000 + //000 111 + //000 111 + // 111 + // + // 222 + // 222 + // 222 + RectF(0f, 0f, 30f, 30f), + RectF(40f, 10f, 70f, 40f), + RectF(80.5f, 50f, 110f, 80f), // left+=0.5 to cause a preference for TOP/BOTTOM attach + ) + + assertPositioning( + nodes, + // In the case of corner adjacency, we prefer a left/right attachment. + Pair(POSITION_RIGHT, 10f), + Pair(POSITION_BOTTOM, 40.5f), // TODO: fix implementation to remove this gap + ) + + assertThat(nodes[0].children).containsExactly(nodes[1]) + assertThat(nodes[1].children).containsExactly(nodes[2]) + assertThat(nodes[2].children).isEmpty() + } + + /** + * Runs the rearrange algorithm and returns the resulting tree as a list of nodes, with the + * root at index 0. The number of nodes is inferred from the number of positions passed. + */ + private fun rearrangeRects(vararg pos : RectF) : List<DisplayTopology.TreeNode> { + // Generates a linear sequence of nodes in order in the List from root to leaf, + // left-to-right. IDs are ascending from 0 to count - 1. + + val nodes = pos.indices.map { + DisplayTopology.TreeNode(it, pos[it].width(), pos[it].height(), POSITION_RIGHT, 0f) + } + + nodes.forEachIndexed { id, node -> + if (id > 0) { + nodes[id - 1].addChild(node) + } + } + + DisplayTopology(nodes[0], 0).rearrange(pos.indices.associateWith { + PointF(pos[it].left, pos[it].top) + }) + + return nodes + } + + private fun assertPositioning( + nodes : List<DisplayTopology.TreeNode>, vararg positions : Pair<Int, Float>) { + assertThat(nodes.drop(1).map { Pair(it.position, it.offset )}) + .containsExactly(*positions) + .inOrder() + } +} diff --git a/core/tests/coretests/src/android/os/OWNERS b/core/tests/coretests/src/android/os/OWNERS index 6149382d0800..4620cb8d8148 100644 --- a/core/tests/coretests/src/android/os/OWNERS +++ b/core/tests/coretests/src/android/os/OWNERS @@ -12,3 +12,6 @@ per-file PerformanceHintManagerTest.java = file:/ADPF_OWNERS # Caching per-file IpcDataCache* = file:/PERFORMANCE_OWNERS + +# RemoteCallbackList +per-file RemoteCallbackListTest.java = shayba@google.com diff --git a/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java b/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java index ac6c19e79fcb..66cf9c7ec832 100644 --- a/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java +++ b/core/tests/coretests/src/android/view/HapticScrollFeedbackProviderTest.java @@ -17,6 +17,7 @@ package android.view; import static android.os.vibrator.Flags.FLAG_HAPTIC_FEEDBACK_INPUT_SOURCE_CUSTOMIZATION_ENABLED; +import static android.view.flags.Flags.FLAG_DYNAMIC_VIEW_ROTARY_HAPTICS_CONFIGURATION; import static android.view.HapticFeedbackConstants.SCROLL_ITEM_FOCUS; import static android.view.HapticFeedbackConstants.SCROLL_LIMIT; import static android.view.HapticFeedbackConstants.SCROLL_TICK; @@ -74,12 +75,13 @@ public final class HapticScrollFeedbackProviderTest { mView = new TestView(InstrumentationRegistry.getContext()); mProvider = new HapticScrollFeedbackProvider(mView, mMockViewConfig, - /* disabledIfViewPlaysScrollHaptics= */ true); + /* isFromView= */ false); mSetFlagsRule.disableFlags(FLAG_HAPTIC_FEEDBACK_INPUT_SOURCE_CUSTOMIZATION_ENABLED); } @Test public void testRotaryEncoder_noFeedbackWhenViewBasedFeedbackIsEnabled() { + mSetFlagsRule.disableFlags(FLAG_DYNAMIC_VIEW_ROTARY_HAPTICS_CONFIGURATION); when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) .thenReturn(true); setHapticScrollTickInterval(5); @@ -97,7 +99,24 @@ public final class HapticScrollFeedbackProviderTest { } @Test + public void testRotaryEncoder_dynamicViewRotaryFeedback_enabledEvenWhenViewFeedbackIsEnabled() { + mSetFlagsRule.enableFlags(FLAG_DYNAMIC_VIEW_ROTARY_HAPTICS_CONFIGURATION); + when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) + .thenReturn(true); + setHapticScrollTickInterval(5); + mProvider = new HapticScrollFeedbackProvider(mView, mMockViewConfig, + /* isFromView= */ false); + + mProvider.onScrollProgress( + INPUT_DEVICE_1, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL, + /* deltaInPixels= */ 10); + + assertFeedbackCount(mView, SCROLL_TICK, 1); + } + + @Test public void testRotaryEncoder_inputDeviceCustomized_noFeedbackWhenViewBasedFeedbackIsEnabled() { + mSetFlagsRule.disableFlags(FLAG_DYNAMIC_VIEW_ROTARY_HAPTICS_CONFIGURATION); mSetFlagsRule.enableFlags(FLAG_HAPTIC_FEEDBACK_INPUT_SOURCE_CUSTOMIZATION_ENABLED); when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) @@ -119,7 +138,7 @@ public final class HapticScrollFeedbackProviderTest { @Test public void testRotaryEncoder_feedbackWhenDisregardingViewBasedScrollHaptics() { mProvider = new HapticScrollFeedbackProvider(mView, mMockViewConfig, - /* disabledIfViewPlaysScrollHaptics= */ false); + /* isFromView= */ true); when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) .thenReturn(true); setHapticScrollTickInterval(5); @@ -144,7 +163,7 @@ public final class HapticScrollFeedbackProviderTest { List<HapticFeedbackRequest> requests = new ArrayList<>(); mProvider = new HapticScrollFeedbackProvider(mView, mMockViewConfig, - /* disabledIfViewPlaysScrollHaptics= */ false); + /* isFromView= */ true); when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) .thenReturn(true); setHapticScrollTickInterval(5); @@ -917,19 +936,20 @@ public final class HapticScrollFeedbackProviderTest { @Test public void testNonRotaryInputFeedbackNotBlockedByRotaryUnavailability() { + mSetFlagsRule.disableFlags(FLAG_DYNAMIC_VIEW_ROTARY_HAPTICS_CONFIGURATION); when(mMockViewConfig.isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()) .thenReturn(true); setHapticScrollFeedbackEnabled(true); setHapticScrollTickInterval(5); mProvider = new HapticScrollFeedbackProvider(mView, mMockViewConfig, - /* disabledIfViewPlaysScrollHaptics= */ true); + /* isFromView= */ false); // Expect one feedback here. Touch input should provide feedback since scroll feedback has // been enabled via `setHapticScrollFeedbackEnabled(true)`. mProvider.onScrollProgress( INPUT_DEVICE_1, InputDevice.SOURCE_TOUCHSCREEN, MotionEvent.AXIS_Y, /* deltaInPixels= */ 10); - // Because `isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()` is false and + // Because `isViewBasedRotaryEncoderHapticScrollFeedbackEnabled()` is true and // `disabledIfViewPlaysScrollHaptics` is true, the scroll progress from rotary encoders will // produce no feedback. mProvider.onScrollProgress( diff --git a/core/tests/coretests/src/android/view/RotaryScrollHapticsTest.java b/core/tests/coretests/src/android/view/RotaryScrollHapticsTest.java index 9a5c1c5112e6..b1a56373c9d6 100644 --- a/core/tests/coretests/src/android/view/RotaryScrollHapticsTest.java +++ b/core/tests/coretests/src/android/view/RotaryScrollHapticsTest.java @@ -30,8 +30,12 @@ import static org.mockito.Mockito.when; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import android.annotation.Nullable; import android.content.Context; +import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; +import android.platform.test.flag.junit.SetFlagsRule; +import android.view.flags.Flags; import androidx.test.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -39,6 +43,7 @@ import androidx.test.filters.SmallTest; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -48,6 +53,8 @@ import org.mockito.Mock; @RunWith(AndroidJUnit4.class) @Presubmit public final class RotaryScrollHapticsTest { + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private static final int TEST_ROTARY_DEVICE_ID = 1; private static final int TEST_RANDOM_DEVICE_ID = 2; @@ -167,6 +174,26 @@ public final class RotaryScrollHapticsTest { } @Test + @EnableFlags(Flags.FLAG_DYNAMIC_VIEW_ROTARY_HAPTICS_CONFIGURATION) + public void testChildViewImplementationUsesScrollFeedbackProvider_doesNoScrollFeedback() { + mView.configureGenericMotion(/* result= */ false, /* scroll= */ true); + mView.mUsesCustomScrollFeedbackProvider = true; + + // Send multiple generic motion events, to catch bugs where the behavior is WAI only for the + // first dispatch, but buggy for future calls. + mView.dispatchGenericMotionEvent(createRotaryEvent(20)); + mView.dispatchGenericMotionEvent(createRotaryEvent(10)); + mView.dispatchGenericMotionEvent(createRotaryEvent(30)); + + // Verify that the base View class's ScrollFeedbackProvider produces no scroll progress + // or limit events, because there's a custom ScrollFeedbackProvider used by the child + // View class implementation, which should hint the base View class to disable its own + // ScrollFeedbackProvider usage. + verifyNoScrollProgress(); + verifyNoScrollLimit(); + } + + @Test public void testScrollProgress_genericMotionEventCallbackReturningTrue_doesScrollProgress() { mView.configureGenericMotion(/* result= */ true, /* scroll= */ true); @@ -208,6 +235,9 @@ public final class RotaryScrollHapticsTest { private static final class TestGenericMotionEventControllingView extends View { private boolean mGenericMotionResult; private boolean mScrollOnGenericMotion; + private boolean mUsesCustomScrollFeedbackProvider = false; + + @Nullable private ScrollFeedbackProvider mCustomScrollFeedbackProvider; TestGenericMotionEventControllingView(Context context) { super(context); @@ -222,6 +252,19 @@ public final class RotaryScrollHapticsTest { public boolean onGenericMotionEvent(MotionEvent event) { if (mScrollOnGenericMotion) { scrollTo(100, 200); // scroll values random (not relevant for tests). + if (mUsesCustomScrollFeedbackProvider) { + // Mimic how a real child class of View would instantiate and use the + // ScrollFeedbackProvider API. + if (mCustomScrollFeedbackProvider == null) { + mCustomScrollFeedbackProvider = ScrollFeedbackProvider.createProvider(this); + } + float axisScrollValue = event.getAxisValue(AXIS_SCROLL); + mCustomScrollFeedbackProvider.onScrollProgress( + event.getDeviceId(), + event.getSource(), + MotionEvent.AXIS_SCROLL, + (int) (axisScrollValue * TEST_SCALED_VERTICAL_SCROLL_FACTOR)); + } } return mGenericMotionResult; } diff --git a/data/sounds/Android.bp b/data/sounds/Android.bp new file mode 100644 index 000000000000..65d4872cdc16 --- /dev/null +++ b/data/sounds/Android.bp @@ -0,0 +1,304 @@ +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +phony { + name: "frameworks_sounds", + required: [ + "frameworks_alarm_sounds", + "frameworks_notifications_sounds", + "frameworks_ringtones_sounds", + "frameworks_ui_sounds", + "frameworks_ui_48k_sounds", + ], +} + +prebuilt_media { + name: "frameworks_alarm_sounds", + srcs: [ + "Alarm_Beep_01.ogg", + "Alarm_Beep_02.ogg", + "Alarm_Beep_03.ogg", + "Alarm_Buzzer.ogg", + "Alarm_Classic.ogg", + "Alarm_Rooster_02.ogg", + "alarms/ogg/Argon.ogg", + "alarms/ogg/Barium.ogg", + "alarms/ogg/Carbon.ogg", + "alarms/ogg/Helium.ogg", + "alarms/ogg/Krypton.ogg", + "alarms/ogg/Neon.ogg", + "alarms/ogg/Neptunium.ogg", + "alarms/ogg/Osmium.ogg", + "alarms/ogg/Oxygen.ogg", + "alarms/ogg/Platinum.ogg", + "alarms/ogg/Promethium.ogg", + "alarms/ogg/Scandium.ogg", + ], + relative_install_path: "audio/alarms", + product_specific: true, + no_full_install: true, +} + +prebuilt_media { + name: "frameworks_notifications_sounds", + srcs: [ + "notifications/ogg/Adara.ogg", + "notifications/Aldebaran.ogg", + "notifications/Altair.ogg", + "notifications/ogg/Alya.ogg", + "notifications/Antares.ogg", + "notifications/ogg/Antimony.ogg", + "notifications/ogg/Arcturus.ogg", + "notifications/ogg/Argon.ogg", + "notifications/Beat_Box_Android.ogg", + "notifications/ogg/Bellatrix.ogg", + "notifications/ogg/Beryllium.ogg", + "notifications/Betelgeuse.ogg", + "newwavelabs/CaffeineSnake.ogg", + "notifications/Canopus.ogg", + "notifications/ogg/Capella.ogg", + "notifications/Castor.ogg", + "notifications/ogg/CetiAlpha.ogg", + "notifications/ogg/Cobalt.ogg", + "notifications/Cricket.ogg", + "newwavelabs/DearDeer.ogg", + "notifications/Deneb.ogg", + "notifications/Doink.ogg", + "newwavelabs/DontPanic.ogg", + "notifications/Drip.ogg", + "notifications/Electra.ogg", + "F1_MissedCall.ogg", + "F1_New_MMS.ogg", + "F1_New_SMS.ogg", + "notifications/ogg/Fluorine.ogg", + "notifications/Fomalhaut.ogg", + "notifications/ogg/Gallium.ogg", + "notifications/Heaven.ogg", + "notifications/ogg/Helium.ogg", + "newwavelabs/Highwire.ogg", + "notifications/ogg/Hojus.ogg", + "notifications/ogg/Iridium.ogg", + "notifications/ogg/Krypton.ogg", + "newwavelabs/KzurbSonar.ogg", + "notifications/ogg/Lalande.ogg", + "notifications/Merope.ogg", + "notifications/ogg/Mira.ogg", + "newwavelabs/OnTheHunt.ogg", + "notifications/ogg/Palladium.ogg", + "notifications/Plastic_Pipe.ogg", + "notifications/ogg/Polaris.ogg", + "notifications/ogg/Pollux.ogg", + "notifications/ogg/Procyon.ogg", + "notifications/ogg/Proxima.ogg", + "notifications/ogg/Radon.ogg", + "notifications/ogg/Rubidium.ogg", + "notifications/ogg/Selenium.ogg", + "notifications/ogg/Shaula.ogg", + "notifications/Sirrah.ogg", + "notifications/SpaceSeed.ogg", + "notifications/ogg/Spica.ogg", + "notifications/ogg/Strontium.ogg", + "notifications/ogg/Syrma.ogg", + "notifications/TaDa.ogg", + "notifications/ogg/Talitha.ogg", + "notifications/ogg/Tejat.ogg", + "notifications/ogg/Thallium.ogg", + "notifications/Tinkerbell.ogg", + "notifications/ogg/Upsilon.ogg", + "notifications/ogg/Vega.ogg", + "newwavelabs/Voila.ogg", + "notifications/ogg/Xenon.ogg", + "notifications/ogg/Zirconium.ogg", + "notifications/arcturus.ogg", + "notifications/moonbeam.ogg", + "notifications/pixiedust.ogg", + "notifications/pizzicato.ogg", + "notifications/regulus.ogg", + "notifications/sirius.ogg", + "notifications/tweeters.ogg", + "notifications/vega.ogg", + ], + relative_install_path: "audio/notifications", + product_specific: true, + no_full_install: true, +} + +prebuilt_media { + name: "frameworks_ringtones_sounds", + srcs: [ + "ringtones/ANDROMEDA.ogg", + "ringtones/ogg/Andromeda.ogg", + "ringtones/ogg/Aquila.ogg", + "ringtones/ogg/ArgoNavis.ogg", + "ringtones/ogg/Atria.ogg", + "ringtones/BOOTES.ogg", + "newwavelabs/Backroad.ogg", + "newwavelabs/BeatPlucker.ogg", + "newwavelabs/BentleyDubs.ogg", + "newwavelabs/Big_Easy.ogg", + "newwavelabs/BirdLoop.ogg", + "newwavelabs/Bollywood.ogg", + "newwavelabs/BussaMove.ogg", + "ringtones/CANISMAJOR.ogg", + "ringtones/CASSIOPEIA.ogg", + "newwavelabs/Cairo.ogg", + "newwavelabs/Calypso_Steel.ogg", + "ringtones/ogg/CanisMajor.ogg", + "newwavelabs/CaribbeanIce.ogg", + "ringtones/ogg/Carina.ogg", + "ringtones/ogg/Centaurus.ogg", + "newwavelabs/Champagne_Edition.ogg", + "newwavelabs/Club_Cubano.ogg", + "newwavelabs/CrayonRock.ogg", + "newwavelabs/CrazyDream.ogg", + "newwavelabs/CurveBall.ogg", + "ringtones/ogg/Cygnus.ogg", + "newwavelabs/DancinFool.ogg", + "newwavelabs/Ding.ogg", + "newwavelabs/DonMessWivIt.ogg", + "ringtones/ogg/Draco.ogg", + "newwavelabs/DreamTheme.ogg", + "newwavelabs/Eastern_Sky.ogg", + "newwavelabs/Enter_the_Nexus.ogg", + "ringtones/Eridani.ogg", + "newwavelabs/EtherShake.ogg", + "ringtones/FreeFlight.ogg", + "newwavelabs/FriendlyGhost.ogg", + "newwavelabs/Funk_Yall.ogg", + "newwavelabs/GameOverGuitar.ogg", + "newwavelabs/Gimme_Mo_Town.ogg", + "ringtones/ogg/Girtab.ogg", + "newwavelabs/Glacial_Groove.ogg", + "newwavelabs/Growl.ogg", + "newwavelabs/HalfwayHome.ogg", + "ringtones/ogg/Hydra.ogg", + "newwavelabs/InsertCoin.ogg", + "ringtones/ogg/Kuma.ogg", + "newwavelabs/LoopyLounge.ogg", + "newwavelabs/LoveFlute.ogg", + "ringtones/Lyra.ogg", + "ringtones/ogg/Machina.ogg", + "newwavelabs/MidEvilJaunt.ogg", + "newwavelabs/MildlyAlarming.ogg", + "newwavelabs/Nairobi.ogg", + "newwavelabs/Nassau.ogg", + "newwavelabs/NewPlayer.ogg", + "newwavelabs/No_Limits.ogg", + "newwavelabs/Noises1.ogg", + "newwavelabs/Noises2.ogg", + "newwavelabs/Noises3.ogg", + "newwavelabs/OrganDub.ogg", + "ringtones/ogg/Orion.ogg", + "ringtones/PERSEUS.ogg", + "newwavelabs/Paradise_Island.ogg", + "ringtones/ogg/Pegasus.ogg", + "ringtones/ogg/Perseus.ogg", + "newwavelabs/Playa.ogg", + "ringtones/ogg/Pyxis.ogg", + "ringtones/ogg/Rasalas.ogg", + "newwavelabs/Revelation.ogg", + "ringtones/ogg/Rigel.ogg", + "Ring_Classic_02.ogg", + "Ring_Digital_02.ogg", + "Ring_Synth_02.ogg", + "Ring_Synth_04.ogg", + "newwavelabs/Road_Trip.ogg", + "newwavelabs/RomancingTheTone.ogg", + "newwavelabs/Safari.ogg", + "newwavelabs/Savannah.ogg", + "ringtones/ogg/Scarabaeus.ogg", + "ringtones/ogg/Sceptrum.ogg", + "newwavelabs/Seville.ogg", + "newwavelabs/Shes_All_That.ogg", + "newwavelabs/SilkyWay.ogg", + "newwavelabs/SitarVsSitar.ogg", + "ringtones/ogg/Solarium.ogg", + "newwavelabs/SpringyJalopy.ogg", + "newwavelabs/Steppin_Out.ogg", + "newwavelabs/Terminated.ogg", + "ringtones/Testudo.ogg", + "ringtones/ogg/Themos.ogg", + "newwavelabs/Third_Eye.ogg", + "newwavelabs/Thunderfoot.ogg", + "newwavelabs/TwirlAway.ogg", + "ringtones/URSAMINOR.ogg", + "ringtones/ogg/UrsaMinor.ogg", + "newwavelabs/VeryAlarmed.ogg", + "ringtones/Vespa.ogg", + "newwavelabs/World.ogg", + "ringtones/ogg/Zeta.ogg", + "ringtones/hydra.ogg", + ], + relative_install_path: "audio/ringtones", + product_specific: true, + no_full_install: true, +} + +prebuilt_media { + name: "frameworks_ui_48k_sounds", + srcs: [ + "effects/ogg/Effect_Tick_48k.ogg", + "effects/ogg/KeypressDelete_120_48k.ogg", + "effects/ogg/KeypressReturn_120_48k.ogg", + "effects/ogg/KeypressSpacebar_120_48k.ogg", + "effects/ogg/KeypressStandard_120_48k.ogg", + "effects/ogg/KeypressInvalid_120_48k.ogg", + "effects/ogg/Trusted_48k.ogg", + "effects/ogg/VideoRecord_48k.ogg", + "effects/ogg/VideoStop_48k.ogg", + "effects/ogg/camera_click_48k.ogg", + ], + dsts: [ + "Effect_Tick.ogg", + "KeypressDelete.ogg", + "KeypressReturn.ogg", + "KeypressSpacebar.ogg", + "KeypressStandard.ogg", + "KeypressInvalid.ogg", + "Trusted.ogg", + "VideoRecord.ogg", + "VideoStop.ogg", + "camera_click.ogg", + ], + relative_install_path: "audio/ui", + product_specific: true, + no_full_install: true, +} + +prebuilt_media { + name: "frameworks_ui_sounds", + srcs: [ + "effects/ogg/Dock.ogg", + "effects/ogg/Lock.ogg", + "effects/ogg/LowBattery.ogg", + "effects/ogg/Undock.ogg", + "effects/ogg/Unlock.ogg", + "effects/ogg/WirelessChargingStarted.ogg", + "effects/ogg/camera_focus.ogg", + "effects/ogg/ChargingStarted.ogg", + "effects/ogg/InCallNotification.ogg", + "effects/ogg/NFCFailure.ogg", + "effects/ogg/NFCInitiated.ogg", + "effects/ogg/NFCSuccess.ogg", + "effects/ogg/NFCTransferComplete.ogg", + "effects/ogg/NFCTransferInitiated.ogg", + ], + relative_install_path: "audio/ui", + product_specific: true, + no_full_install: true, +} diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/EfficientParcelableChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/EfficientParcelableChecker.java index cae5d8e6846d..35b2375fbc46 100644 --- a/errorprone/java/com/google/errorprone/bugpatterns/android/EfficientParcelableChecker.java +++ b/errorprone/java/com/google/errorprone/bugpatterns/android/EfficientParcelableChecker.java @@ -96,7 +96,7 @@ public final class EfficientParcelableChecker extends BugChecker } if (WRITE_PARCELABLE.matches(tree, state)) { return buildDescription(tree) - .setMessage("Recommended to use 'item.writeToParcel()' to improve " + .setMessage("Recommended to use 'writeTypedObject()' to improve " + "efficiency; saves overhead of Parcelable class name") .build(); } diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java index 03e0ab0591a1..a31acc8c09b9 100644 --- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java +++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java @@ -249,9 +249,10 @@ public class GroupedTaskInfo implements Parcelable { return null; } return "id=" + taskInfo.taskId - + " baseIntent=" + (taskInfo.baseIntent != null - ? taskInfo.baseIntent.getComponent() - : "null") + + " baseIntent=" + + (taskInfo.baseIntent != null && taskInfo.baseIntent.getComponent() != null + ? taskInfo.baseIntent.getComponent().flattenToString() + : "null") + " winMode=" + WindowConfiguration.windowingModeToString( taskInfo.getWindowingMode()); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java index 0fd98ed7eaf1..823c533e8e72 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java @@ -274,8 +274,11 @@ public class BubbleController implements ConfigurationChangeListener, private final DragAndDropController mDragAndDropController; /** Used to send bubble events to launcher. */ private Bubbles.BubbleStateListener mBubbleStateListener; - /** Used to track previous navigation mode to detect switch to buttons navigation. */ - private boolean mIsPrevNavModeGestures; + /** + * Used to track previous navigation mode to detect switch to buttons navigation. Set to + * true to switch the bubble bar to the opposite side for 3 nav buttons mode on device boot. + */ + private boolean mIsPrevNavModeGestures = true; /** Used to send updates to the views from {@link #mBubbleDataListener}. */ private BubbleViewCallback mBubbleViewCallback; @@ -357,7 +360,6 @@ public class BubbleController implements ConfigurationChangeListener, } }; mExpandedViewManager = BubbleExpandedViewManager.fromBubbleController(this); - mIsPrevNavModeGestures = ContextUtils.isGestureNavigationMode(mContext); } private void registerOneHandedState(OneHandedController oneHanded) { @@ -593,9 +595,9 @@ public class BubbleController implements ConfigurationChangeListener, if (mBubbleStateListener != null) { boolean isCurrentNavModeGestures = ContextUtils.isGestureNavigationMode(mContext); if (mIsPrevNavModeGestures && !isCurrentNavModeGestures) { - BubbleBarLocation navButtonsLocation = ContextUtils.isRtl(mContext) + BubbleBarLocation bubbleBarLocation = ContextUtils.isRtl(mContext) ? BubbleBarLocation.RIGHT : BubbleBarLocation.LEFT; - mBubblePositioner.setBubbleBarLocation(navButtonsLocation); + mBubblePositioner.setBubbleBarLocation(bubbleBarLocation); } mIsPrevNavModeGestures = isCurrentNavModeGestures; BubbleBarUpdate update = mBubbleData.getInitialStateForBubbleBar(); @@ -1295,6 +1297,14 @@ public class BubbleController implements ConfigurationChangeListener, // We still have bubbles, if we dragged an individual bubble to dismiss we were expanded // so re-expand to whatever is selected. showExpandedViewForBubbleBar(); + if (bubbleKey.equals(selectedBubbleKey)) { + // We dragged the selected bubble to dismiss, log switch event + if (mBubbleData.getSelectedBubble() instanceof Bubble) { + // Log only bubbles as overflow can't be dragged + mLogger.log((Bubble) mBubbleData.getSelectedBubble(), + BubbleLogger.Event.BUBBLE_BAR_BUBBLE_SWITCHED); + } + } } } @@ -1337,10 +1347,16 @@ public class BubbleController implements ConfigurationChangeListener, public void expandStackAndSelectBubbleFromLauncher(String key, int topOnScreen) { mBubblePositioner.setBubbleBarTopOnScreen(topOnScreen); + boolean wasExpanded = (mLayerView != null && mLayerView.isExpanded()); + if (BubbleOverflow.KEY.equals(key)) { mBubbleData.setSelectedBubbleFromLauncher(mBubbleData.getOverflow()); mLayerView.showExpandedView(mBubbleData.getOverflow()); - mLogger.log(BubbleLogger.Event.BUBBLE_BAR_EXPANDED); + if (wasExpanded) { + mLogger.log(BubbleLogger.Event.BUBBLE_BAR_BUBBLE_SWITCHED); + } else { + mLogger.log(BubbleLogger.Event.BUBBLE_BAR_EXPANDED); + } return; } @@ -1352,7 +1368,11 @@ public class BubbleController implements ConfigurationChangeListener, // already in the stack mBubbleData.setSelectedBubbleFromLauncher(b); mLayerView.showExpandedView(b); - mLogger.log(b, BubbleLogger.Event.BUBBLE_BAR_EXPANDED); + if (wasExpanded) { + mLogger.log(b, BubbleLogger.Event.BUBBLE_BAR_BUBBLE_SWITCHED); + } else { + mLogger.log(b, BubbleLogger.Event.BUBBLE_BAR_EXPANDED); + } } else if (mBubbleData.hasOverflowBubbleWithKey(b.getKey())) { // TODO: (b/271468319) handle overflow } else { @@ -2081,6 +2101,9 @@ public class BubbleController implements ConfigurationChangeListener, // Only need to update the layer view if we're currently expanded for selection changes. if (mLayerView != null && mLayerView.isExpanded()) { mLayerView.showExpandedView(selectedBubble); + if (selectedBubble instanceof Bubble bubble) { + mLogger.log(bubble, BubbleLogger.Event.BUBBLE_BAR_BUBBLE_SWITCHED); + } } } }; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt index 7446b88e2507..6928c255edde 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt @@ -1179,7 +1179,7 @@ class DesktopTasksController( val userContext = context.createContextAsUser(userHandle, /* flags= */ 0) val intent = Intent(userContext, DesktopWallpaperActivity::class.java) - intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); + intent.putExtra(Intent.EXTRA_USER_HANDLE, userId) val options = ActivityOptions.makeBasic().apply { launchWindowingMode = WINDOWING_MODE_FULLSCREEN diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java index 5ffc64f412f1..79a9ce5212c6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java @@ -47,7 +47,6 @@ import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipMenuController; -import com.android.wm.shell.common.split.SplitScreenUtils; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.DefaultMixedHandler; @@ -312,10 +311,10 @@ public abstract class PipTransitionController implements Transitions.TransitionH } /** Whether a particular package is same as current pip package. */ - public boolean isPackageActiveInPip(String packageName) { - final TaskInfo inPipTask = mPipOrganizer.getTaskInfo(); - return packageName != null && inPipTask != null && mPipOrganizer.isInPip() - && packageName.equals(SplitScreenUtils.getPackageName(inPipTask.baseIntent)); + public boolean isPackageActiveInPip(@Nullable String packageName) { + return packageName != null + && mPipBoundsState.getLastPipComponentName() != null + && packageName.equals(mPipBoundsState.getLastPipComponentName().getPackageName()); } /** Add PiP-related changes to `outWCT` for the given request. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java index bc0918331168..e901c39b8792 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java @@ -322,7 +322,7 @@ public class PipController implements ConfigurationChangeListener, mPipBoundsAlgorithm.applySnapFraction(toBounds, snapFraction); mPipBoundsState.setBounds(toBounds); } - t.setBounds(mPipTransitionState.mPipTaskToken, mPipBoundsState.getBounds()); + t.setBounds(mPipTransitionState.getPipTaskToken(), mPipBoundsState.getBounds()); } private void setDisplayLayout(DisplayLayout layout) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java index 607de0eccd77..5438a014af00 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java @@ -25,10 +25,13 @@ import android.content.Context; import android.graphics.Matrix; import android.graphics.Rect; import android.view.SurfaceControl; +import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.ProtoLog; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.pip.PipBoundsState; @@ -48,11 +51,13 @@ public class PipScheduler { private final ShellExecutor mMainExecutor; private final PipTransitionState mPipTransitionState; private PipTransitionController mPipTransitionController; - private final PipSurfaceTransactionHelper.SurfaceControlTransactionFactory + private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; @Nullable private Runnable mUpdateMovementBoundsRunnable; + private PipAlphaAnimatorSupplier mPipAlphaAnimatorSupplier; + public PipScheduler(Context context, PipBoundsState pipBoundsState, ShellExecutor mainExecutor, @@ -64,10 +69,7 @@ public class PipScheduler { mSurfaceControlTransactionFactory = new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory(); - } - - ShellExecutor getMainExecutor() { - return mMainExecutor; + mPipAlphaAnimatorSupplier = PipAlphaAnimator::new; } void setPipTransitionController(PipTransitionController pipTransitionController) { @@ -76,27 +78,29 @@ public class PipScheduler { @Nullable private WindowContainerTransaction getExitPipViaExpandTransaction() { - if (mPipTransitionState.mPipTaskToken == null) { + WindowContainerToken pipTaskToken = mPipTransitionState.getPipTaskToken(); + if (pipTaskToken == null) { return null; } WindowContainerTransaction wct = new WindowContainerTransaction(); // final expanded bounds to be inherited from the parent - wct.setBounds(mPipTransitionState.mPipTaskToken, null); + wct.setBounds(pipTaskToken, null); // if we are hitting a multi-activity case // windowing mode change will reparent to original host task - wct.setWindowingMode(mPipTransitionState.mPipTaskToken, WINDOWING_MODE_UNDEFINED); + wct.setWindowingMode(pipTaskToken, WINDOWING_MODE_UNDEFINED); return wct; } @Nullable private WindowContainerTransaction getRemovePipTransaction() { - if (mPipTransitionState.mPipTaskToken == null) { + WindowContainerToken pipTaskToken = mPipTransitionState.getPipTaskToken(); + if (pipTaskToken == null) { return null; } WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.setBounds(mPipTransitionState.mPipTaskToken, null); - wct.setWindowingMode(mPipTransitionState.mPipTaskToken, WINDOWING_MODE_UNDEFINED); - wct.reorder(mPipTransitionState.mPipTaskToken, false); + wct.setBounds(pipTaskToken, null); + wct.setWindowingMode(pipTaskToken, WINDOWING_MODE_UNDEFINED); + wct.reorder(pipTaskToken, false); return wct; } @@ -117,7 +121,7 @@ public class PipScheduler { /** Runs remove PiP animation and schedules remove PiP transition after the animation ends. */ public void removePipAfterAnimation() { SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); - PipAlphaAnimator animator = new PipAlphaAnimator(mContext, + PipAlphaAnimator animator = mPipAlphaAnimatorSupplier.get(mContext, mPipTransitionState.getPinnedTaskLeash(), tx, PipAlphaAnimator.FADE_OUT); animator.setAnimationEndCallback(this::scheduleRemovePipImmediately); animator.start(); @@ -159,13 +163,14 @@ public class PipScheduler { * for running the animator will get this as an extra. */ public void scheduleAnimateResizePip(Rect toBounds, boolean configAtEnd, int duration) { - if (mPipTransitionState.mPipTaskToken == null || !mPipTransitionState.isInPip()) { + WindowContainerToken pipTaskToken = mPipTransitionState.getPipTaskToken(); + if (pipTaskToken == null || !mPipTransitionState.isInPip()) { return; } WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.setBounds(mPipTransitionState.mPipTaskToken, toBounds); + wct.setBounds(pipTaskToken, toBounds); if (configAtEnd) { - wct.deferConfigToTransitionEnd(mPipTransitionState.mPipTaskToken); + wct.deferConfigToTransitionEnd(pipTaskToken); } mPipTransitionController.startResizeTransition(wct, duration); } @@ -204,7 +209,7 @@ public class PipScheduler { return; } SurfaceControl leash = mPipTransitionState.getPinnedTaskLeash(); - final SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); + final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); Matrix transformTensor = new Matrix(); final float[] mMatrixTmp = new float[9]; @@ -218,7 +223,7 @@ public class PipScheduler { tx.apply(); } - void setUpdateMovementBoundsRunnable(Runnable updateMovementBoundsRunnable) { + void setUpdateMovementBoundsRunnable(@Nullable Runnable updateMovementBoundsRunnable) { mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable; } @@ -235,4 +240,23 @@ public class PipScheduler { mPipBoundsState.setBounds(newBounds); maybeUpdateMovementBounds(); } + + @VisibleForTesting + void setSurfaceControlTransactionFactory( + @NonNull PipSurfaceTransactionHelper.SurfaceControlTransactionFactory factory) { + mSurfaceControlTransactionFactory = factory; + } + + @VisibleForTesting + interface PipAlphaAnimatorSupplier { + PipAlphaAnimator get(@NonNull Context context, + SurfaceControl leash, + SurfaceControl.Transaction tx, + @PipAlphaAnimator.Fade int direction); + } + + @VisibleForTesting + void setPipAlphaAnimatorSupplier(@NonNull PipAlphaAnimatorSupplier supplier) { + mPipAlphaAnimatorSupplier = supplier; + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java index 3caad0966b1f..d415c10b0cf8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java @@ -420,7 +420,8 @@ public class PipTransition extends PipTransitionController implements } // Update the src-rect-hint in params in place, to set up initial animator transform. - params.getSourceRectHint().set(adjustedSourceRectHint); + params.copyOnlySet(new PictureInPictureParams.Builder() + .setSourceRectHint(adjustedSourceRectHint).build()); // Config-at-end transitions need to have their activities transformed before starting // the animation; this makes the buffer seem like it's been updated to final size. @@ -543,7 +544,7 @@ public class PipTransition extends PipTransitionController implements @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { - WindowContainerToken pipToken = mPipTransitionState.mPipTaskToken; + WindowContainerToken pipToken = mPipTransitionState.getPipTaskToken(); TransitionInfo.Change pipChange = getChangeByToken(info, pipToken); if (pipChange == null) { @@ -773,11 +774,11 @@ public class PipTransition extends PipTransitionController implements } private boolean isRemovePipTransition(@NonNull TransitionInfo info) { - if (mPipTransitionState.mPipTaskToken == null) { + if (mPipTransitionState.getPipTaskToken() == null) { // PiP removal makes sense if enter-PiP has cached a valid pinned task token. return false; } - TransitionInfo.Change pipChange = info.getChange(mPipTransitionState.mPipTaskToken); + TransitionInfo.Change pipChange = info.getChange(mPipTransitionState.getPipTaskToken()); if (pipChange == null) { // Search for the PiP change by token since the windowing mode might be FULLSCREEN now. return false; @@ -859,18 +860,18 @@ public class PipTransition extends PipTransitionController implements Preconditions.checkState(extra != null, "No extra bundle for " + mPipTransitionState); - mPipTransitionState.mPipTaskToken = extra.getParcelable( - PIP_TASK_TOKEN, WindowContainerToken.class); + mPipTransitionState.setPipTaskToken(extra.getParcelable( + PIP_TASK_TOKEN, WindowContainerToken.class)); mPipTransitionState.setPinnedTaskLeash(extra.getParcelable( PIP_TASK_LEASH, SurfaceControl.class)); - boolean hasValidTokenAndLeash = mPipTransitionState.mPipTaskToken != null + boolean hasValidTokenAndLeash = mPipTransitionState.getPipTaskToken() != null && mPipTransitionState.getPinnedTaskLeash() != null; Preconditions.checkState(hasValidTokenAndLeash, "Unexpected bundle for " + mPipTransitionState); break; case PipTransitionState.EXITED_PIP: - mPipTransitionState.mPipTaskToken = null; + mPipTransitionState.setPipTaskToken(null); mPipTransitionState.setPinnedTaskLeash(null); break; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java index 03e06f906015..8e90bfee2636 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java @@ -138,7 +138,7 @@ public class PipTransitionState { // pinned PiP task's WC token @Nullable - WindowContainerToken mPipTaskToken; + private WindowContainerToken mPipTaskToken; // pinned PiP task's leash @Nullable @@ -304,6 +304,14 @@ public class PipTransitionState { mSwipePipToHomeAppBounds.setEmpty(); } + @Nullable WindowContainerToken getPipTaskToken() { + return mPipTaskToken; + } + + public void setPipTaskToken(@Nullable WindowContainerToken token) { + mPipTaskToken = token; + } + @Nullable SurfaceControl getPinnedTaskLeash() { return mPinnedTaskLeash; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java index f739d65e63c3..49cf8ae81aa8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java @@ -63,6 +63,8 @@ public enum ShellProtoLogGroup implements IProtoLogGroup { "Bubbles"), WM_SHELL_COMPAT_UI(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM_COMPAT_UI), + WM_SHELL_APP_COMPAT(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, + Consts.TAG_WM_APP_COMPAT), TEST_GROUP(true, true, false, "WindowManagerShellProtoLogTest"); private final boolean mEnabled; @@ -131,6 +133,7 @@ public enum ShellProtoLogGroup implements IProtoLogGroup { private static final String TAG_WM_SPLIT_SCREEN = "ShellSplitScreen"; private static final String TAG_WM_DESKTOP_MODE = "ShellDesktopMode"; private static final String TAG_WM_COMPAT_UI = "CompatUi"; + private static final String TAG_WM_APP_COMPAT = "AppCompat"; private static final boolean ENABLE_DEBUG = true; private static final boolean ENABLE_LOG_TO_PROTO_DEBUG = true; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java index 9911669d2cb8..cea4d33d85c8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java @@ -205,7 +205,7 @@ public class RecentTasksController implements TaskStackListenerCallback, mTaskSplitBoundsMap.put(taskId1, splitBounds); mTaskSplitBoundsMap.put(taskId2, splitBounds); notifyRecentTasksChanged(); - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENT_TASKS, "Add split pair: %d, %d, %s", + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Add split pair: %d, %d, %s", taskId1, taskId2, splitBounds); return true; } @@ -221,7 +221,7 @@ public class RecentTasksController implements TaskStackListenerCallback, mTaskSplitBoundsMap.remove(taskId); mTaskSplitBoundsMap.remove(pairedTaskId); notifyRecentTasksChanged(); - ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENT_TASKS, "Remove split pair: %d, %d", + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Remove split pair: %d, %d", taskId, pairedTaskId); } } @@ -234,7 +234,17 @@ public class RecentTasksController implements TaskStackListenerCallback, // We could do extra verification of requiring both taskIds of a pair and verifying that // the same split bounds object is returned... but meh. Seems unnecessary. - return mTaskSplitBoundsMap.get(taskId); + SplitBounds splitBounds = mTaskSplitBoundsMap.get(taskId); + if (splitBounds != null) { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "getSplitBoundsForTaskId: taskId=%d splitBoundsTasks=[%d, %d]", taskId, + splitBounds.leftTopTaskId, splitBounds.rightBottomTaskId); + } else { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, + "getSplitBoundsForTaskId: expected split bounds for taskId=%d but not found", + taskId); + } + return splitBounds; } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java index 9016c45e8197..417a6558ffcc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java @@ -1286,6 +1286,16 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, if (mFinishCB == null || (Flags.enableShellTopTaskTracking() && mPendingFinishTransition != null)) { Slog.e(TAG, "Duplicate call to finish"); + if (runnerFinishCb != null) { + try { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, + "[%d] RecentsController.finishInner: calling finish callback", + mInstanceId); + runnerFinishCb.send(0, null); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to report transition finished", e); + } + } return; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index cc0e1df115c2..7d1ffb80735e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -1362,7 +1362,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } void clearSplitPairedInRecents(@ExitReason int exitReason) { - if (!shouldBreakPairedTaskInRecents(exitReason) || !mShouldUpdateRecents) return; + if (!shouldBreakPairedTaskInRecents(exitReason) || !mShouldUpdateRecents) { + ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "clearSplitPairedInRecents: skipping reason=%s", + !mShouldUpdateRecents ? "shouldn't update" : exitReasonToString(exitReason)); + return; + } ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "clearSplitPairedInRecents: reason=%s", exitReasonToString(exitReason)); @@ -1608,6 +1612,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private void updateRecentTasksSplitPair() { // Preventing from single task update while processing recents. if (!mShouldUpdateRecents || !mPausingTasks.isEmpty()) { + ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "updateRecentTasksSplitPair: skipping reason=%s", + !mShouldUpdateRecents ? "shouldn't update" : "no pausing tasks"); return; } mRecentTasks.ifPresent(recentTasks -> { diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/MaximizeAppWindowWithDragToTopDragZoneTest.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/MaximizeAppWindowWithDragToTopDragZoneTest.kt new file mode 100644 index 000000000000..7e0b81a783c0 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/MaximizeAppWindowWithDragToTopDragZoneTest.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.functional + +import android.platform.test.annotations.Postsubmit +import com.android.wm.shell.scenarios.MaximizeAppWindowWithDragToTopDragZone +import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner + +/* Functional test for [MaximizeAppWindowWithDragToTopDragZone]. */ +@RunWith(BlockJUnit4ClassRunner::class) +@Postsubmit +class MaximizeAppWindowWithDragToTopDragZoneTest : MaximizeAppWindowWithDragToTopDragZone() diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MaximizeAppWindowWithDragToTopDragZone.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MaximizeAppWindowWithDragToTopDragZone.kt new file mode 100644 index 000000000000..a2b88f278ff2 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MaximizeAppWindowWithDragToTopDragZone.kt @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.scenarios + +import android.app.Instrumentation +import android.tools.NavBar +import android.tools.Rotation +import android.tools.flicker.rules.ChangeDisplayOrientationRule +import android.tools.traces.parsers.WindowManagerStateHelper +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import com.android.internal.R +import com.android.launcher3.tapl.LauncherInstrumentation +import com.android.server.wm.flicker.helpers.DesktopModeAppHelper +import com.android.server.wm.flicker.helpers.SimpleAppHelper +import com.android.window.flags.Flags +import com.android.wm.shell.Utils +import org.junit.After +import org.junit.Assume +import org.junit.Before +import org.junit.Ignore +import org.junit.Rule +import org.junit.Test + +/** + * Base scenario test for maximizing a desktop app window by dragging it to the top drag zone. + */ +@Ignore("Test Base Class") +abstract class MaximizeAppWindowWithDragToTopDragZone +constructor(private val rotation: Rotation = Rotation.ROTATION_0) { + private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() + private val tapl = LauncherInstrumentation() + private val wmHelper = WindowManagerStateHelper(instrumentation) + private val device = UiDevice.getInstance(instrumentation) + private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation)) + + @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation) + + @Before + fun setup() { + Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet) + // Skip the test when the drag-to-maximize is disabled on this device. + Assume.assumeTrue(Flags.enableDragToMaximize() && + instrumentation.context.resources.getBoolean(R.bool.config_dragToMaximizeInDesktopMode)) + tapl.setEnableRotation(true) + tapl.setExpectedRotation(rotation.value) + ChangeDisplayOrientationRule.setRotation(rotation) + testApp.enterDesktopWithDrag(wmHelper, device) + } + + @Test + open fun maximizeAppWithDragToTopDragZone() { + testApp.maximizeAppWithDragToTopDragZone(wmHelper, device) + } + + @After + fun teardown() { + testApp.exit(wmHelper) + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java new file mode 100644 index 000000000000..cab625216236 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.pip2.phone; + +import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP; +import static com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.when; +import static org.mockito.kotlin.MatchersKt.eq; +import static org.mockito.kotlin.VerificationKt.times; +import static org.mockito.kotlin.VerificationKt.verify; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Matrix; +import android.graphics.Rect; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.view.SurfaceControl; +import android.window.WindowContainerToken; +import android.window.WindowContainerTransaction; + +import androidx.test.filters.SmallTest; + +import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.common.pip.PipBoundsState; +import com.android.wm.shell.pip.PipTransitionController; +import com.android.wm.shell.pip2.PipSurfaceTransactionHelper; +import com.android.wm.shell.pip2.animation.PipAlphaAnimator; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Unit test against {@link PipScheduler} + */ + +@SmallTest +@TestableLooper.RunWithLooper +@RunWith(AndroidTestingRunner.class) +public class PipSchedulerTest { + private static final int TEST_RESIZE_DURATION = 1; + private static final Rect TEST_STARTING_BOUNDS = new Rect(0, 0, 10, 10); + private static final Rect TEST_BOUNDS = new Rect(0, 0, 20, 20); + + @Mock private Context mMockContext; + @Mock private Resources mMockResources; + @Mock private PipBoundsState mMockPipBoundsState; + @Mock private ShellExecutor mMockMainExecutor; + @Mock private PipTransitionState mMockPipTransitionState; + @Mock private PipTransitionController mMockPipTransitionController; + @Mock private Runnable mMockUpdateMovementBoundsRunnable; + @Mock private WindowContainerToken mMockPipTaskToken; + @Mock private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mMockFactory; + @Mock private SurfaceControl.Transaction mMockTransaction; + @Mock private PipAlphaAnimator mMockAlphaAnimator; + + @Captor private ArgumentCaptor<Runnable> mRunnableArgumentCaptor; + @Captor private ArgumentCaptor<WindowContainerTransaction> mWctArgumentCaptor; + + private PipScheduler mPipScheduler; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mMockContext.getResources()).thenReturn(mMockResources); + when(mMockResources.getInteger(anyInt())).thenReturn(0); + when(mMockPipBoundsState.getBounds()).thenReturn(TEST_STARTING_BOUNDS); + when(mMockFactory.getTransaction()).thenReturn(mMockTransaction); + when(mMockTransaction.setMatrix(any(SurfaceControl.class), any(Matrix.class), any())) + .thenReturn(mMockTransaction); + + mPipScheduler = new PipScheduler(mMockContext, mMockPipBoundsState, mMockMainExecutor, + mMockPipTransitionState); + mPipScheduler.setPipTransitionController(mMockPipTransitionController); + mPipScheduler.setSurfaceControlTransactionFactory(mMockFactory); + mPipScheduler.setPipAlphaAnimatorSupplier((context, leash, tx, direction) -> + mMockAlphaAnimator); + + SurfaceControl testLeash = new SurfaceControl.Builder() + .setContainerLayer() + .setName("PipSchedulerTest") + .setCallsite("PipSchedulerTest") + .build(); + when(mMockPipTransitionState.getPinnedTaskLeash()).thenReturn(testLeash); + } + + @Test + public void scheduleExitPipViaExpand_nullTaskToken_noop() { + setNullPipTaskToken(); + + mPipScheduler.scheduleExitPipViaExpand(); + + verify(mMockMainExecutor, never()).execute(any()); + } + + @Test + public void scheduleExitPipViaExpand_exitTransitionCalled() { + setMockPipTaskToken(); + + mPipScheduler.scheduleExitPipViaExpand(); + + verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture()); + assertNotNull(mRunnableArgumentCaptor.getValue()); + mRunnableArgumentCaptor.getValue().run(); + + verify(mMockPipTransitionController, times(1)) + .startExitTransition(eq(TRANSIT_EXIT_PIP), any(), isNull()); + } + + @Test + public void removePipAfterAnimation() { + //TODO: Update once this is changed to run animation as part of transition + setMockPipTaskToken(); + + mPipScheduler.removePipAfterAnimation(); + verify(mMockAlphaAnimator, times(1)) + .setAnimationEndCallback(mRunnableArgumentCaptor.capture()); + assertNotNull(mRunnableArgumentCaptor.getValue()); + verify(mMockAlphaAnimator, times(1)).start(); + + mRunnableArgumentCaptor.getValue().run(); + + verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture()); + assertNotNull(mRunnableArgumentCaptor.getValue()); + + mRunnableArgumentCaptor.getValue().run(); + + verify(mMockPipTransitionController, times(1)) + .startExitTransition(eq(TRANSIT_REMOVE_PIP), any(), isNull()); + } + + @Test + public void scheduleAnimateResizePip_bounds_nullTaskToken_noop() { + setNullPipTaskToken(); + + mPipScheduler.scheduleAnimateResizePip(TEST_BOUNDS); + + verify(mMockPipTransitionController, never()).startResizeTransition(any(), anyInt()); + } + + @Test + public void scheduleAnimateResizePip_boundsConfig_nullTaskToken_noop() { + setNullPipTaskToken(); + + mPipScheduler.scheduleAnimateResizePip(TEST_BOUNDS, true); + + verify(mMockPipTransitionController, never()).startResizeTransition(any(), anyInt()); + } + + @Test + public void scheduleAnimateResizePip_boundsConfig_setsConfigAtEnd() { + setMockPipTaskToken(); + when(mMockPipTransitionState.isInPip()).thenReturn(true); + + mPipScheduler.scheduleAnimateResizePip(TEST_BOUNDS, true); + + verify(mMockPipTransitionController, times(1)) + .startResizeTransition(mWctArgumentCaptor.capture(), anyInt()); + assertNotNull(mWctArgumentCaptor.getValue()); + assertNotNull(mWctArgumentCaptor.getValue().getChanges()); + boolean hasConfigAtEndChange = false; + for (WindowContainerTransaction.Change change : + mWctArgumentCaptor.getValue().getChanges().values()) { + if (change.getConfigAtTransitionEnd()) { + hasConfigAtEndChange = true; + break; + } + } + assertTrue(hasConfigAtEndChange); + } + + @Test + public void scheduleAnimateResizePip_boundsConfigDuration_nullTaskToken_noop() { + setNullPipTaskToken(); + + mPipScheduler.scheduleAnimateResizePip(TEST_BOUNDS, true, TEST_RESIZE_DURATION); + + verify(mMockPipTransitionController, never()).startResizeTransition(any(), anyInt()); + } + + @Test + public void scheduleAnimateResizePip_notInPip_noop() { + setMockPipTaskToken(); + when(mMockPipTransitionState.isInPip()).thenReturn(false); + + mPipScheduler.scheduleAnimateResizePip(TEST_BOUNDS, true, TEST_RESIZE_DURATION); + + verify(mMockPipTransitionController, never()).startResizeTransition(any(), anyInt()); + } + + @Test + public void scheduleAnimateResizePip_resizeTransition() { + setMockPipTaskToken(); + when(mMockPipTransitionState.isInPip()).thenReturn(true); + + mPipScheduler.scheduleAnimateResizePip(TEST_BOUNDS, true, TEST_RESIZE_DURATION); + + verify(mMockPipTransitionController, times(1)) + .startResizeTransition(any(), eq(TEST_RESIZE_DURATION)); + } + + @Test + public void scheduleUserResizePip_emptyBounds_noop() { + setMockPipTaskToken(); + + mPipScheduler.scheduleUserResizePip(new Rect()); + + verify(mMockTransaction, never()).apply(); + } + + @Test + public void scheduleUserResizePip_rotation_emptyBounds_noop() { + setMockPipTaskToken(); + + mPipScheduler.scheduleUserResizePip(new Rect(), 90); + + verify(mMockTransaction, never()).apply(); + } + + @Test + public void scheduleUserResizePip_applyTransaction() { + setMockPipTaskToken(); + + mPipScheduler.scheduleUserResizePip(TEST_BOUNDS, 90); + + verify(mMockTransaction, times(1)).apply(); + } + + @Test + public void finishResize_movementBoundsRunnableCalled() { + mPipScheduler.setUpdateMovementBoundsRunnable(mMockUpdateMovementBoundsRunnable); + mPipScheduler.scheduleFinishResizePip(TEST_BOUNDS); + + verify(mMockUpdateMovementBoundsRunnable, times(1)).run(); + } + + private void setNullPipTaskToken() { + when(mMockPipTransitionState.getPipTaskToken()).thenReturn(null); + } + + private void setMockPipTaskToken() { + when(mMockPipTransitionState.getPipTaskToken()).thenReturn(mMockPipTaskToken); + } +} diff --git a/media/java/android/media/AudioPlaybackConfiguration.java b/media/java/android/media/AudioPlaybackConfiguration.java index 3cd5f5266ef2..da50f2cd86c4 100644 --- a/media/java/android/media/AudioPlaybackConfiguration.java +++ b/media/java/android/media/AudioPlaybackConfiguration.java @@ -19,6 +19,7 @@ package android.media; import static android.media.AudioAttributes.ALLOW_CAPTURE_BY_ALL; import static android.media.AudioAttributes.ALLOW_CAPTURE_BY_NONE; import static android.media.audio.Flags.FLAG_MUTED_BY_PORT_VOLUME_API; +import static android.media.audio.Flags.FLAG_ROUTED_DEVICE_IDS; import android.annotation.FlaggedApi; import android.annotation.IntDef; @@ -39,6 +40,8 @@ import com.android.internal.annotations.GuardedBy; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; /** @@ -461,8 +464,12 @@ public final class AudioPlaybackConfiguration implements Parcelable { /** * Returns information about the {@link AudioDeviceInfo} used for this playback. - * @return the audio playback device or null if the device is not available at the time of query + * @return the audio playback device or null if the device is not available at the time of + * query. + * @deprecated this information was never populated */ + @Deprecated + @FlaggedApi(FLAG_ROUTED_DEVICE_IDS) public @Nullable AudioDeviceInfo getAudioDeviceInfo() { final int deviceId; synchronized (mUpdateablePropLock) { @@ -476,6 +483,23 @@ public final class AudioPlaybackConfiguration implements Parcelable { /** * @hide + * Returns information about the List of {@link AudioDeviceInfo} used for this playback. + * @return the audio playback devices + */ + @SystemApi + @FlaggedApi(FLAG_ROUTED_DEVICE_IDS) + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public @NonNull List<AudioDeviceInfo> getAudioDeviceInfos() { + List<AudioDeviceInfo> audioDeviceInfos = new ArrayList<AudioDeviceInfo>(); + AudioDeviceInfo audioDeviceInfo = getAudioDeviceInfo(); + if (audioDeviceInfo != null) { + audioDeviceInfos.add(audioDeviceInfo); + } + return audioDeviceInfos; + } + + /** + * @hide * Return the audio session ID associated with this player. * See {@link AudioManager#generateAudioSessionId()}. * @return an audio session ID diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java index 80e57193d0dc..939494152116 100644 --- a/media/java/android/media/AudioRecord.java +++ b/media/java/android/media/AudioRecord.java @@ -20,8 +20,10 @@ import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAUL import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_AUDIO; import static android.content.Context.DEVICE_ID_DEFAULT; import static android.media.AudioManager.AUDIO_SESSION_ID_GENERATE; +import static android.media.audio.Flags.FLAG_ROUTED_DEVICE_IDS; import android.annotation.CallbackExecutor; +import android.annotation.FlaggedApi; import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.IntRange; @@ -1920,6 +1922,23 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection, } /** + * Returns a List of {@link AudioDeviceInfo} identifying the current routing of this + * AudioRecord. + * Note: The query is only valid if the AudioRecord is currently playing. If it is not, + * <code>getRoutedDevices()</code> will return an empty list. + */ + @Override + @FlaggedApi(FLAG_ROUTED_DEVICE_IDS) + public @NonNull List<AudioDeviceInfo> getRoutedDevices() { + List<AudioDeviceInfo> audioDeviceInfos = new ArrayList<AudioDeviceInfo>(); + AudioDeviceInfo audioDeviceInfo = getRoutedDevice(); + if (audioDeviceInfo != null) { + audioDeviceInfos.add(audioDeviceInfo); + } + return audioDeviceInfos; + } + + /** * Must match the native definition in frameworks/av/service/audioflinger/Audioflinger.h. */ private static final long MAX_SHARED_AUDIO_HISTORY_MS = 5000; diff --git a/media/java/android/media/AudioRouting.java b/media/java/android/media/AudioRouting.java index 26fa631ac6ac..22aa9a09d560 100644 --- a/media/java/android/media/AudioRouting.java +++ b/media/java/android/media/AudioRouting.java @@ -16,9 +16,16 @@ package android.media; +import static android.media.audio.Flags.FLAG_ROUTED_DEVICE_IDS; + +import android.annotation.FlaggedApi; +import android.annotation.NonNull; import android.os.Handler; import android.os.Looper; +import java.util.ArrayList; +import java.util.List; + /** * AudioRouting defines an interface for controlling routing and routing notifications in * AudioTrack and AudioRecord objects. @@ -49,6 +56,22 @@ public interface AudioRouting { public AudioDeviceInfo getRoutedDevice(); /** + * Returns a List of {@link AudioDeviceInfo} identifying the current routing of this + * AudioTrack/AudioRecord. + * Note: The query is only valid if the AudioTrack/AudioRecord is currently playing. + * If it is not, <code>getRoutedDevices()</code> will return an empty List. + */ + @FlaggedApi(FLAG_ROUTED_DEVICE_IDS) + default @NonNull List<AudioDeviceInfo> getRoutedDevices() { + List<AudioDeviceInfo> audioDeviceInfos = new ArrayList<AudioDeviceInfo>(); + AudioDeviceInfo audioDeviceInfo = getRoutedDevice(); + if (audioDeviceInfo != null) { + audioDeviceInfos.add(audioDeviceInfo); + } + return new ArrayList<AudioDeviceInfo>(); + } + + /** * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing * changes on this AudioTrack/AudioRecord. * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 03cd53580b1b..93a183188793 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -17,8 +17,10 @@ package android.media; import static android.media.AudioManager.AUDIO_SESSION_ID_GENERATE; +import static android.media.audio.Flags.FLAG_ROUTED_DEVICE_IDS; import android.annotation.CallbackExecutor; +import android.annotation.FlaggedApi; import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.IntRange; @@ -54,7 +56,9 @@ import java.lang.ref.WeakReference; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.NioUtils; +import java.util.ArrayList; import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.Executor; @@ -3783,6 +3787,8 @@ public class AudioTrack extends PlayerBase * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioTrack. * Note: The query is only valid if the AudioTrack is currently playing. If it is not, * <code>getRoutedDevice()</code> will return null. + * Audio may play on multiple devices simultaneously (e.g. an alarm playing on headphones and + * speaker on a phone), so prefer using {@link #getRoutedDevices}. */ @Override public AudioDeviceInfo getRoutedDevice() { @@ -3793,6 +3799,23 @@ public class AudioTrack extends PlayerBase return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_OUTPUTS); } + /** + * Returns a List of {@link AudioDeviceInfo} identifying the current routing of this + * AudioTrack. + * Note: The query is only valid if the AudioTrack is currently playing. If it is not, + * <code>getRoutedDevices()</code> will return an empty list. + */ + @Override + @FlaggedApi(FLAG_ROUTED_DEVICE_IDS) + public @NonNull List<AudioDeviceInfo> getRoutedDevices() { + List<AudioDeviceInfo> audioDeviceInfos = new ArrayList<AudioDeviceInfo>(); + AudioDeviceInfo audioDeviceInfo = getRoutedDevice(); + if (audioDeviceInfo != null) { + audioDeviceInfos.add(audioDeviceInfo); + } + return audioDeviceInfos; + } + private void tryToDisableNativeRoutingCallback() { synchronized (mRoutingChangeListeners) { if (mEnableSelfRoutingMonitor) { diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java index 3f9126aa9456..1ecba31ce07f 100644 --- a/media/java/android/media/MediaCas.java +++ b/media/java/android/media/MediaCas.java @@ -16,10 +16,9 @@ package android.media; +import static android.media.tv.flags.Flags.FLAG_MEDIACAS_UPDATE_CLIENT_PROFILE_PRIORITY; import static android.media.tv.flags.Flags.FLAG_SET_RESOURCE_HOLDER_RETAIN; -import static com.android.media.flags.Flags.FLAG_UPDATE_CLIENT_PROFILE_PRIORITY; - import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; @@ -996,7 +995,7 @@ public final class MediaCas implements AutoCloseable { * @param niceValue the nice value. * @hide */ - @FlaggedApi(FLAG_UPDATE_CLIENT_PROFILE_PRIORITY) + @FlaggedApi(FLAG_MEDIACAS_UPDATE_CLIENT_PROFILE_PRIORITY) @SystemApi @RequiresPermission(android.Manifest.permission.TUNER_RESOURCE_ACCESS) public boolean updateResourcePriority(int priority, int niceValue) { diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 2ae89d3300c1..82e950365850 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -16,6 +16,7 @@ package android.media; +import static android.media.codec.Flags.FLAG_CODEC_AVAILABILITY; import static android.media.codec.Flags.FLAG_NULL_OUTPUT_SURFACE; import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST; import static android.media.codec.Flags.FLAG_SUBSESSION_METRICS; @@ -29,6 +30,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.ImageFormat; import android.graphics.Rect; @@ -1843,6 +1845,12 @@ final public class MediaCodec { */ private static final int CB_METRICS_FLUSHED = 8; + /** + * Callback ID to notify the change in resource requirement + * for the codec component. + */ + private static final int CB_REQUIRED_RESOURCES_CHANGE = 9; + private class EventHandler extends Handler { private MediaCodec mCodec; @@ -2017,13 +2025,19 @@ final public class MediaCodec { case CB_METRICS_FLUSHED: { - if (GetFlag(() -> android.media.codec.Flags.subsessionMetrics())) { mCallback.onMetricsFlushed(mCodec, (PersistableBundle)msg.obj); } break; } + case CB_REQUIRED_RESOURCES_CHANGE: { + if (android.media.codec.Flags.codecAvailability()) { + mCallback.onRequiredResourcesChanged(mCodec); + } + break; + } + default: { break; @@ -2302,6 +2316,70 @@ final public class MediaCodec { } /** + * @hide + * Abstraction for the Global Codec resources. + * This encapsulates all the available codec resources on the device. + * + * To be able to enforce and test the implementation of codec availability hal APIs, + * globally available codec resources are exposed only as TestApi. + * This will be tracked and verified through cts. + */ + @FlaggedApi(FLAG_CODEC_AVAILABILITY) + @TestApi + public static final class GlobalResourceInfo { + /** + * Identifier for the Resource type. + */ + String mName; + /** + * Total count/capacity of resources of this type. + */ + long mCapacity; + /** + * Available count of this resource type. + */ + long mAvailable; + + @NonNull + public String getName() { + return mName; + } + + public long getCapacity() { + return mCapacity; + } + + public long getAvailable() { + return mAvailable; + } + }; + + /** + * @hide + * Get a list of globally available codec resources. + * + * To be able to enforce and test the implementation of codec availability hal APIs, + * it is exposed only as TestApi. + * This will be tracked and verified through cts. + * + * This returns a {@link java.util.List} list of codec resources. + * For every {@link GlobalResourceInfo} in the list, it encapsulates the + * information about each resources available globaly on device. + * + * @return A list of available device codec resources; an empty list if no + * device codec resources are available. + * @throws UnsupportedOperationException if not implemented. + */ + @FlaggedApi(FLAG_CODEC_AVAILABILITY) + @TestApi + public static @NonNull List<GlobalResourceInfo> getGloballyAvailableResources() { + return native_getGloballyAvailableResources(); + } + + @NonNull + private static native List<GlobalResourceInfo> native_getGloballyAvailableResources(); + + /** * Configures a component. * * @param format The format of the input data (decoder) or the desired @@ -2443,6 +2521,73 @@ final public class MediaCodec { } /** + * @hide + * Abstraction for the resources associated with a codec instance. + * This encapsulates the required codec resources for a configured codec instance. + * + * To be able to enforce and test the implementation of codec availability hal APIs, + * required codec resources are exposed only as TestApi. + * This will be tracked and verified through cts. + */ + @FlaggedApi(FLAG_CODEC_AVAILABILITY) + @TestApi + public static final class InstanceResourceInfo { + /** + * Identifier for the Resource type. + */ + String mName; + /** + * Required resource count of this type. + */ + long mStaticCount; + /** + * Per frame resource requirement of this resource type. + */ + long mPerFrameCount; + + @NonNull + public String getName() { + return mName; + } + + public long getStaticCount() { + return mStaticCount; + } + + public long getPerFrameCount() { + return mPerFrameCount; + } + }; + + /** + * @hide + * Get a list of required codec resources for this configuration. + * + * To be able to enforce and test the implementation of codec availability hal APIs, + * it is exposed only as TestApi. + * This will be tracked and verified through cts. + * + * This returns a {@link java.util.List} list of codec resources. + * For every {@link GlobalResourceInfo} in the list, it encapsulates the + * information about each resources required for the current configuration. + * + * NOTE: This may only be called after {@link #configure}. + * + * @return A list of required device codec resources; an empty list if no + * device codec resources are required. + * @throws IllegalStateException if the codec wasn't configured yet. + * @throws UnsupportedOperationException if not implemented. + */ + @FlaggedApi(FLAG_CODEC_AVAILABILITY) + @TestApi + public @NonNull List<InstanceResourceInfo> getRequiredResources() { + return native_getRequiredResources(); + } + + @NonNull + private native List<InstanceResourceInfo> native_getRequiredResources(); + + /** * Dynamically sets the output surface of a codec. * <p> * This can only be used if the codec was configured with an output surface. The @@ -5740,6 +5885,25 @@ final public class MediaCodec { @NonNull MediaCodec codec, @NonNull PersistableBundle metrics) { // default implementation ignores this callback. } + + /** + * @hide + * Called when there is a change in the required resources for the codec. + * <p> + * Upon receiving this notification, the updated resource requirement + * can be queried through {@link #getRequiredResources}. + * + * @param codec The MediaCodec object. + */ + @FlaggedApi(FLAG_CODEC_AVAILABILITY) + @TestApi + public void onRequiredResourcesChanged(@NonNull MediaCodec codec) { + /* + * A default implementation for backward compatibility. + * Since this is a TestApi, we are not enforcing the callback to be + * overridden. + */ + } } private void postEventFromNative( diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index a0f8ae5defeb..158bc7fcd482 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -18,7 +18,9 @@ package android.media; import static android.Manifest.permission.BIND_IMS_SERVICE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.media.audio.Flags.FLAG_ROUTED_DEVICE_IDS; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -84,6 +86,7 @@ import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.URL; import java.nio.ByteOrder; +import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; import java.util.HashMap; @@ -1542,6 +1545,8 @@ public class MediaPlayer extends PlayerBase * Note: The query is only valid if the MediaPlayer is currently playing. * If the player is not playing, the returned device can be null or correspond to previously * selected device when the player was last active. + * Audio may play on multiple devices simultaneously (e.g. an alarm playing on headphones and + * speaker on a phone), so prefer using {@link #getRoutedDevices}. */ @Override public AudioDeviceInfo getRoutedDevice() { @@ -1552,6 +1557,23 @@ public class MediaPlayer extends PlayerBase return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_OUTPUTS); } + /** + * Returns a List of {@link AudioDeviceInfo} identifying the current routing of this + * MediaPlayer. + * Note: The query is only valid if the MediaPlayer is currently playing. + * If the player is not playing, the returned devices can be empty or correspond to previously + * selected devices when the player was last active. + */ + @Override + @FlaggedApi(FLAG_ROUTED_DEVICE_IDS) + public @NonNull List<AudioDeviceInfo> getRoutedDevices() { + List<AudioDeviceInfo> audioDeviceInfos = new ArrayList<AudioDeviceInfo>(); + AudioDeviceInfo audioDeviceInfo = getRoutedDevice(); + if (audioDeviceInfo != null) { + audioDeviceInfos.add(audioDeviceInfo); + } + return audioDeviceInfos; + } /** * Sends device list change notification to all listeners. diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index 2d17bf500f12..f75bcf3c437d 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -16,7 +16,10 @@ package android.media; +import static android.media.audio.Flags.FLAG_ROUTED_DEVICE_IDS; + import android.annotation.CallbackExecutor; +import android.annotation.FlaggedApi; import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.NonNull; @@ -1695,6 +1698,24 @@ public class MediaRecorder implements AudioRouting, return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_INPUTS); } + /** + * Returns a List of {@link AudioDeviceInfo} identifying the current routing of this + * MediaRecorder. + * Note: The query is only valid if the MediaRecorder is currently recording. + * If the recorder is not recording, the returned devices can be empty or correspond to + * previously selected devices when the recorder was last active. + */ + @Override + @FlaggedApi(FLAG_ROUTED_DEVICE_IDS) + public @NonNull List<AudioDeviceInfo> getRoutedDevices() { + List<AudioDeviceInfo> audioDeviceInfos = new ArrayList<AudioDeviceInfo>(); + AudioDeviceInfo audioDeviceInfo = getRoutedDevice(); + if (audioDeviceInfo != null) { + audioDeviceInfos.add(audioDeviceInfo); + } + return audioDeviceInfos; + } + /* * Call BEFORE adding a routing callback handler or AFTER removing a routing callback handler. */ diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig index 7895eb27b372..5b1ea8b81c80 100644 --- a/media/java/android/media/flags/media_better_together.aconfig +++ b/media/java/android/media/flags/media_better_together.aconfig @@ -78,13 +78,6 @@ flag { } flag { - name: "update_client_profile_priority" - namespace: "media_solutions" - description : "Feature flag to add updateResourcePriority api to MediaCas" - bug: "300565729" -} - -flag { name: "enable_built_in_speaker_route_suitability_statuses" is_exported: true namespace: "media_solutions" diff --git a/media/java/android/media/quality/AmbientBacklightEvent.java b/media/java/android/media/quality/AmbientBacklightEvent.java index 3bc6b86c0615..5c11def43209 100644 --- a/media/java/android/media/quality/AmbientBacklightEvent.java +++ b/media/java/android/media/quality/AmbientBacklightEvent.java @@ -16,9 +16,11 @@ package android.media.quality; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.media.tv.flags.Flags; import android.os.Parcel; import android.os.Parcelable; @@ -27,8 +29,10 @@ import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** + * Ambient backlight event * @hide */ +@FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW) public final class AmbientBacklightEvent implements Parcelable { /** @hide */ @@ -64,6 +68,9 @@ public final class AmbientBacklightEvent implements Parcelable { @Nullable private final AmbientBacklightMetadata mMetadata; + /** + * Constructor of AmbientBacklightEvent. + */ public AmbientBacklightEvent(int eventType, @Nullable AmbientBacklightMetadata metadata) { mEventType = eventType; @@ -75,10 +82,19 @@ public final class AmbientBacklightEvent implements Parcelable { mMetadata = in.readParcelable(AmbientBacklightMetadata.class.getClassLoader()); } + /** + * Gets event type. + */ public int getEventType() { return mEventType; } + /** + * Gets ambient backlight metadata. + * + * @return the metadata of the event. It's non-null only for + * {@link #AMBIENT_BACKLIGHT_EVENT_METADATA}. + */ @Nullable public AmbientBacklightMetadata getMetadata() { return mMetadata; @@ -95,7 +111,8 @@ public final class AmbientBacklightEvent implements Parcelable { return 0; } - public static final @NonNull Parcelable.Creator<AmbientBacklightEvent> CREATOR = + @NonNull + public static final Parcelable.Creator<AmbientBacklightEvent> CREATOR = new Parcelable.Creator<AmbientBacklightEvent>() { public AmbientBacklightEvent createFromParcel(Parcel in) { return new AmbientBacklightEvent(in); diff --git a/media/java/android/media/quality/AmbientBacklightMetadata.java b/media/java/android/media/quality/AmbientBacklightMetadata.java index fc779348de11..9c11f9a3e560 100644 --- a/media/java/android/media/quality/AmbientBacklightMetadata.java +++ b/media/java/android/media/quality/AmbientBacklightMetadata.java @@ -16,6 +16,10 @@ package android.media.quality; +import android.annotation.FlaggedApi; +import android.annotation.IntRange; +import android.graphics.PixelFormat; +import android.media.tv.flags.Flags; import android.os.Parcel; import android.os.Parcelable; @@ -24,9 +28,11 @@ import androidx.annotation.NonNull; import java.util.Arrays; /** + * Metadata of ambient backlight. * @hide */ -public class AmbientBacklightMetadata implements Parcelable { +@FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW) +public final class AmbientBacklightMetadata implements Parcelable { @NonNull private final String mPackageName; private final int mCompressAlgorithm; @@ -37,6 +43,9 @@ public class AmbientBacklightMetadata implements Parcelable { @NonNull private final int[] mZonesColors; + /** + * Constructor of AmbientBacklightMetadata. + */ public AmbientBacklightMetadata(@NonNull String packageName, int compressAlgorithm, int source, int colorFormat, int horizontalZonesNumber, int verticalZonesNumber, @NonNull int[] zonesColors) { @@ -59,31 +68,58 @@ public class AmbientBacklightMetadata implements Parcelable { mZonesColors = in.createIntArray(); } + /** + * Gets package name. + * @hide + */ @NonNull public String getPackageName() { return mPackageName; } + /** + * Gets compress algorithm. + */ + @AmbientBacklightSettings.CompressAlgorithm public int getCompressAlgorithm() { return mCompressAlgorithm; } + /** + * Gets source of ambient backlight detection. + */ + @AmbientBacklightSettings.Source public int getSource() { return mSource; } + /** + * Gets color format. + */ + @PixelFormat.Format public int getColorFormat() { return mColorFormat; } + /** + * Gets the number of lights in each horizontal zone. + */ + @IntRange(from = 0) public int getHorizontalZonesNumber() { return mHorizontalZonesNumber; } + /** + * Gets the number of lights in each vertical zone. + */ + @IntRange(from = 0) public int getVerticalZonesNumber() { return mVerticalZonesNumber; } + /** + * @hide + */ @NonNull public int[] getZonesColors() { return mZonesColors; diff --git a/media/java/android/media/quality/AmbientBacklightSettings.java b/media/java/android/media/quality/AmbientBacklightSettings.java index bb782bf1aee4..4ed7bc79fdca 100644 --- a/media/java/android/media/quality/AmbientBacklightSettings.java +++ b/media/java/android/media/quality/AmbientBacklightSettings.java @@ -16,7 +16,11 @@ package android.media.quality; +import android.annotation.FlaggedApi; import android.annotation.IntDef; +import android.annotation.IntRange; +import android.graphics.PixelFormat; +import android.media.tv.flags.Flags; import android.os.Parcel; import android.os.Parcelable; @@ -29,7 +33,8 @@ import java.lang.annotation.RetentionPolicy; * Settings for ambient backlight. * @hide */ -public class AmbientBacklightSettings implements Parcelable { +@FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW) +public final class AmbientBacklightSettings implements Parcelable { /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef({SOURCE_NONE, SOURCE_AUDIO, SOURCE_VIDEO, SOURCE_AUDIO_VIDEO}) @@ -62,6 +67,7 @@ public class AmbientBacklightSettings implements Parcelable { /** * The color format is RGB888. + * @hide */ public static final int COLOR_FORMAT_RGB888 = 1; @@ -76,7 +82,7 @@ public class AmbientBacklightSettings implements Parcelable { public static final int ALGORITHM_NONE = 0; /** - * The compress algorithm is RLE. + * The compress algorithm is run length encoding (RLE). */ public static final int ALGORITHM_RLE = 1; @@ -115,6 +121,9 @@ public class AmbientBacklightSettings implements Parcelable { */ private final int mThreshold; + /** + * Constructs AmbientBacklightSettings. + */ public AmbientBacklightSettings(int source, int maxFps, int colorFormat, int horizontalZonesNumber, int verticalZonesNumber, boolean isLetterboxOmitted, int threshold) { @@ -137,32 +146,57 @@ public class AmbientBacklightSettings implements Parcelable { mThreshold = in.readInt(); } + /** + * Gets source of ambient backlight detection. + */ @Source public int getSource() { return mSource; } + /** + * Gets max frames per second. + */ + @IntRange(from = 1) public int getMaxFps() { return mMaxFps; } - @ColorFormat + /** + * Gets color format. + */ + @PixelFormat.Format public int getColorFormat() { return mColorFormat; } + /** + * Gets the number of lights in each horizontal zone. + */ + @IntRange(from = 0) public int getHorizontalZonesNumber() { return mHorizontalZonesNumber; } + /** + * Gets the number of lights in each vertical zone. + */ + @IntRange(from = 0) public int getVerticalZonesNumber() { return mVerticalZonesNumber; } + /** + * Returns {@code true} if letter box is omitted; {@code false} otherwise. + * @hide + */ public boolean isLetterboxOmitted() { return mIsLetterboxOmitted; } + /** + * @hide + */ public int getThreshold() { return mThreshold; } diff --git a/media/java/android/media/quality/MediaQualityContract.java b/media/java/android/media/quality/MediaQualityContract.java index 472d7985b304..f07ef873a0af 100644 --- a/media/java/android/media/quality/MediaQualityContract.java +++ b/media/java/android/media/quality/MediaQualityContract.java @@ -33,6 +33,7 @@ public class MediaQualityContract { */ public interface BaseParameters { String PARAMETER_ID = "_id"; + String PARAMETER_TYPE = "_type"; String PARAMETER_NAME = "_name"; String PARAMETER_PACKAGE = "_package"; String PARAMETER_INPUT_ID = "_input_id"; @@ -43,7 +44,7 @@ public class MediaQualityContract { * Parameters picture quality. * @hide */ - public static final class PictureQuality { + public static final class PictureQuality implements BaseParameters { /** * The brightness. * diff --git a/media/java/android/media/quality/MediaQualityManager.java b/media/java/android/media/quality/MediaQualityManager.java index 26d83aca3e7b..4d4526cf9925 100644 --- a/media/java/android/media/quality/MediaQualityManager.java +++ b/media/java/android/media/quality/MediaQualityManager.java @@ -567,7 +567,6 @@ public final class MediaQualityManager { /** * Registers a {@link AmbientBacklightCallback}. - * @hide */ public void registerAmbientBacklightCallback( @NonNull @CallbackExecutor Executor executor, @@ -581,7 +580,6 @@ public final class MediaQualityManager { /** * Unregisters the existing {@link AmbientBacklightCallback}. - * @hide */ public void unregisterAmbientBacklightCallback( @NonNull final AmbientBacklightCallback callback) { @@ -602,7 +600,6 @@ public final class MediaQualityManager { * Set the ambient backlight settings. * * @param settings The settings to use for the backlight detector. - * @hide */ public void setAmbientBacklightSettings( @NonNull AmbientBacklightSettings settings) { @@ -618,7 +615,6 @@ public final class MediaQualityManager { * Enables or disables the ambient backlight detection. * * @param enabled {@code true} to enable, {@code false} to disable. - * @hide */ public void setAmbientBacklightEnabled(boolean enabled) { try { @@ -843,14 +839,12 @@ public final class MediaQualityManager { /** * Callback used to monitor status of ambient backlight. - * @hide */ public abstract static class AmbientBacklightCallback { /** * Called when new ambient backlight event is emitted. - * @hide */ - public void onAmbientBacklightEvent(AmbientBacklightEvent event) { + public void onAmbientBacklightEvent(@NonNull AmbientBacklightEvent event) { } } } diff --git a/media/java/android/media/tv/TvInputServiceExtensionManager.java b/media/java/android/media/tv/TvInputServiceExtensionManager.java index c514f6ed04ef..9442726508c6 100644 --- a/media/java/android/media/tv/TvInputServiceExtensionManager.java +++ b/media/java/android/media/tv/TvInputServiceExtensionManager.java @@ -20,7 +20,9 @@ import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.StringDef; +import android.annotation.SystemApi; import android.media.tv.flags.Flags; import android.os.IBinder; import android.os.RemoteException; @@ -43,6 +45,7 @@ import java.util.Set; * * @hide */ +@SystemApi @FlaggedApi(Flags.FLAG_TIF_EXTENSION_STANDARDIZATION) public final class TvInputServiceExtensionManager { private static final String TAG = "TvInputServiceExtensionManager"; @@ -186,8 +189,7 @@ public final class TvInputServiceExtensionManager { @Retention(RetentionPolicy.SOURCE) public @interface StandardizedExtensionName {} /** - * Interface responsible for creating scan session and obtain parameters. - * @hide + * Interface responsible for creating scan session and obtaining related parameters. */ public static final String ISCAN_INTERFACE = SCAN_PACKAGE + "IScanInterface"; /** @@ -286,12 +288,10 @@ public final class TvInputServiceExtensionManager { public static final String ISCAN_SAT_SEARCH = SCAN_PACKAGE + "IScanSatSearch"; /** * Interface for Over-the-Air Download. - * @hide */ public static final String IOAD_UPDATE_INTERFACE = OAD_PACKAGE + "IOadUpdateInterface"; /** * Interface for handling conditional access module app related information. - * @hide */ public static final String ICAM_APP_INFO_SERVICE = CAM_PACKAGE + "ICamAppInfoService"; /** @@ -406,8 +406,7 @@ public final class TvInputServiceExtensionManager { public static final String IDOWNLOADABLE_RATING_TABLE_MONITOR = RATING_PACKAGE + "IDownloadableRatingTableMonitor"; /** - * Interface for handling RRT rating related information. - * @hide + * Interface for handling Region Rating Table rating system related information. */ public static final String IRATING_INTERFACE = RATING_PACKAGE + "IRatingInterface"; /** @@ -442,12 +441,10 @@ public final class TvInputServiceExtensionManager { public static final String IPROGRAM_INFO_LISTENER = RATING_PACKAGE + "IProgramInfoListener"; /** * Interface for getting broadcast time related information. - * @hide */ public static final String IBROADCAST_TIME = TIME_PACKAGE + "BroadcastTime"; /** * Interface for handling data service signal information on teletext. - * @hide */ public static final String IDATA_SERVICE_SIGNAL_INFO = TELETEXT_PACKAGE + "IDataServiceSignalInfo"; @@ -476,17 +473,14 @@ public final class TvInputServiceExtensionManager { + "IScanBackgroundServiceUpdateListener"; /** * Interface for generating client token. - * @hide */ public static final String ICLIENT_TOKEN = CLIENT_TOKEN_PACKAGE + "IClientToken"; /** * Interfaces for handling screen mode information. - * @hide */ public static final String ISCREEN_MODE_SETTINGS = SCREEN_MODE_PACKAGE + "IScreenModeSettings"; /** * Interfaces for handling HDMI signal information update. - * @hide */ public static final String IHDMI_SIGNAL_INTERFACE = SIGNAL_PACKAGE + "IHdmiSignalInterface"; /** @@ -529,7 +523,6 @@ public final class TvInputServiceExtensionManager { public static final String ISERVICE_LIST_EDIT = SERVICE_DATABASE_PACKAGE + "IServiceListEdit"; /** * Interfaces for changes on service database updates. - * @hide */ public static final String ISERVICE_LIST_EDIT_LISTENER = SERVICE_DATABASE_PACKAGE + "IServiceListEditListener"; @@ -587,8 +580,7 @@ public final class TvInputServiceExtensionManager { public static final String ICHANNEL_LIST_TRANSFER = SERVICE_DATABASE_PACKAGE + "IChannelListTransfer"; /** - * Interfaces for record contents updates. - * @hide + * Interface for operations related to recorded contents. */ public static final String IRECORDED_CONTENTS = PVR_PACKAGE + "IRecordedContents"; /** @@ -605,7 +597,6 @@ public final class TvInputServiceExtensionManager { + "IGetInfoRecordedContentsCallback"; /** * Interfaces for monitoring present event information. - * @hide */ public static final String IEVENT_MONITOR = EVENT_PACKAGE + "IEventMonitor"; /** @@ -784,20 +775,22 @@ public final class TvInputServiceExtensionManager { } /** - * This function should be used by OEM to register IBinder objects that implement - * standardized AIDL interfaces. + * Registers IBinder objects that implement standardized AIDL interfaces. + * <p>This function should be used by SoCs/OEMs * * @param extensionName Extension Interface Name * @param binder IBinder object to be registered - * @return REGISTER_SUCCESS on success of registering IBinder object - * REGISTER_FAIL_NAME_NOT_STANDARDIZED on failure due to registering extension with - * non-standardized name - * REGISTER_FAIL_IMPLEMENTATION_NOT_STANDARDIZED on failure due to IBinder not + * @return {@link #REGISTER_SUCCESS} on success of registering IBinder object + * {@link #REGISTER_FAIL_NAME_NOT_STANDARDIZED} on failure due to registering extension + * with non-standardized name + * {@link #REGISTER_FAIL_IMPLEMENTATION_NOT_STANDARDIZED} on failure due to IBinder not * implementing standardized AIDL interface - * REGISTER_FAIL_REMOTE_EXCEPTION on failure due to remote exception + * {@link #REGISTER_FAIL_REMOTE_EXCEPTION} on failure due to remote exception * * @hide */ + @SystemApi + @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE) @RegisterResult public int registerExtensionIBinder(@StandardizedExtensionName @NonNull String extensionName, @NonNull IBinder binder) { diff --git a/media/java/android/media/tv/flags/media_tv.aconfig b/media/java/android/media/tv/flags/media_tv.aconfig index 4de68634af5e..3dd6a95043ce 100644 --- a/media/java/android/media/tv/flags/media_tv.aconfig +++ b/media/java/android/media/tv/flags/media_tv.aconfig @@ -77,6 +77,22 @@ flag { name: "set_resource_holder_retain" is_exported: true namespace: "media_tv" - description : "Feature flag to add setResourceHolderRetain api to MediaCas and Tuner JAVA." + description: "Feature flag to add setResourceHolderRetain api to MediaCas and Tuner JAVA." bug: "372973197" } + +flag { + name: "mediacas_update_client_profile_priority" + is_exported: true + namespace: "media_tv" + description: "Feature flag to add updateResourcePriority api to MediaCas" + bug: "372971241" +} + +flag { + name: "apply_picture_profiles" + is_exported: true + namespace: "media_tv" + description : "Feature flag to enable APIs for applying picture profiles" + bug: "337330263" +} diff --git a/media/jni/Android.bp b/media/jni/Android.bp index c44e26f17b5e..f09dc7218d7d 100644 --- a/media/jni/Android.bp +++ b/media/jni/Android.bp @@ -104,6 +104,7 @@ cc_library_shared { "libgrallocusage", "libmedia_midiiowrapper", "android.companion.virtualdevice.flags-aconfig-cc", + "android.media.codec-aconfig-cc", "android.media.playback.flags-aconfig-cc", ], diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index 001653b08f0c..fc184fe5c872 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -39,6 +39,8 @@ #include <C2Buffer.h> #include <C2PlatformSupport.h> +#include <android_media_codec.h> + #include <android/hardware/cas/native/1.0/IDescrambler.h> #include <android_runtime/android_hardware_HardwareBuffer.h> @@ -189,6 +191,22 @@ static struct { jmethodID setId; } gBufferInfo; +static struct { + jclass clazz; + jmethodID ctorId; + jfieldID resourceId; + jfieldID capacityId; + jfieldID availableId; +} gGlobalResourceInfo; + +static struct { + jclass clazz; + jmethodID ctorId; + jfieldID resourceId; + jfieldID staticCountId; + jfieldID perFrameCountId; +} gInstanceResourceInfo; + struct fields_t { jmethodID postEventFromNativeID; jmethodID lockAndGetContextID; @@ -1129,6 +1147,37 @@ status_t JMediaCodec::unsubscribeFromVendorParameters(JNIEnv *env, jobject names return mCodec->unsubscribeFromVendorParameters(names); } +static jobject getJavaResources( + JNIEnv *env, + const std::vector<MediaCodec::InstanceResourceInfo>& resources) { + jobject resourcesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId); + for (const MediaCodec::InstanceResourceInfo& res : resources) { + ScopedLocalRef<jobject> object{env, env->NewObject( + gInstanceResourceInfo.clazz, gInstanceResourceInfo.ctorId)}; + ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(res.mName.c_str())}; + env->SetObjectField(object.get(), gInstanceResourceInfo.resourceId, nameStr.get()); + env->SetLongField(object.get(), + gInstanceResourceInfo.staticCountId, + (jlong)res.mStaticCount); + env->SetLongField(object.get(), + gInstanceResourceInfo.perFrameCountId, + (jlong)res.mPerFrameCount); + (void)env->CallBooleanMethod(resourcesObj, gArrayListInfo.addId, object.get()); + } + + return resourcesObj; +} + +status_t JMediaCodec::getRequiredResources(JNIEnv *env, jobject *resourcesObj) { + std::vector<MediaCodec::InstanceResourceInfo> resources; + status_t status = mCodec->getRequiredResources(resources); + if (status != OK) { + return status; + } + *resourcesObj = getJavaResources(env, resources); + return OK; +} + static jthrowable createCodecException( JNIEnv *env, status_t err, int32_t actionCode, const char *msg = NULL) { ScopedLocalRef<jclass> clazz( @@ -1475,6 +1524,10 @@ void JMediaCodec::handleCallback(const sp<AMessage> &msg) { obj = MediaMetricsJNI::writeMetricsToBundle(env, item, NULL); break; } + case MediaCodec::CB_REQUIRED_RESOURCES_CHANGED: + { + break; + } default: TRESPASS(); @@ -3560,6 +3613,64 @@ static void android_media_MediaCodec_unsubscribeFromVendorParameters( return; } +static jobject getJavaResources( + JNIEnv *env, + const std::vector<MediaCodec::GlobalResourceInfo>& resources) { + jobject resourcesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId); + for (const MediaCodec::GlobalResourceInfo& res : resources) { + ScopedLocalRef<jobject> object{env, env->NewObject( + gGlobalResourceInfo.clazz, gGlobalResourceInfo.ctorId)}; + ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(res.mName.c_str())}; + env->SetObjectField(object.get(), gInstanceResourceInfo.resourceId, nameStr.get()); + env->SetLongField(object.get(), gGlobalResourceInfo.capacityId, (jlong)res.mCapacity); + env->SetLongField(object.get(), gGlobalResourceInfo.availableId, (jlong)res.mAvailable); + (void)env->CallBooleanMethod(resourcesObj, gArrayListInfo.addId, object.get()); + } + + return resourcesObj; +} + +static jobject android_media_MediaCodec_getGloballyAvailableResources( + JNIEnv *env, jobject thiz) { + (void)thiz; + std::vector<MediaCodec::GlobalResourceInfo> resources; + status_t status = MediaCodec::getGloballyAvailableResources(resources); + if (status != OK) { + if (status == ERROR_UNSUPPORTED) { + jniThrowException(env, "java/lang/UnsupportedOperationException", + "Function Not Implemented"); + } else { + throwExceptionAsNecessary(env, status, nullptr); + } + return nullptr; + } + + return getJavaResources(env, resources); +} + +static jobject android_media_MediaCodec_getRequiredResources( + JNIEnv *env, jobject thiz) { + sp<JMediaCodec> codec = getMediaCodec(env, thiz); + if (codec == nullptr || codec->initCheck() != OK) { + throwExceptionAsNecessary(env, INVALID_OPERATION, codec); + return nullptr; + } + + jobject ret = nullptr; + status_t status = codec->getRequiredResources(env, &ret); + if (status != OK) { + if (status == ERROR_UNSUPPORTED) { + jniThrowException(env, "java/lang/UnsupportedOperationException", + "Function Not Implemented"); + } else { + throwExceptionAsNecessary(env, status, nullptr); + } + return nullptr; + } + + return ret; +} + static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) { ScopedLocalRef<jclass> clazz( env, env->FindClass("android/media/MediaCodec")); @@ -3905,6 +4016,36 @@ static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) { gFields.bufferInfoOffset = env->GetFieldID(clazz.get(), "offset", "I"); gFields.bufferInfoPresentationTimeUs = env->GetFieldID(clazz.get(), "presentationTimeUs", "J"); + + // Since these TestApis are defined under the flag, make sure they are + // accessed only when the flag is set. + if (android::media::codec::codec_availability()) { + clazz.reset(env->FindClass("android/media/MediaCodec$GlobalResourceInfo")); + CHECK(clazz.get() != NULL); + gGlobalResourceInfo.clazz = (jclass)env->NewGlobalRef(clazz.get()); + gGlobalResourceInfo.ctorId = env->GetMethodID(clazz.get(), "<init>", "()V"); + CHECK(gGlobalResourceInfo.ctorId != NULL); + gGlobalResourceInfo.resourceId = + env->GetFieldID(clazz.get(), "mName", "Ljava/lang/String;"); + CHECK(gGlobalResourceInfo.resourceId != NULL); + gGlobalResourceInfo.capacityId = env->GetFieldID(clazz.get(), "mCapacity", "J"); + CHECK(gGlobalResourceInfo.capacityId != NULL); + gGlobalResourceInfo.availableId = env->GetFieldID(clazz.get(), "mAvailable", "J"); + CHECK(gGlobalResourceInfo.availableId != NULL); + + clazz.reset(env->FindClass("android/media/MediaCodec$InstanceResourceInfo")); + CHECK(clazz.get() != NULL); + gInstanceResourceInfo.clazz = (jclass)env->NewGlobalRef(clazz.get()); + gInstanceResourceInfo.ctorId = env->GetMethodID(clazz.get(), "<init>", "()V"); + CHECK(gInstanceResourceInfo.ctorId != NULL); + gInstanceResourceInfo.resourceId = + env->GetFieldID(clazz.get(), "mName", "Ljava/lang/String;"); + CHECK(gInstanceResourceInfo.resourceId != NULL); + gInstanceResourceInfo.staticCountId= env->GetFieldID(clazz.get(), "mStaticCount", "J"); + CHECK(gInstanceResourceInfo.staticCountId != NULL); + gInstanceResourceInfo.perFrameCountId = env->GetFieldID(clazz.get(), "mPerFrameCount", "J"); + CHECK(gInstanceResourceInfo.perFrameCountId != NULL); + } } static void android_media_MediaCodec_native_setup( @@ -4261,6 +4402,12 @@ static const JNINativeMethod gMethods[] = { { "native_finalize", "()V", (void *)android_media_MediaCodec_native_finalize }, + + { "native_getGloballyAvailableResources", "()Ljava/util/List;", + (void *)android_media_MediaCodec_getGloballyAvailableResources}, + + { "native_getRequiredResources", "()Ljava/util/List;", + (void *)android_media_MediaCodec_getRequiredResources}, }; static const JNINativeMethod gLinearBlockMethods[] = { diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h index c9b6b7f6f337..930dbbeb7f30 100644 --- a/media/jni/android_media_MediaCodec.h +++ b/media/jni/android_media_MediaCodec.h @@ -185,6 +185,8 @@ struct JMediaCodec : public AHandler { status_t unsubscribeFromVendorParameters(JNIEnv *env, jobject names); + status_t getRequiredResources(JNIEnv *env, jobject *resourcesObj); + bool hasCryptoOrDescrambler() { return mHasCryptoOrDescrambler; } const sp<ICrypto> &getCrypto() { return mCrypto; } diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp index 9de3a6f525e6..641e8d9a9b48 100644 --- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp +++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp @@ -66,6 +66,18 @@ public: std::optional<hal::ChannelConfig>* _aidl_return), (override)); MOCK_METHOD(ScopedAStatus, closeSessionChannel, (), (override)); + MOCK_METHOD(ScopedAStatus, getCpuHeadroom, + (const ::aidl::android::os::CpuHeadroomParamsInternal& in_params, + std::vector<float>* _aidl_return), + (override)); + MOCK_METHOD(ScopedAStatus, getCpuHeadroomMinIntervalMillis, (int64_t* _aidl_return), + (override)); + MOCK_METHOD(ScopedAStatus, getGpuHeadroom, + (const ::aidl::android::os::GpuHeadroomParamsInternal& in_params, + float* _aidl_return), + (override)); + MOCK_METHOD(ScopedAStatus, getGpuHeadroomMinIntervalMillis, (int64_t* _aidl_return), + (override)); MOCK_METHOD(SpAIBinder, asBinder, (), (override)); MOCK_METHOD(bool, isRemote, (), (override)); }; diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt index a23845fa17e9..c25f77b12116 100644 --- a/nfc/api/system-current.txt +++ b/nfc/api/system-current.txt @@ -107,6 +107,7 @@ package android.nfc { method public void onRfDiscoveryStarted(boolean); method public void onRfFieldActivated(boolean); method public void onRoutingChanged(); + method public void onRoutingTableFull(); method public void onStateUpdated(int); method public void onTagConnected(boolean); method public void onTagDispatch(@NonNull java.util.function.Consumer<java.lang.Boolean>); diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl index b102e873d737..fb793b024288 100644 --- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl +++ b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl @@ -52,5 +52,6 @@ interface INfcOemExtensionCallback { void onNdefMessage(in Tag tag, in NdefMessage message, in ResultReceiver hasOemExecutableContent); void onLaunchHceAppChooserActivity(in String selectedAid, in List<ApduServiceInfo> services, in ComponentName failedComponent, in String category); void onLaunchHceTapAgainActivity(in ApduServiceInfo service, in String category); + void onRoutingTableFull(); void onLogEventNotified(in OemLogItems item); } diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java index abd99bc02f55..57ee981caf9c 100644 --- a/nfc/java/android/nfc/NfcOemExtension.java +++ b/nfc/java/android/nfc/NfcOemExtension.java @@ -394,6 +394,13 @@ public final class NfcOemExtension { void onLaunchHceTapAgainDialog(@NonNull ApduServiceInfo service, @NonNull String category); /** + * Callback to indicate that routing table is full and the OEM can optionally launch a + * dialog to request the user to remove some Card Emulation apps from the device to free + * routing table space. + */ + void onRoutingTableFull(); + + /** * Callback when OEM specified log event are notified. * @param item the log items that contains log information of NFC event. */ @@ -853,6 +860,12 @@ public final class NfcOemExtension { handleVoidCallback(enabled, cb::onReaderOptionChanged, ex)); } + public void onRoutingTableFull() throws RemoteException { + mCallbackMap.forEach((cb, ex) -> + handleVoidCallback(null, + (Object input) -> cb.onRoutingTableFull(), ex)); + } + @Override public void onGetOemAppSearchIntent(List<String> packages, ResultReceiver intentConsumer) throws RemoteException { diff --git a/nfc/java/android/nfc/OemLogItems.java b/nfc/java/android/nfc/OemLogItems.java index 6671941c1cc9..4f3e1999f5d3 100644 --- a/nfc/java/android/nfc/OemLogItems.java +++ b/nfc/java/android/nfc/OemLogItems.java @@ -142,8 +142,11 @@ public final class OemLogItems implements Parcelable { dest.writeByteArray(mCommandApdus);
dest.writeInt(mResponseApdus.length);
dest.writeByteArray(mResponseApdus);
- dest.writeLong(mRfFieldOnTime.getEpochSecond());
- dest.writeInt(mRfFieldOnTime.getNano());
+ dest.writeBoolean(mRfFieldOnTime != null);
+ if (mRfFieldOnTime != null) {
+ dest.writeLong(mRfFieldOnTime.getEpochSecond());
+ dest.writeInt(mRfFieldOnTime.getNano());
+ }
dest.writeParcelable(mTag, 0);
}
@@ -305,7 +308,12 @@ public final class OemLogItems implements Parcelable { in.readByteArray(this.mCommandApdus);
this.mResponseApdus = new byte[in.readInt()];
in.readByteArray(this.mResponseApdus);
- this.mRfFieldOnTime = Instant.ofEpochSecond(in.readLong(), in.readInt());
+ boolean isRfFieldOnTimeSet = in.readBoolean();
+ if (isRfFieldOnTimeSet) {
+ this.mRfFieldOnTime = Instant.ofEpochSecond(in.readLong(), in.readInt());
+ } else {
+ this.mRfFieldOnTime = null;
+ }
this.mTag = in.readParcelable(Tag.class.getClassLoader(), Tag.class);
}
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp index b2dcb7fa4f53..a3da93da31ae 100644 --- a/packages/SettingsLib/Android.bp +++ b/packages/SettingsLib/Android.bp @@ -61,9 +61,11 @@ android_library { "SettingsLibUtils", "SettingsLibZeroStatePreference", "settingslib_media_flags_lib", + ], + libs:[ + // This flag library has been added in frameworks jar "aconfig_settingslib_flags_java_lib", ], - plugins: ["androidx.room_room-compiler-plugin"], use_resource_processor: true, resource_dirs: ["res"], diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v35/themes.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v35/themes.xml index e68253e2200d..fadcf7ba8699 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v35/themes.xml +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-night-v35/themes.xml @@ -18,7 +18,7 @@ <style name="Theme.CollapsingToolbar.Settings" parent="@style/Theme.MaterialComponents.DayNight"> <item name="elevationOverlayEnabled">true</item> <item name="elevationOverlayColor">?attr/colorPrimary</item> - <item name="colorPrimary">@color/settingslib_materialColorInverseOnSurface</item> + <item name="colorPrimary">@color/settingslib_materialColorOnSurfaceInverse</item> <item name="colorAccent">@color/settingslib_materialColorPrimaryFixed</item> </style> </resources>
\ No newline at end of file diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes.xml index f7c9aac68629..7c9d1a47b7ef 100644 --- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes.xml +++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/themes.xml @@ -18,7 +18,7 @@ <style name="Theme.CollapsingToolbar.Settings" parent="@style/Theme.MaterialComponents.DayNight"> <item name="elevationOverlayEnabled">true</item> <item name="elevationOverlayColor">?attr/colorPrimary</item> - <item name="colorPrimary">@color/settingslib_materialColorInverseOnSurface</item> + <item name="colorPrimary">@color/settingslib_materialColorOnSurfaceInverse</item> <item name="colorAccent">@color/settingslib_materialColorPrimary</item> </style> </resources>
\ No newline at end of file diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceHierarchy.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceHierarchy.kt index bde4217b3962..a2b826a50e58 100644 --- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceHierarchy.kt +++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceHierarchy.kt @@ -166,10 +166,6 @@ class PreferenceHierarchy internal constructor(metadata: PreferenceMetadata) : } return null } - - /** Returns all the [PreferenceHierarchyNode]s appear in the hierarchy. */ - fun getAllPreferences(): List<PreferenceHierarchyNode> = - mutableListOf<PreferenceHierarchyNode>().apply { forEachRecursively { add(it) } } } /** diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt index 49acc1d44144..6b7be91c1903 100644 --- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt +++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt @@ -108,6 +108,9 @@ interface PreferenceBinding { } } +/** Interface indicates that a virtual [Preference] should be created for binding. */ +interface PreferenceBindingPlaceholder + /** Abstract preference screen to provide preference hierarchy and binding factory. */ interface PreferenceScreenCreator : PreferenceScreenMetadata, PreferenceScreenProvider { diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt index fbe892710d40..cfe6089169d3 100644 --- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt +++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt @@ -218,34 +218,47 @@ class PreferenceScreenBindingHelper( preferenceScreen: PreferenceScreen, preferenceBindingFactory: PreferenceBindingFactory, preferenceHierarchy: PreferenceHierarchy, - ) = - preferenceScreen.bindRecursively( - preferenceBindingFactory, - preferenceHierarchy.getAllPreferences().associateBy { it.metadata.key }, - ) - - private fun PreferenceGroup.bindRecursively( - preferenceBindingFactory: PreferenceBindingFactory, - preferences: Map<String, PreferenceHierarchyNode>, - storages: MutableMap<KeyValueStore, PreferenceDataStore> = mutableMapOf(), ) { - preferences[key]?.let { preferenceBindingFactory.bind(this, it) } - val count = preferenceCount - for (index in 0 until count) { - val preference = getPreference(index) - if (preference is PreferenceGroup) { - preference.bindRecursively(preferenceBindingFactory, preferences, storages) - } else { - preferences[preference.key]?.let { - val metadata = it.metadata - (metadata as? PersistentPreference<*>)?.storage(context)?.let { storage -> - preference.preferenceDataStore = - storages.getOrPut(storage) { PreferenceDataStoreAdapter(storage) } + val preferences = mutableMapOf<String, PreferenceHierarchyNode>() + preferenceHierarchy.forEachRecursively { + val metadata = it.metadata + preferences[metadata.key] = it + } + val storages = mutableMapOf<KeyValueStore, PreferenceDataStore>() + + fun Preference.setPreferenceDataStore(metadata: PreferenceMetadata) { + (metadata as? PersistentPreference<*>)?.storage(context)?.let { storage -> + preferenceDataStore = + storages.getOrPut(storage) { PreferenceDataStoreAdapter(storage) } + } + } + + fun PreferenceGroup.bindRecursively() { + preferences.remove(key)?.let { preferenceBindingFactory.bind(this, it) } + val count = preferenceCount + for (index in 0 until count) { + val preference = getPreference(index) + if (preference is PreferenceGroup) { + preference.bindRecursively() + } else { + preferences.remove(preference.key)?.let { + preference.setPreferenceDataStore(it.metadata) + preferenceBindingFactory.bind(preference, it) } - preferenceBindingFactory.bind(preference, it) } } } + + preferenceScreen.bindRecursively() + for (node in preferences.values) { + val metadata = node.metadata + val binding = preferenceBindingFactory.getPreferenceBinding(metadata) + if (binding !is PreferenceBindingPlaceholder) continue + val preference = binding.createWidget(preferenceScreen.context) + preference.setPreferenceDataStore(metadata) + preferenceBindingFactory.bind(preference, node, binding) + preferenceScreen.addPreference(preference) + } } } } diff --git a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_surface_light.xml b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_surface_light.xml index 8b574aa95176..b46181e20eaa 100644 --- a/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_surface_light.xml +++ b/packages/SettingsLib/SettingsTheme/res/color-v31/settingslib_surface_light.xml @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. --> -<!--Deprecated. After sdk 35, don't use it, using materialColorInverseOnSurface in light theme --> +<!--Deprecated. After sdk 35, don't use it, using materialColorOnSurfaceInverse in light theme --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@android:color/system_neutral1_500" android:lStar="98" /> </selector>
\ No newline at end of file diff --git a/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml index 46ec62e7a5ef..313748d8f091 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml @@ -51,7 +51,7 @@ <color name="settingslib_text_color_preference_category_title">@android:color/system_accent1_100</color> - <!--Deprecated. After sdk 35, don't use it, using materialColorInverseOnSurface in dark theme --> + <!--Deprecated. After sdk 35, don't use it, using materialColorOnSurfaceInverse in dark theme --> <color name="settingslib_surface_dark">@android:color/system_neutral1_800</color> <!--Deprecated. After sdk 35, don't use it--> diff --git a/packages/SettingsLib/SettingsTheme/res/values-night-v35/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-night-v35/colors.xml index 84a3ed68af01..94ff02d898db 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-night-v35/colors.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-night-v35/colors.xml @@ -53,11 +53,11 @@ <color name="settingslib_materialColorSurfaceContainerLow">@android:color/system_surface_container_low_dark</color> <color name="settingslib_materialColorOnPrimaryContainer">@android:color/system_on_primary_container_dark</color> <color name="settingslib_materialColorOnErrorContainer">@android:color/system_on_error_container_dark</color> - <color name="settingslib_materialColorInverseOnSurface">@android:color/system_on_surface_light</color> + <color name="settingslib_materialColorOnSurfaceInverse">@android:color/system_on_surface_light</color> <color name="settingslib_materialColorSecondaryContainer">@android:color/system_secondary_container_dark</color> <color name="settingslib_materialColorErrorContainer">@android:color/system_error_container_dark</color> - <color name="settingslib_materialColorInversePrimary">@android:color/system_primary_light</color> - <color name="settingslib_materialColorInverseSurface">@android:color/system_surface_light</color> + <color name="settingslib_materialColorPrimaryInverse">@android:color/system_primary_light</color> + <color name="settingslib_materialColorSurfaceInverse">@android:color/system_surface_light</color> <color name="settingslib_materialColorSurfaceVariant">@android:color/system_surface_variant_dark</color> <color name="settingslib_materialColorTertiaryContainer">@android:color/system_tertiary_container_dark</color> <color name="settingslib_materialColorPrimaryContainer">@android:color/system_primary_container_dark</color> diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml index fef92b792bec..b99ee5123491 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml @@ -67,9 +67,9 @@ <color name="settingslib_accent_primary_variant">@android:color/system_accent1_600</color> <!--Deprecated. After sdk 35 don't use it.--> <color name="settingslib_accent_secondary_device_default">@android:color/system_accent2_100</color> - <!--Deprecated. After sdk 35 don't use it.using materialColorInverseOnSurface in dark theme--> + <!--Deprecated. After sdk 35 don't use it.using materialColorOnSurfaceInverse in dark theme--> <color name="settingslib_background_device_default_dark">@android:color/system_neutral1_900</color> - <!--Deprecated. After sdk 35 don't use it. using materialColorInverseOnSurface in light theme--> + <!--Deprecated. After sdk 35 don't use it. using materialColorOnSurfaceInverse in light theme--> <color name="settingslib_background_device_default_light">@android:color/system_neutral1_50</color> <!--Deprecated. After sdk 35 don't use it. using materialColorOnSurface--> <color name="settingslib_text_color_primary_device_default">@android:color/system_neutral1_900</color> diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-v35/colors.xml index 90c19e1aa676..8b9501608000 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-v35/colors.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-v35/colors.xml @@ -66,16 +66,16 @@ <color name="settingslib_materialColorSecondaryFixedDim">@android:color/system_secondary_fixed_dim</color> <color name="settingslib_materialColorOnErrorContainer">@android:color/system_on_error_container_light</color> <color name="settingslib_materialColorOnSecondaryFixed">@android:color/system_on_secondary_fixed</color> - <color name="settingslib_materialColorInverseOnSurface">@android:color/system_on_surface_dark</color> + <color name="settingslib_materialColorOnSurfaceInverse">@android:color/system_on_surface_dark</color> <color name="settingslib_materialColorTertiaryFixedDim">@android:color/system_tertiary_fixed_dim</color> <color name="settingslib_materialColorOnTertiaryFixed">@android:color/system_on_tertiary_fixed</color> <color name="settingslib_materialColorPrimaryFixedDim">@android:color/system_primary_fixed_dim</color> <color name="settingslib_materialColorSecondaryContainer">@android:color/system_secondary_container_light</color> <color name="settingslib_materialColorErrorContainer">@android:color/system_error_container_light</color> <color name="settingslib_materialColorOnPrimaryFixed">@android:color/system_on_primary_fixed</color> - <color name="settingslib_materialColorInversePrimary">@android:color/system_primary_dark</color> + <color name="settingslib_materialColorPrimaryInverse">@android:color/system_primary_dark</color> <color name="settingslib_materialColorSecondaryFixed">@android:color/system_secondary_fixed</color> - <color name="settingslib_materialColorInverseSurface">@android:color/system_surface_dark</color> + <color name="settingslib_materialColorSurfaceInverse">@android:color/system_surface_dark</color> <color name="settingslib_materialColorSurfaceVariant">@android:color/system_surface_variant_light</color> <color name="settingslib_materialColorTertiaryContainer">@android:color/system_tertiary_container_light</color> <color name="settingslib_materialColorTertiaryFixed">@android:color/system_tertiary_fixed</color> diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/CategoryPageProvider.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/CategoryPageProvider.kt index 4d3a78a583fc..f2bc380a93de 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/CategoryPageProvider.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/CategoryPageProvider.kt @@ -17,8 +17,12 @@ package com.android.settingslib.spa.gallery.ui import android.os.Bundle +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.height import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import com.android.settingslib.spa.framework.common.SettingsEntry import com.android.settingslib.spa.framework.common.SettingsEntryBuilder import com.android.settingslib.spa.framework.common.SettingsPageProvider @@ -30,6 +34,7 @@ import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.preference.SimplePreferenceMacro import com.android.settingslib.spa.widget.scaffold.RegularScaffold import com.android.settingslib.spa.widget.ui.Category +import com.android.settingslib.spa.widget.ui.LazyCategory private const val TITLE = "Sample Category" @@ -65,7 +70,7 @@ object CategoryPageProvider : SettingsPageProvider { ) entryList.add( SettingsEntryBuilder.create("Preference 3", owner) - .setMacro { SimplePreferenceMacro(title = "Preference 2", summary = "Summary 3") } + .setMacro { SimplePreferenceMacro(title = "Preference 3", summary = "Summary 3") } .build() ) entryList.add( @@ -88,6 +93,13 @@ object CategoryPageProvider : SettingsPageProvider { entries[2].UiLayout() entries[3].UiLayout() } + Column(Modifier.height(200.dp)) { + LazyCategory( + list = entries, + entry = { index: Int -> @Composable { entries[index].UiLayout() } }, + title = { index: Int -> if (index == 0 || index == 2) "LazyCategory" else null }, + ) {} + } } } } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt index 66680fa547b1..28b2b4ab1662 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt @@ -19,8 +19,13 @@ package com.android.settingslib.spa.widget.ui import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.TouchApp import androidx.compose.material3.MaterialTheme @@ -34,6 +39,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.android.settingslib.spa.framework.theme.SettingsDimension import com.android.settingslib.spa.framework.theme.SettingsShape @@ -98,6 +104,57 @@ fun Category(title: String? = null, content: @Composable ColumnScope.() -> Unit) } } +/** + * A container that is used to group items with lazy loading. + * + * @param list The list of items to display. + * @param entry The entry for each list item according to its index in list. + * @param key Optional. The key for each item in list to provide unique item identifiers, making + * the list more efficient. + * @param title Optional. Category title for each item or each group of items in the list. It + * should be decided by the index. + * @param bottomPadding Optional. Bottom outside padding of the category. + * @param state Optional. State of LazyList. + * @param content Optional. Content to be shown at the top of the category. + */ + +@Composable +fun LazyCategory( + list: List<Any>, + entry: (Int) -> @Composable () -> Unit, + key: ((Int) -> Any)? = null, + title: ((Int) -> String?)? = null, + bottomPadding: Dp = SettingsDimension.paddingSmall, + state: LazyListState = rememberLazyListState(), + content: @Composable () -> Unit, +) { + Column( + Modifier.padding( + PaddingValues( + start = SettingsDimension.paddingLarge, + end = SettingsDimension.paddingLarge, + top = SettingsDimension.paddingSmall, + bottom = bottomPadding, + ) + ) + .clip(SettingsShape.CornerMedium2) + ) { + LazyColumn( + modifier = Modifier.fillMaxSize(), + verticalArrangement = Arrangement.spacedBy(SettingsDimension.paddingTiny), + state = state, + ) { + item { content() } + + items(count = list.size, key = key) { + title?.invoke(it)?.let { title -> CategoryTitle(title) } + val entryPreference = entry(it) + entryPreference() + } + } + } +} + @Preview @Composable private fun CategoryPreview() { diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/CategoryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/CategoryTest.kt index 09a6e6ddc7f0..4b4a8c20b39e 100644 --- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/CategoryTest.kt +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/CategoryTest.kt @@ -16,10 +16,16 @@ package com.android.settingslib.spa.widget.ui +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.height +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.unit.dp import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.PreferenceModel @@ -30,14 +36,11 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class CategoryTest { - @get:Rule - val composeTestRule = createComposeRule() + @get:Rule val composeTestRule = createComposeRule() @Test fun categoryTitle() { - composeTestRule.setContent { - CategoryTitle(title = "CategoryTitle") - } + composeTestRule.setContent { CategoryTitle(title = "CategoryTitle") } composeTestRule.onNodeWithText("CategoryTitle").assertIsDisplayed() } @@ -46,12 +49,14 @@ class CategoryTest { fun category_hasContent_titleDisplayed() { composeTestRule.setContent { Category(title = "CategoryTitle") { - Preference(remember { - object : PreferenceModel { - override val title = "Some Preference" - override val summary = { "Some summary" } + Preference( + remember { + object : PreferenceModel { + override val title = "Some Preference" + override val summary = { "Some summary" } + } } - }) + ) } } @@ -60,10 +65,45 @@ class CategoryTest { @Test fun category_noContent_titleNotDisplayed() { - composeTestRule.setContent { - Category(title = "CategoryTitle") {} - } + composeTestRule.setContent { Category(title = "CategoryTitle") {} } composeTestRule.onNodeWithText("CategoryTitle").assertDoesNotExist() } + + @Test + fun lazyCategory_content_displayed() { + composeTestRule.setContent { TestLazyCategory() } + + composeTestRule.onNodeWithText("text").assertExists() + } + + @Test + fun lazyCategory_title_displayed() { + composeTestRule.setContent { TestLazyCategory() } + + composeTestRule.onNodeWithText("LazyCategory 0").assertExists() + composeTestRule.onNodeWithText("LazyCategory 1").assertDoesNotExist() + } +} + +@Composable +private fun TestLazyCategory() { + val list: List<PreferenceModel> = + listOf( + object : PreferenceModel { + override val title = "title" + }, + object : PreferenceModel { + override val title = "title" + }, + ) + Column(Modifier.height(200.dp)) { + LazyCategory( + list = list, + entry = { index: Int -> @Composable { Preference(list[index]) } }, + title = { index: Int -> if (index == 0) "LazyCategory $index" else null }, + ) { + Text("text") + } + } } diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt index bededf03a0f4..2a214b6f74a6 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt @@ -37,7 +37,9 @@ import com.android.settingslib.spa.framework.compose.LifecycleEffect import com.android.settingslib.spa.framework.compose.LogCompositions import com.android.settingslib.spa.framework.compose.TimeMeasurer.Companion.rememberTimeMeasurer import com.android.settingslib.spa.framework.compose.rememberLazyListStateAndHideKeyboardWhenStartScroll +import com.android.settingslib.spa.framework.theme.isSpaExpressiveEnabled import com.android.settingslib.spa.widget.ui.CategoryTitle +import com.android.settingslib.spa.widget.ui.LazyCategory import com.android.settingslib.spa.widget.ui.PlaceholderTitle import com.android.settingslib.spa.widget.ui.Spinner import com.android.settingslib.spa.widget.ui.SpinnerOption @@ -55,19 +57,14 @@ import kotlinx.coroutines.flow.MutableStateFlow private const val TAG = "AppList" private const val CONTENT_TYPE_HEADER = "header" -/** - * The config used to load the App List. - */ +/** The config used to load the App List. */ data class AppListConfig( val userIds: List<Int>, val showInstantApps: Boolean, val matchAnyUserForAdmin: Boolean, ) -data class AppListState( - val showSystem: () -> Boolean, - val searchQuery: () -> String, -) +data class AppListState(val showSystem: () -> Boolean, val searchQuery: () -> String) data class AppListInput<T : AppRecord>( val config: AppListConfig, @@ -90,7 +87,7 @@ fun <T : AppRecord> AppListInput<T>.AppList() { @Composable internal fun <T : AppRecord> AppListInput<T>.AppListImpl( - viewModelSupplier: @Composable () -> IAppListViewModel<T>, + viewModelSupplier: @Composable () -> IAppListViewModel<T> ) { LogCompositions(TAG, config.userIds.toString()) val viewModel = viewModelSupplier() @@ -125,7 +122,7 @@ private fun <T : AppRecord> AppListModel<T>.AppListWidget( appListData: State<AppListData<T>?>, header: @Composable () -> Unit, bottomPadding: Dp, - noItemMessage: String? + noItemMessage: String?, ) { val timeMeasurer = rememberTimeMeasurer(TAG) appListData.value?.let { (list, option) -> @@ -135,40 +132,61 @@ private fun <T : AppRecord> AppListModel<T>.AppListWidget( PlaceholderTitle(noItemMessage ?: stringResource(R.string.no_applications)) return } - LazyColumn( - modifier = Modifier.fillMaxSize(), - state = rememberLazyListStateAndHideKeyboardWhenStartScroll(), - contentPadding = PaddingValues(bottom = bottomPadding), - ) { - item(contentType = CONTENT_TYPE_HEADER) { + if (isSpaExpressiveEnabled) { + LazyCategory( + list = list, + entry = { index: Int -> + @Composable { + val appEntry = list[index] + val summary = getSummary(option, appEntry.record) ?: { "" } + remember(appEntry) { + AppListItemModel(appEntry.record, appEntry.label, summary) + } + .AppItem() + } + }, + key = { index: Int -> list[index].record.itemKey(option) }, + title = { index: Int -> getGroupTitle(option, list[index].record) }, + bottomPadding = bottomPadding, + state = rememberLazyListStateAndHideKeyboardWhenStartScroll(), + ) { header() } - - items(count = list.size, key = { list[it].record.itemKey(option) }) { - remember(list) { getGroupTitleIfFirst(option, list, it) } - ?.let { group -> CategoryTitle(title = group) } - - val appEntry = list[it] - val summary = getSummary(option, appEntry.record) ?: { "" } - remember(appEntry) { - AppListItemModel(appEntry.record, appEntry.label, summary) - }.AppItem() + } else { + LazyColumn( + modifier = Modifier.fillMaxSize(), + state = rememberLazyListStateAndHideKeyboardWhenStartScroll(), + contentPadding = PaddingValues(bottom = bottomPadding), + ) { + item(contentType = CONTENT_TYPE_HEADER) { header() } + + items(count = list.size, key = { list[it].record.itemKey(option) }) { + remember(list) { getGroupTitleIfFirst(option, list, it) } + ?.let { group -> CategoryTitle(title = group) } + + val appEntry = list[it] + val summary = getSummary(option, appEntry.record) ?: { "" } + remember(appEntry) { + AppListItemModel(appEntry.record, appEntry.label, summary) + } + .AppItem() + } } } } } -private fun <T : AppRecord> T.itemKey(option: Int) = - listOf(option, app.packageName, app.userId) +private fun <T : AppRecord> T.itemKey(option: Int) = listOf(option, app.packageName, app.userId) /** Returns group title if this is the first item of the group. */ private fun <T : AppRecord> AppListModel<T>.getGroupTitleIfFirst( option: Int, list: List<AppEntry<T>>, index: Int, -): String? = getGroupTitle(option, list[index].record)?.takeIf { - index == 0 || it != getGroupTitle(option, list[index - 1].record) -} +): String? = + getGroupTitle(option, list[index].record)?.takeIf { + index == 0 || it != getGroupTitle(option, list[index - 1].record) + } @Composable private fun <T : AppRecord> rememberViewModel( @@ -183,16 +201,19 @@ private fun <T : AppRecord> rememberViewModel( viewModel.searchQuery.Sync(state.searchQuery) LifecycleEffect(onStart = { viewModel.reloadApps() }) - val intentFilter = IntentFilter(Intent.ACTION_PACKAGE_ADDED).apply { - addAction(Intent.ACTION_PACKAGE_REMOVED) - addAction(Intent.ACTION_PACKAGE_CHANGED) - addDataScheme("package") - } + val intentFilter = + IntentFilter(Intent.ACTION_PACKAGE_ADDED).apply { + addAction(Intent.ACTION_PACKAGE_REMOVED) + addAction(Intent.ACTION_PACKAGE_CHANGED) + addDataScheme("package") + } for (userId in config.userIds) { DisposableBroadcastReceiverAsUser( intentFilter = intentFilter, userHandle = UserHandle.of(userId), - ) { viewModel.reloadApps() } + ) { + viewModel.reloadApps() + } } return viewModel } diff --git a/packages/SettingsLib/aconfig/settingslib.aconfig b/packages/SettingsLib/aconfig/settingslib.aconfig index a78d3cd7d209..bf419cc46aeb 100644 --- a/packages/SettingsLib/aconfig/settingslib.aconfig +++ b/packages/SettingsLib/aconfig/settingslib.aconfig @@ -101,6 +101,14 @@ flag { } flag { + name: "write_system_preference_permission_enabled" + is_fixed_read_only: true + namespace: "android_settings" + description: "Enable WRITE_SYSTEM_PREFERENCE permission and appop" + bug: "375193223" +} + +flag { name: "asha_profile_access_profile_enabled_true" namespace: "accessibility" description: "Changes the return value of HearingAidProfile.accessProfileEnabled() to true" @@ -156,3 +164,10 @@ flag { description: "Enable the ambient volume control in device details and hearing devices dialog." bug: "357878944" } + +flag { + name: "settings_preference_write_consent_enabled" + namespace: "android_settings" + description: "Enable the user consent prompt before writing sensitive preferences via service" + bug: "378552675" +} diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index c710aa35fa95..f03014ca95e2 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -821,9 +821,9 @@ <!-- Title of checkbox setting that enables the Linux terminal app. [CHAR LIMIT=32] --> <string name="enable_linux_terminal_title">Linux development environment</string> - <!-- Summary of checkbox setting that enables the Linux terminal app. [CHAR LIMIT=64] --> - <string name="enable_linux_terminal_summary">Run Linux terminal on Android</string> - <!-- Disclaimer below the checkbox that disabling the Linux terminal app would clear its data. [CHAR LIMIT=64] --> + <!-- Summary of checkbox setting that enables the Linux terminal app. [CHAR LIMIT=none] --> + <string name="enable_linux_terminal_summary">(Experimental) Run Linux terminal on Android</string> + <!-- Disclaimer below the checkbox that disabling the Linux terminal app would clear its data. [CHAR LIMIT=none] --> <string name="disable_linux_terminal_disclaimer">If you disable, Linux terminal data will be cleared</string> <!-- HDCP checking title, used for debug purposes only. [CHAR LIMIT=25] --> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java index a87b8153b858..216574a5fff9 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java @@ -1,6 +1,7 @@ package com.android.settingslib.bluetooth; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.UNKNOWN_VALUE_PLACEHOLDER; +import static com.android.settingslib.flags.Flags.audioSharingHysteresisModeFix; import static com.android.settingslib.widget.AdaptiveOutlineDrawable.ICON_TYPE_ADVANCED; import android.annotation.SuppressLint; @@ -651,6 +652,13 @@ public class BluetoothUtils { context.getContentResolver())); } + /** Returns if the le audio sharing hysteresis mode fix is available. */ + @WorkerThread + public static boolean isAudioSharingHysteresisModeFixAvailable(@Nullable Context context) { + return (audioSharingHysteresisModeFix() && Flags.enableLeAudioSharing()) + || (context != null && isAudioSharingPreviewEnabled(context.getContentResolver())); + } + /** Returns if the le audio sharing is enabled. */ public static boolean isAudioSharingEnabled() { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); @@ -733,13 +741,15 @@ public class BluetoothUtils { @WorkerThread public static boolean hasConnectedBroadcastSourceForBtDevice( @Nullable BluetoothDevice device, @Nullable LocalBluetoothManager localBtManager) { - if (Flags.audioSharingHysteresisModeFix()) { + if (localBtManager == null) { + Log.d(TAG, "Skip check hasConnectedBroadcastSourceForBtDevice due to arg is null"); + return false; + } + if (isAudioSharingHysteresisModeFixAvailable(localBtManager.getContext())) { return hasActiveLocalBroadcastSourceForBtDevice(device, localBtManager); } LocalBluetoothLeBroadcastAssistant assistant = - localBtManager == null - ? null - : localBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile(); + localBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile(); if (device == null || assistant == null) { Log.d(TAG, "Skip check hasConnectedBroadcastSourceForBtDevice due to arg is null"); return false; diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java index 6a9d5687370e..dc52b4dafd9b 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java @@ -18,6 +18,8 @@ package com.android.settingslib.bluetooth; import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; +import static com.android.settingslib.Utils.isAudioModeOngoingCall; + import static java.util.stream.Collectors.toList; import android.annotation.CallbackExecutor; @@ -54,7 +56,6 @@ import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import com.android.settingslib.R; -import com.android.settingslib.flags.Flags; import com.google.common.collect.ImmutableList; @@ -303,6 +304,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { + ", sourceId = " + sourceId); } + updateFallbackActiveDeviceIfNeeded(); } @Override @@ -390,9 +392,6 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { + ", state = " + state); } - if (BluetoothUtils.isConnected(state)) { - updateFallbackActiveDeviceIfNeeded(); - } } }; @@ -1130,18 +1129,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded for work profile."); return; } - if (mServiceBroadcast == null) { - Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded due to broadcast profile is null"); - return; - } - List<BluetoothLeBroadcastMetadata> sources = mServiceBroadcast.getAllBroadcastMetadata(); - if (sources.stream() - .noneMatch(source -> mServiceBroadcast.isPlaying(source.getBroadcastId()))) { - Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded due to no broadcast ongoing"); - return; - } - if (mServiceBroadcastAssistant == null) { - Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded due to assistant profile is null"); + if (isAudioModeOngoingCall(mContext)) { + Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded due to ongoing call"); return; } Map<Integer, List<BluetoothDevice>> deviceGroupsInBroadcast = getDeviceGroupsInBroadcast(); @@ -1152,7 +1141,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { int targetGroupId = BluetoothCsipSetCoordinator.GROUP_ID_INVALID; int fallbackActiveGroupId = BluetoothUtils.getPrimaryGroupIdForBroadcast( mContext.getContentResolver()); - if (Flags.audioSharingHysteresisModeFix()) { + if (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext)) { int userPreferredPrimaryGroupId = getUserPreferredPrimaryGroupId(); if (userPreferredPrimaryGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID && deviceGroupsInBroadcast.containsKey(userPreferredPrimaryGroupId)) { @@ -1193,7 +1182,8 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile { @NonNull private Map<Integer, List<BluetoothDevice>> getDeviceGroupsInBroadcast() { - boolean hysteresisModeFixEnabled = Flags.audioSharingHysteresisModeFix(); + boolean hysteresisModeFixEnabled = + BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext); List<BluetoothDevice> connectedDevices = mServiceBroadcastAssistant.getConnectedDevices(); return connectedDevices.stream() .filter( diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistantCallbackExt.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistantCallbackExt.kt index 91a99aed6db5..a0a6d2698d8c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistantCallbackExt.kt +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistantCallbackExt.kt @@ -35,11 +35,7 @@ val LocalBluetoothLeBroadcastAssistant.onSourceConnectedOrRemoved: Flow<Unit> sink: BluetoothDevice, sourceId: Int, state: BluetoothLeBroadcastReceiveState - ) { - if (BluetoothUtils.isConnected(state)) { - launch { send(Unit) } - } - } + ) {} override fun onSourceRemoved(sink: BluetoothDevice, sourceId: Int, reason: Int) { launch { send(Unit) } @@ -55,7 +51,9 @@ val LocalBluetoothLeBroadcastAssistant.onSourceConnectedOrRemoved: Flow<Unit> override fun onSourceFound(source: BluetoothLeBroadcastMetadata) {} - override fun onSourceAdded(sink: BluetoothDevice, sourceId: Int, reason: Int) {} + override fun onSourceAdded(sink: BluetoothDevice, sourceId: Int, reason: Int) { + launch { send(Unit) } + } override fun onSourceAddFailed( sink: BluetoothDevice, diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java index 3cc111f6e099..34d3bd9846d0 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java +++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java @@ -24,7 +24,6 @@ import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE; import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY; import static android.service.notification.SystemZenRules.getTriggerDescriptionForScheduleEvent; import static android.service.notification.SystemZenRules.getTriggerDescriptionForScheduleTime; -import static android.service.notification.ZenModeConfig.tryParseCountdownConditionId; import static android.service.notification.ZenModeConfig.tryParseEventConditionId; import static android.service.notification.ZenModeConfig.tryParseScheduleConditionId; @@ -225,27 +224,6 @@ public class ZenMode implements Parcelable { } /** - * Returns a "dynamic" trigger description. For some modes (such as manual Do Not Disturb) - * when activated, we know when (and if) the mode is expected to end on its own; this dynamic - * description reflects that. In other cases, returns {@link #getTriggerDescription}. - */ - @Nullable - public String getDynamicDescription(Context context) { - if (isManualDnd() && isActive()) { - long countdownEndTime = tryParseCountdownConditionId(mRule.getConditionId()); - if (countdownEndTime > 0) { - CharSequence formattedTime = ZenModeConfig.getFormattedTime(context, - countdownEndTime, ZenModeConfig.isToday(countdownEndTime), - context.getUserId()); - return context.getString(com.android.internal.R.string.zen_mode_until, - formattedTime); - } - } - - return getTriggerDescription(); - } - - /** * Returns the {@link ZenIcon.Key} corresponding to the icon resource for this mode. This can be * either app-provided (via {@link AutomaticZenRule#setIconResId}, user-chosen (via the icon * picker in Settings), or a default icon based on the mode {@link Kind} and {@link #getType}. diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModeDescriptions.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModeDescriptions.java new file mode 100644 index 000000000000..f5776989917e --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModeDescriptions.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.notification.modes; + +import static android.app.AutomaticZenRule.TYPE_SCHEDULE_TIME; +import static android.service.notification.ZenModeConfig.tryParseCountdownConditionId; + +import android.content.Context; +import android.service.notification.SystemZenRules; +import android.service.notification.ZenModeConfig; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.google.common.base.Strings; + +public final class ZenModeDescriptions { + + private final Context mContext; + + public ZenModeDescriptions(@NonNull Context context) { + mContext = context; + } + + /** + * Returns a version of the mode's trigger description that might be "dynamic". + * + * <p>For some modes (such as manual Do Not Disturb) when activated, we know when (and if) the + * mode is expected to end on its own; this description reflects that. In other cases, + * returns {@link ZenMode#getTriggerDescription}. + */ + @Nullable + public String getTriggerDescription(@NonNull ZenMode mode) { + if (mode.isManualDnd() && mode.isActive()) { + long countdownEndTime = tryParseCountdownConditionId(mode.getRule().getConditionId()); + if (countdownEndTime > 0) { + CharSequence formattedTime = ZenModeConfig.getFormattedTime(mContext, + countdownEndTime, ZenModeConfig.isToday(countdownEndTime), + mContext.getUserId()); + return mContext.getString(com.android.internal.R.string.zen_mode_until, + formattedTime); + } + } + + return Strings.emptyToNull(mode.getTriggerDescription()); + } + + /** + * Returns a version of the {@link ZenMode} trigger description that is suitable for + * accessibility (for example, where abbreviations are expanded to full words). + * + * <p>Returns {@code null} If the standard trigger description (returned by + * {@link #getTriggerDescription}) is sufficient. + */ + @Nullable + public String getTriggerDescriptionForAccessibility(@NonNull ZenMode mode) { + // Only one special case: time-based schedules, where we want to use full day names. + if (mode.isSystemOwned() && mode.getType() == TYPE_SCHEDULE_TIME) { + ZenModeConfig.ScheduleInfo schedule = ZenModeConfig.tryParseScheduleConditionId( + mode.getRule().getConditionId()); + if (schedule != null) { + String fullDaysSummary = SystemZenRules.getDaysOfWeekFull(mContext, schedule); + if (fullDaysSummary != null) { + return fullDaysSummary + ", " + SystemZenRules.getTimeSummary(mContext, + schedule); + } + } + } + + return null; + } +} diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java index 6d481dbe64e9..fa5d54283a17 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java @@ -1256,4 +1256,40 @@ public class BluetoothUtilsTest { assertThat(BluetoothUtils.isAudioSharingUIAvailable(mContext)).isTrue(); } + + @Test + public void isAudioSharingHysteresisModeFixAvailable_mainAndPreviewFlagOff_returnsFalse() { + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); + mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); + mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION); + + assertThat(BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext)).isFalse(); + } + + @Test + public void isAudioSharingHysteresisModeFixAvailable_hysteresisFixFlagOff_returnsFalse() { + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); + mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); + mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION); + + assertThat(BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext)).isFalse(); + } + + @Test + public void isAudioSharingHysteresisModeFixAvailable_previewFlagOn_returnsTrue() { + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); + mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); + mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION); + + assertThat(BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext)).isTrue(); + } + + @Test + public void isAudioSharingHysteresisModeFixAvailable_mainAndPreviewFlagOn_returnsTrue() { + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); + mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); + mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION); + + assertThat(BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext)).isTrue(); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeDescriptionsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeDescriptionsTest.java new file mode 100644 index 000000000000..2b3accdbb906 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeDescriptionsTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.notification.modes; + +import static android.app.AutomaticZenRule.TYPE_SCHEDULE_TIME; +import static android.service.notification.SystemZenRules.PACKAGE_ANDROID; + +import static com.google.common.truth.Truth.assertThat; + +import android.service.notification.ZenModeConfig; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +import java.util.Calendar; + +@RunWith(RobolectricTestRunner.class) +public class ZenModeDescriptionsTest { + + private final ZenModeDescriptions mDescriptions = new ZenModeDescriptions( + RuntimeEnvironment.getApplication()); + + @Test + public void getTriggerDescriptionForAccessibility_scheduleTime_usesFullDays() { + ZenModeConfig.ScheduleInfo scheduleInfo = new ZenModeConfig.ScheduleInfo(); + scheduleInfo.days = new int[] { Calendar.MONDAY }; + scheduleInfo.startHour = 11; + scheduleInfo.endHour = 15; + ZenMode mode = new TestModeBuilder() + .setPackage(PACKAGE_ANDROID) + .setType(TYPE_SCHEDULE_TIME) + .setConditionId(ZenModeConfig.toScheduleConditionId(scheduleInfo)) + .build(); + + assertThat(mDescriptions.getTriggerDescriptionForAccessibility(mode)) + .isEqualTo("Monday, 11:00 AM - 3:00 PM"); + } + + @Test + public void getTriggerDescriptionForAccessibility_otherMode_isNull() { + ZenMode mode = new TestModeBuilder().setTriggerDescription("When December ends").build(); + assertThat(mDescriptions.getTriggerDescriptionForAccessibility(mode)).isNull(); + } +} diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java index fbce6ca07b3e..aca2c4ef2a49 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java @@ -16,6 +16,7 @@ package com.android.providers.settings; +import static android.provider.DeviceConfig.DUMP_ARG_NAMESPACE; import static android.provider.Settings.Config.SYNC_DISABLED_MODE_NONE; import static android.provider.Settings.Config.SYNC_DISABLED_MODE_PERSISTENT; import static android.provider.Settings.Config.SYNC_DISABLED_MODE_UNTIL_REBOOT; @@ -42,6 +43,7 @@ import android.provider.DeviceConfigShellCommandHandler; import android.provider.Settings; import android.provider.Settings.Config.SyncDisabledMode; import android.provider.UpdatableDeviceConfigServiceReadiness; +import android.util.Log; import android.util.Slog; import com.android.internal.util.FastPrintWriter; @@ -55,11 +57,13 @@ import java.io.PrintWriter; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.regex.Pattern; /** * Receives shell commands from the command line related to device config flags, and dispatches them @@ -80,6 +84,7 @@ public final class DeviceConfigService extends Binder { final SettingsProvider mProvider; private static final String TAG = "DeviceConfigService"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); public DeviceConfigService(SettingsProvider provider) { mProvider = provider; @@ -97,14 +102,35 @@ public final class DeviceConfigService extends Binder { } } + // TODO(b/364399200): add unit test @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + String filter = null; if (android.provider.flags.Flags.dumpImprovements()) { - pw.print("SyncDisabledForTests: "); - MyShellCommand.getSyncDisabledForTests(pw, pw); + if (args.length > 0) { + switch (args[0]) { + case DUMP_ARG_NAMESPACE: + if (args.length < 2) { + throw new IllegalArgumentException("argument " + DUMP_ARG_NAMESPACE + + " requires an extra argument"); + } + filter = args[1]; + if (DEBUG) { + Slog.d(TAG, "dump(): setting filter as " + filter); + } + break; + default: + Slog.w(TAG, "dump(): ignoring invalid arguments: " + Arrays.toString(args)); + break; + } + } + if (filter == null) { + pw.print("SyncDisabledForTests: "); + MyShellCommand.getSyncDisabledForTests(pw, pw); - pw.print("UpdatableDeviceConfigServiceReadiness.shouldStartUpdatableService(): "); - pw.println(UpdatableDeviceConfigServiceReadiness.shouldStartUpdatableService()); + pw.print("UpdatableDeviceConfigServiceReadiness.shouldStartUpdatableService(): "); + pw.println(UpdatableDeviceConfigServiceReadiness.shouldStartUpdatableService()); + } pw.println("DeviceConfig provider: "); try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(fd)) { @@ -117,8 +143,16 @@ public final class DeviceConfigService extends Binder { IContentProvider iprovider = mProvider.getIContentProvider(); pw.println("DeviceConfig flags:"); + Pattern lineFilter = filter == null ? null : Pattern.compile("^.*" + filter + ".*\\/.*$"); for (String line : MyShellCommand.listAll(iprovider)) { - pw.println(line); + if (lineFilter == null || lineFilter.matcher(line).matches()) { + pw.println(line); + } + } + + if (filter != null) { + // TODO(b/364399200): use filter to skip instead? + return; } ArrayList<String> missingFiles = new ArrayList<String>(); diff --git a/packages/Shell/OWNERS b/packages/Shell/OWNERS index 8feefa5d892f..d4b5b86223ea 100644 --- a/packages/Shell/OWNERS +++ b/packages/Shell/OWNERS @@ -12,3 +12,4 @@ patb@google.com cbrubaker@google.com omakoto@google.com michaelwr@google.com +ronish@google.com diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java index 7c478ac78a29..7f25b51e35ca 100644 --- a/packages/Shell/src/com/android/shell/BugreportProgressService.java +++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java @@ -153,6 +153,10 @@ public class BugreportProgressService extends Service { static final String INTENT_BUGREPORT_FINISHED = "com.android.internal.intent.action.BUGREPORT_FINISHED"; + // Intent sent to notify external apps that bugreport aborted due to error. + static final String INTENT_BUGREPORT_ABORTED = + "com.android.internal.intent.action.BUGREPORT_ABORTED"; + // Internal intents used on notification actions. static final String INTENT_BUGREPORT_CANCEL = "android.intent.action.BUGREPORT_CANCEL"; static final String INTENT_BUGREPORT_SHARE = "android.intent.action.BUGREPORT_SHARE"; @@ -174,6 +178,8 @@ public class BugreportProgressService extends Service { static final String EXTRA_INFO = "android.intent.extra.INFO"; static final String EXTRA_EXTRA_ATTACHMENT_URIS = "android.intent.extra.EXTRA_ATTACHMENT_URIS"; + static final String EXTRA_ABORTED_ERROR_CODE = + "android.intent.extra.EXTRA_ABORTED_ERROR_CODE"; private static final ThreadFactory sBugreportManagerCallbackThreadFactory = new ThreadFactory() { @@ -404,6 +410,7 @@ public class BugreportProgressService extends Service { @Override public void onError(@BugreportErrorCode int errorCode) { synchronized (mLock) { + sendBugreportAbortedBroadcastLocked(errorCode); stopProgressLocked(mInfo.id); mInfo.deleteEmptyFiles(); } @@ -460,6 +467,13 @@ public class BugreportProgressService extends Service { onBugreportFinished(mInfo); } } + + @GuardedBy("mLock") + private void sendBugreportAbortedBroadcastLocked(@BugreportErrorCode int errorCode) { + final Intent intent = new Intent(INTENT_BUGREPORT_ABORTED); + intent.putExtra(EXTRA_ABORTED_ERROR_CODE, errorCode); + mContext.sendBroadcast(intent, android.Manifest.permission.DUMP); + } } private void sendRemoteBugreportFinishedBroadcast(Context context, diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index bffda8bcae65..dafe38dc5c00 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -90,8 +90,6 @@ filegroup { "tests/src/**/systemui/globalactions/GlobalActionsDialogLiteTest.java", "tests/src/**/systemui/globalactions/GlobalActionsImeTest.java", "tests/src/**/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt", - "tests/src/**/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt", - "tests/src/**/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt", "tests/src/**/systemui/media/dialog/MediaOutputAdapterTest.java", "tests/src/**/systemui/media/dialog/MediaOutputBaseDialogTest.java", "tests/src/**/systemui/media/dialog/MediaOutputBroadcastDialogTest.java", @@ -134,7 +132,6 @@ filegroup { "tests/src/**/systemui/accessibility/floatingmenu/MenuViewLayerTest.java", "tests/src/**/systemui/accessibility/floatingmenu/MenuViewTest.java", "tests/src/**/systemui/classifier/PointerCountClassifierTest.java", - "tests/src/**/systemui/qs/tileimpl/QSIconViewImplTest_311121830.kt", "tests/src/**/systemui/accessibility/floatingmenu/RadiiAnimatorTest.java", "tests/src/**/systemui/screenrecord/RecordingControllerTest.java", "tests/src/**/systemui/screenshot/RequestProcessorTest.kt", @@ -216,8 +213,6 @@ filegroup { "tests/src/**/systemui/statusbar/KeyboardShortcutsTest.java", "tests/src/**/systemui/statusbar/KeyguardIndicationControllerWithCoroutinesTest.kt", "tests/src/**/systemui/statusbar/notification/AssistantFeedbackControllerTest.java", - "tests/src/**/systemui/statusbar/notification/PropertyAnimatorTest.java", - "tests/src/**/systemui/statusbar/notification/collection/NotifCollectionTest.java", "tests/src/**/systemui/statusbar/notification/collection/NotificationEntryTest.java", "tests/src/**/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt", "tests/src/**/systemui/statusbar/notification/collection/ShadeListBuilderTest.java", @@ -233,9 +228,7 @@ filegroup { "tests/src/**/systemui/statusbar/notification/row/NotificationConversationInfoTest.java", "tests/src/**/systemui/statusbar/notification/row/NotificationGutsManagerTest.java", "tests/src/**/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt", - "tests/src/**/systemui/statusbar/notification/row/NotifLayoutInflaterFactoryTest.kt", "tests/src/**/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapperTest.kt", - "tests/src/**/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java", "tests/src/**/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java", "tests/src/**/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt", "tests/src/**/systemui/statusbar/phone/AutoTileManagerTest.java", @@ -250,7 +243,6 @@ filegroup { "tests/src/**/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt", "tests/src/**/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt", "tests/src/**/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt", - "tests/src/**/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt", "tests/src/**/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt", "tests/src/**/systemui/statusbar/policy/CallbackControllerTest.java", "tests/src/**/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java", @@ -263,11 +255,9 @@ filegroup { "tests/src/**/systemui/theme/ThemeOverlayApplierTest.java", "tests/src/**/systemui/touch/TouchInsetManagerTest.java", "tests/src/**/systemui/util/LifecycleFragmentTest.java", - "tests/src/**/systemui/util/TestableAlertDialogTest.kt", "tests/src/**/systemui/util/kotlin/PairwiseFlowTest", "tests/src/**/systemui/util/sensors/AsyncManagerTest.java", "tests/src/**/systemui/util/sensors/ThresholdSensorImplTest.java", - "tests/src/**/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java", "tests/src/**/systemui/volume/VolumeDialogImplTest.java", "tests/src/**/systemui/wallet/controller/QuickAccessWalletControllerTest.java", "tests/src/**/systemui/wallet/ui/WalletScreenControllerTest.java", @@ -288,9 +278,6 @@ filegroup { "tests/src/**/systemui/qs/QSImplTest.java", "tests/src/**/systemui/qs/panels/ui/compose/DragAndDropTest.kt", "tests/src/**/systemui/qs/panels/ui/compose/ResizingTest.kt", - "tests/src/**/systemui/screenshot/ActionExecutorTest.kt", - "tests/src/**/systemui/screenshot/ScreenshotDetectionControllerTest.kt", - "tests/src/**/systemui/screenshot/TakeScreenshotServiceTest.kt", "tests/src/**/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java", "tests/src/**/systemui/accessibility/floatingmenu/PositionTest.java", "tests/src/**/systemui/animation/TransitionAnimatorTest.kt", @@ -303,10 +290,45 @@ filegroup { "tests/src/**/systemui/statusbar/notification/row/BigPictureIconManagerTest.kt", "tests/src/**/systemui/statusbar/policy/RotationLockControllerImplTest.java", "tests/src/**/systemui/statusbar/phone/ScrimControllerTest.java", - "tests/src/**/systemui/stylus/StylusUsiPowerStartableTest.kt", "tests/src/**/systemui/toast/ToastUITest.java", "tests/src/**/systemui/statusbar/policy/FlashlightControllerImplTest.kt", "tests/src/**/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt", + "tests/src/**/systemui/stylus/StylusUsiPowerUiTest.kt", + ], +} + +// Files which use ExtendedMockito on the device. +filegroup { + name: "SystemUI-tests-broken-robofiles-mockito-extended", + srcs: [ + "tests/src/**/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt", + "tests/src/**/systemui/notetask/shortcut/LaunchNoteTaskActivityTest.kt", + "tests/src/**/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivityTest.kt", + "tests/src/**/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt", + "tests/src/**/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelTest.kt", + "tests/src/**/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt", + "tests/src/**/systemui/stylus/StylusManagerTest.kt", + "tests/src/**/systemui/recents/OverviewProxyServiceTest.kt", + "tests/src/**/systemui/DisplayCutoutBaseViewTest.kt", + "tests/src/**/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt", + "tests/src/**/systemui/statusbar/policy/BatteryControllerTest.java", + "tests/src/**/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt", + "tests/src/**/systemui/statusbar/KeyboardShortcutsReceiverTest.java", + "tests/src/**/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt", + "tests/src/**/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt", + "tests/src/**/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt", + "tests/src/**/systemui/qs/tiles/HotspotTileTest.java", + "tests/src/**/systemui/qs/tiles/dialog/InternetDialogDelegateTest.java", + "tests/src/**/systemui/navigationbar/NavigationBarControllerImplTest.java", + "tests/src/**/systemui/wmshell/BubblesTest.java", + "tests/src/**/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java", + "tests/src/**/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java", + "tests/src/**/systemui/shared/system/RemoteTransitionTest.java", + "tests/src/**/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java", + "tests/src/**/systemui/qs/external/TileLifecycleManagerTest.java", + "tests/src/**/systemui/ScreenDecorationsTest.java", + "tests/src/**/keyguard/CarrierTextManagerTest.java", + "tests/src/**/keyguard/KeyguardUpdateMonitorTest.java", ], } @@ -314,29 +336,23 @@ filegroup { filegroup { name: "SystemUI-tests-broken-robofiles-compile", srcs: [ - "tests/src/**/keyguard/KeyguardUpdateMonitorTest.java", "tests/src/**/systemui/statusbar/notification/icon/IconManagerTest.kt", "tests/src/**/systemui/statusbar/KeyguardIndicationControllerTest.java", "tests/src/**/systemui/doze/DozeScreenStateTest.java", - "tests/src/**/keyguard/CarrierTextManagerTest.java", "tests/src/**/systemui/notetask/NoteTaskInitializerTest.kt", "tests/src/**/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt", "tests/src/**/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt", "tests/src/**/systemui/controls/management/ControlsFavoritingActivityTest.kt", "tests/src/**/systemui/controls/management/ControlsProviderSelectorActivityTest.kt", "tests/src/**/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt", - "tests/src/**/systemui/media/controls/domain/pipeline/MediaTimeoutListenerTest.kt", "tests/src/**/systemui/media/taptotransfer/receiver/FakeMediaTttChipControllerReceiver.kt", "tests/src/**/systemui/qs/tileimpl/QSTileViewImplTest.kt", - "tests/src/**/systemui/statusbar/policy/BatteryStateNotifierTest.kt", "tests/src/**/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt", "tests/src/**/keyguard/ClockEventControllerTest.kt", "tests/src/**/systemui/bluetooth/qsdialog/BluetoothAutoOnRepositoryTest.kt", - "tests/src/**/systemui/bluetooth/qsdialog/BluetoothStateInteractorTest.kt", "tests/src/**/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegateTest.kt", "tests/src/**/systemui/bluetooth/qsdialog/BluetoothTileDialogRepositoryTest.kt", "tests/src/**/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt", - "tests/src/**/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt", "tests/src/**/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt", "tests/src/**/systemui/broadcast/UserBroadcastDispatcherTest.kt", "tests/src/**/systemui/charging/WiredChargingRippleControllerTest.kt", @@ -351,7 +367,6 @@ filegroup { "tests/src/**/systemui/controls/ui/SelectionItemTest.kt", "tests/src/**/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt", "tests/src/**/systemui/media/controls/domain/pipeline/LegacyMediaDataFilterImplTest.kt", - "tests/src/**/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt", "tests/src/**/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt", "tests/src/**/systemui/media/controls/ui/animation/AnimationBindHandlerTest.kt", "tests/src/**/systemui/media/controls/ui/animation/ColorSchemeTransitionTest.kt", @@ -417,40 +432,9 @@ filegroup { "tests/src/**/systemui/statusbar/policy/VariableDateViewControllerTest.kt", "tests/src/**/systemui/statusbar/policy/WalletControllerImplTest.kt", "tests/src/**/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt", - "tests/src/**/systemui/stylus/StylusUsiPowerUiTest.kt", "tests/src/**/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt", - "tests/src/**/systemui/ScreenDecorationsTest.java", - "tests/src/**/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt", - "tests/src/**/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt", - "tests/src/**/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt", - "tests/src/**/systemui/shared/system/RemoteTransitionTest.java", - "tests/src/**/systemui/navigationbar/NavigationBarControllerImplTest.java", - "tests/src/**/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelTest.kt", - "tests/src/**/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt", - "tests/src/**/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt", - "tests/src/**/systemui/notetask/LaunchNotesRoleSettingsTrampolineActivityTest.kt", - "tests/src/**/systemui/notetask/shortcut/LaunchNoteTaskActivityTest.kt", - "tests/src/**/systemui/DisplayCutoutBaseViewTest.kt", - "tests/src/**/systemui/qs/tiles/dialog/InternetDialogDelegateTest.java", - "tests/src/**/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java", - "tests/src/**/systemui/qs/tiles/HotspotTileTest.java", - "tests/src/**/systemui/qs/external/TileLifecycleManagerTest.java", - "tests/src/**/systemui/recents/OverviewProxyServiceTest.kt", - "tests/src/**/systemui/stylus/StylusManagerTest.kt", - "tests/src/**/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java", - "tests/src/**/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java", "tests/src/**/systemui/statusbar/policy/BatteryControllerStartableTest.java", - "tests/src/**/systemui/statusbar/policy/BatteryControllerTest.java", - "tests/src/**/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt", - "tests/src/**/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt", - "tests/src/**/systemui/statusbar/KeyboardShortcutsReceiverTest.java", - "tests/src/**/systemui/wmshell/BubblesTest.java", - "tests/src/**/systemui/power/PowerUITest.java", - "tests/src/**/systemui/qs/QSSecurityFooterTest.java", - "tests/src/**/systemui/qs/tileimpl/QSTileImplTest.java", "tests/src/**/systemui/shared/plugins/PluginActionManagerTest.java", - "tests/src/**/systemui/statusbar/CommandQueueTest.java", - "tests/src/**/systemui/statusbar/connectivity/CallbackHandlerTest.java", "tests/src/**/systemui/statusbar/policy/SecurityControllerTest.java", "tests/src/**/systemui/shared/clocks/view/SimpleDigitalClockTextViewTest.kt", ], @@ -497,6 +481,9 @@ android_library { resource_dirs: [], static_libs: [ "//frameworks/libs/systemui:compilelib", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/dagger:api", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/util/settings:api", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail:impl", "SystemUI-res", "WifiTrackerLib", "WindowManager-Shell", @@ -770,6 +757,9 @@ android_library { ], static_libs: [ "//frameworks/libs/systemui:compilelib", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/dagger:api", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/util/settings:api", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail:impl", "SystemUI-tests-base", "androidx.test.uiautomator_uiautomator", "androidx.core_core-animation-testing", @@ -910,6 +900,7 @@ android_robolectric_test { ":SystemUI-tests-robofiles", ], exclude_srcs: [ + ":SystemUI-tests-broken-robofiles-mockito-extended", ":SystemUI-tests-broken-robofiles-compile", ":SystemUI-tests-broken-robofiles-run", ":SystemUI-tests-broken-robofiles-sysui-run", diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING index 380344a23c99..e47704ebdf86 100644 --- a/packages/SystemUI/TEST_MAPPING +++ b/packages/SystemUI/TEST_MAPPING @@ -153,5 +153,11 @@ { "path": "cts/tests/tests/multiuser" } + ], + + "sysui-e2e-presubmit": [ + { + "name": "PlatformScenarioTests_SysUI_Presubmit" + } ] } diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index aae0f4b609be..a4b8821383e0 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -1734,16 +1734,6 @@ flag { } flag { - name: "material_colors_10_2024" - namespace: "systemui" - description: "Adding new Material Tokens as of October 2024" - bug: "376195115" - metadata { - purpose: PURPOSE_FEATURE - } -} - -flag { name: "qs_tile_detailed_view" namespace: "systemui" description: "Enables the tile detailed view UI." @@ -1774,6 +1764,7 @@ flag { bug: "371224114" } + flag { name: "keyboard_shortcut_helper_shortcut_customizer" namespace: "systemui" @@ -1799,4 +1790,4 @@ flag { metadata { purpose: PURPOSE_BUGFIX } -} +}
\ No newline at end of file diff --git a/packages/SystemUI/common/Android.bp b/packages/SystemUI/common/Android.bp index 91dc3e338c59..9f1598364dbc 100644 --- a/packages/SystemUI/common/Android.bp +++ b/packages/SystemUI/common/Android.bp @@ -30,5 +30,9 @@ java_library { "src/**/*.kt", ], + static_libs: ["SystemUI-shared-utils"], + + libs: ["//frameworks/libs/systemui:tracinglib-platform"], + kotlincflags: ["-Xjvm-default=all"], } diff --git a/packages/SystemUI/src/com/android/systemui/common/coroutine/ConflatedCallbackFlow.kt b/packages/SystemUI/common/src/com/android/systemui/common/coroutine/ConflatedCallbackFlow.kt index 0c181e99b21c..0c181e99b21c 100644 --- a/packages/SystemUI/src/com/android/systemui/common/coroutine/ConflatedCallbackFlow.kt +++ b/packages/SystemUI/common/src/com/android/systemui/common/coroutine/ConflatedCallbackFlow.kt diff --git a/packages/SystemUI/src/com/android/systemui/coroutines/Tracing.kt b/packages/SystemUI/common/src/com/android/systemui/coroutines/Tracing.kt index efbdf4d1533d..efbdf4d1533d 100644 --- a/packages/SystemUI/src/com/android/systemui/coroutines/Tracing.kt +++ b/packages/SystemUI/common/src/com/android/systemui/coroutines/Tracing.kt diff --git a/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt index 71ec63c1666c..d31d7aa59489 100644 --- a/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt +++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt @@ -63,9 +63,6 @@ private fun platformColorScheme(isDarkTheme: Boolean, context: Context): ColorSc return if (isDarkTheme) { dynamicDarkColorScheme(context) .copy( - inverseSurface = color(context, R.color.system_inverse_surface_dark), - inverseOnSurface = color(context, R.color.system_inverse_on_surface_dark), - inversePrimary = color(context, R.color.system_inverse_primary_dark), error = color(context, R.color.system_error_dark), onError = color(context, R.color.system_on_error_dark), errorContainer = color(context, R.color.system_error_container_dark), @@ -74,9 +71,6 @@ private fun platformColorScheme(isDarkTheme: Boolean, context: Context): ColorSc } else { dynamicLightColorScheme(context) .copy( - inverseSurface = color(context, R.color.system_inverse_surface_light), - inverseOnSurface = color(context, R.color.system_inverse_on_surface_light), - inversePrimary = color(context, R.color.system_inverse_primary_light), error = color(context, R.color.system_error_light), onError = color(context, R.color.system_on_error_light), errorContainer = color(context, R.color.system_error_container_light), diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/PlatformThemeTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/PlatformThemeTest.kt index 737853b88f7a..de021a0677cf 100644 --- a/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/PlatformThemeTest.kt +++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/theme/PlatformThemeTest.kt @@ -89,7 +89,7 @@ class PlatformThemeTest { addValue( "inversePrimary", colorScheme.inversePrimary, - R.attr.materialColorInversePrimary, + R.attr.materialColorPrimaryInverse, ) addValue("secondary", colorScheme.secondary, R.attr.materialColorSecondary) addValue("onSecondary", colorScheme.onSecondary, R.attr.materialColorOnSecondary) @@ -131,12 +131,12 @@ class PlatformThemeTest { addValue( "inverseSurface", colorScheme.inverseSurface, - R.attr.materialColorInverseSurface, + R.attr.materialColorSurfaceInverse, ) addValue( "inverseOnSurface", colorScheme.inverseOnSurface, - R.attr.materialColorInverseOnSurface, + R.attr.materialColorOnSurfaceInverse, ) addValue("error", colorScheme.error, R.attr.materialColorError) addValue("onError", colorScheme.onError, R.attr.materialColorOnError) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt index 9392b1afffa3..96e99b15363d 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt @@ -66,13 +66,13 @@ constructor( interactionHandler = interactionHandler, dialogFactory = dialogFactory, widgetSection = widgetSection, - modifier = Modifier.element(Communal.Elements.Grid) + modifier = Modifier.element(Communal.Elements.Grid), ) } with(lockSection) { LockIcon( overrideColor = MaterialTheme.colorScheme.onPrimaryContainer, - modifier = Modifier.element(Communal.Elements.LockIcon) + modifier = Modifier.element(Communal.Elements.LockIcon), ) } with(bottomAreaSection) { @@ -80,17 +80,13 @@ constructor( Modifier.element(Communal.Elements.IndicationArea).fillMaxWidth() ) } - } + }, ) { measurables, constraints -> val communalGridMeasurable = measurables[0] val lockIconMeasurable = measurables[1] val bottomAreaMeasurable = measurables[2] - val noMinConstraints = - constraints.copy( - minWidth = 0, - minHeight = 0, - ) + val noMinConstraints = constraints.copy(minWidth = 0, minHeight = 0) val lockIconPlaceable = lockIconMeasurable.measure(noMinConstraints) val lockIconBounds = @@ -109,14 +105,8 @@ constructor( ) layout(constraints.maxWidth, constraints.maxHeight) { - communalGridPlaceable.place( - x = 0, - y = 0, - ) - lockIconPlaceable.place( - x = lockIconBounds.left, - y = lockIconBounds.top, - ) + communalGridPlaceable.place(x = 0, y = 0) + lockIconPlaceable.place(x = lockIconBounds.left, y = lockIconBounds.top) bottomAreaPlaceable.place( x = 0, y = constraints.maxHeight - bottomAreaPlaceable.height, diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt index 5e1ac1f30354..df1185cb1a6d 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt @@ -807,7 +807,6 @@ private fun BoxScope.CommunalHubLazyGrid( ) { ResizeableItemFrameViewModel() } - if (viewModel.isEditMode && dragDropState != null) { val isItemDragging = dragDropState.draggingItemKey == item.key val outlineAlpha by diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ContentListState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ContentListState.kt index 6e30575a684d..16002bc709fd 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ContentListState.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ContentListState.kt @@ -59,7 +59,14 @@ internal constructor( private val onAddWidget: (componentName: ComponentName, user: UserHandle, rank: Int) -> Unit, private val onDeleteWidget: (id: Int, componentName: ComponentName, rank: Int) -> Unit, private val onReorderWidgets: (widgetIdToRankMap: Map<Int, Int>) -> Unit, - private val onResizeWidget: (id: Int, spanY: Int, widgetIdToRankMap: Map<Int, Int>) -> Unit, + private val onResizeWidget: + ( + id: Int, + spanY: Int, + widgetIdToRankMap: Map<Int, Int>, + componentName: ComponentName, + rank: Int, + ) -> Unit, ) { var list = communalContent.toMutableStateList() private set @@ -105,7 +112,9 @@ internal constructor( } else { emptyMap() } - onResizeWidget(item.appWidgetId, newSpan, widgetIdToRankMap) + val componentName = item.componentName + val rank = item.rank + onResizeWidget(item.appWidgetId, newSpan, widgetIdToRankMap, componentName, rank) } /** diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt index 20c8c6a3f4bf..2d32fd768eaa 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt @@ -36,6 +36,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.CornerSize import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon import androidx.compose.material3.LocalContentColor @@ -84,6 +85,7 @@ import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsSecurityButtonVi import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.qs.ui.composable.QuickSettings import com.android.systemui.qs.ui.composable.QuickSettingsTheme +import com.android.systemui.qs.ui.compose.borderOnFocus import com.android.systemui.res.R import kotlinx.coroutines.launch @@ -264,7 +266,11 @@ private fun IconButton(model: FooterActionsButtonViewModel, modifier: Modifier = color = colorAttr(model.backgroundColor), shape = CircleShape, onClick = model.onClick, - modifier = modifier, + modifier = + modifier.borderOnFocus( + color = MaterialTheme.colorScheme.secondary, + CornerSize(percent = 50), + ), ) { val tint = model.iconTint?.let { Color(it) } ?: Color.Unspecified Icon(model.icon, tint = tint, modifier = Modifier.size(20.dp)) @@ -291,7 +297,11 @@ private fun NumberButton( shape = CircleShape, onClick = onClick, interactionSource = interactionSource, - modifier = modifier, + modifier = + modifier.borderOnFocus( + color = MaterialTheme.colorScheme.secondary, + CornerSize(percent = 50), + ), ) { Box(Modifier.size(40.dp)) { Box( @@ -342,7 +352,10 @@ private fun TextButton( color = colorAttr(R.attr.underSurface), contentColor = MaterialTheme.colorScheme.onSurfaceVariant, borderStroke = BorderStroke(1.dp, colorAttr(R.attr.shadeInactive)), - modifier = modifier.padding(horizontal = 4.dp), + modifier = + modifier + .padding(horizontal = 4.dp) + .borderOnFocus(color = MaterialTheme.colorScheme.secondary, CornerSize(50)), onClick = onClick, ) { Row( diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt index 2cde6787f730..d546a5db495e 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt @@ -15,7 +15,9 @@ import com.android.systemui.scene.ui.composable.transitions.bouncerToGoneTransit import com.android.systemui.scene.ui.composable.transitions.bouncerToLockscreenPreview import com.android.systemui.scene.ui.composable.transitions.communalToBouncerTransition import com.android.systemui.scene.ui.composable.transitions.communalToShadeTransition +import com.android.systemui.scene.ui.composable.transitions.dreamToBouncerTransition import com.android.systemui.scene.ui.composable.transitions.dreamToGoneTransition +import com.android.systemui.scene.ui.composable.transitions.dreamToShadeTransition import com.android.systemui.scene.ui.composable.transitions.goneToQuickSettingsTransition import com.android.systemui.scene.ui.composable.transitions.goneToShadeTransition import com.android.systemui.scene.ui.composable.transitions.goneToSplitShadeTransition @@ -55,7 +57,9 @@ val SceneContainerTransitions = transitions { // Scene transitions from(Scenes.Bouncer, to = Scenes.Gone) { bouncerToGoneTransition() } + from(Scenes.Dream, to = Scenes.Bouncer) { dreamToBouncerTransition() } from(Scenes.Dream, to = Scenes.Gone) { dreamToGoneTransition() } + from(Scenes.Dream, to = Scenes.Shade) { dreamToShadeTransition() } from(Scenes.Gone, to = Scenes.Shade) { goneToShadeTransition() } from(Scenes.Gone, to = Scenes.Shade, key = ToSplitShade) { goneToSplitShadeTransition() } from(Scenes.Gone, to = Scenes.Shade, key = SlightlyFasterShadeCollapse) { diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutInfo.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromDreamToBouncerTransition.kt index e4ccc2c553fa..8cb89f91a831 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutInfo.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromDreamToBouncerTransition.kt @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.android.systemui.keyboard.shortcut.shared.model +package com.android.systemui.scene.ui.composable.transitions -data class ShortcutInfo( - val label: String, - val categoryType: ShortcutCategoryType, - val subCategoryLabel: String, -) +import com.android.compose.animation.scene.TransitionBuilder + +fun TransitionBuilder.dreamToBouncerTransition() { + toBouncerTransition() +} diff --git a/core/java/android/text/ClientFlags.java b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromDreamToShadeTransition.kt index ca887646b3aa..e35aaae19e29 100644 --- a/core/java/android/text/ClientFlags.java +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromDreamToShadeTransition.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,16 +14,10 @@ * limitations under the License. */ -package android.text; +package com.android.systemui.scene.ui.composable.transitions -/** - * An aconfig feature flags that can be accessible from application process without - * ContentProvider IPCs. - * - * When you add new flags, you have to add flag string to {@link TextFlags#TEXT_ACONFIGS_FLAGS}. - * - * TODO(nona): Remove this class. - * @hide - */ -public class ClientFlags { +import com.android.compose.animation.scene.TransitionBuilder + +fun TransitionBuilder.dreamToShadeTransition(durationScale: Double = 1.0) { + toShadeTransition(durationScale = durationScale) } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt index c33d655fe52b..04c527176cce 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt @@ -530,16 +530,12 @@ internal class Swipes(val upOrLeft: Swipe.Resolved, val downOrRight: Swipe.Resol } internal class NestedScrollHandlerImpl( - private val layoutImpl: SceneTransitionLayoutImpl, - private val orientation: Orientation, + private val draggableHandler: DraggableHandlerImpl, internal var topOrLeftBehavior: NestedScrollBehavior, internal var bottomOrRightBehavior: NestedScrollBehavior, internal var isExternalOverscrollGesture: () -> Boolean, private val pointersInfoOwner: PointersInfoOwner, ) { - private val layoutState = layoutImpl.state - private val draggableHandler = layoutImpl.draggableHandler(orientation) - val connection: PriorityNestedScrollConnection = nestedScrollConnection() private fun nestedScrollConnection(): PriorityNestedScrollConnection { @@ -550,13 +546,15 @@ internal class NestedScrollHandlerImpl( var lastPointersDown: PointersInfo.PointersDown? = null fun shouldEnableSwipes(): Boolean { - return layoutImpl.contentForUserActions().shouldEnableSwipes(orientation) + return draggableHandler.layoutImpl + .contentForUserActions() + .shouldEnableSwipes(draggableHandler.orientation) } var isIntercepting = false return PriorityNestedScrollConnection( - orientation = orientation, + orientation = draggableHandler.orientation, canStartPreScroll = { offsetAvailable, offsetBeforeStart, _ -> val pointersDown: PointersInfo.PointersDown? = when (val info = pointersInfoOwner.pointersInfo()) { @@ -578,8 +576,9 @@ internal class NestedScrollHandlerImpl( draggableHandler.shouldImmediatelyIntercept(pointersDown) if (!canInterceptSwipeTransition) return@PriorityNestedScrollConnection false + val layoutImpl = draggableHandler.layoutImpl val threshold = layoutImpl.transitionInterceptionThreshold - val hasSnappedToIdle = layoutState.snapToIdleIfClose(threshold) + val hasSnappedToIdle = layoutImpl.state.snapToIdleIfClose(threshold) if (hasSnappedToIdle) { // If the current swipe transition is closed to 0f or 1f, then we want to // interrupt the transition (snapping it to Idle) and scroll the list. diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt index d976e8e62f3c..44f60cb6f0a6 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt @@ -50,6 +50,8 @@ import androidx.compose.ui.util.fastForEachReversed import androidx.compose.ui.util.lerp import com.android.compose.animation.scene.content.Content import com.android.compose.animation.scene.content.state.TransitionState +import com.android.compose.animation.scene.transformation.CustomPropertyTransformation +import com.android.compose.animation.scene.transformation.InterpolatedPropertyTransformation import com.android.compose.animation.scene.transformation.PropertyTransformation import com.android.compose.animation.scene.transformation.SharedElementTransformation import com.android.compose.animation.scene.transformation.TransformationWithRange @@ -1308,7 +1310,14 @@ private inline fun <T> computeValue( checkNotNull(if (currentContent == toContent) toState else fromState) val idleValue = contentValue(overscrollState) val targetValue = - with(propertySpec.transformation) { + with( + propertySpec.transformation.requireInterpolatedTransformation( + element, + transition, + ) { + "Custom transformations in overscroll specs should not be possible" + } + ) { layoutImpl.propertyTransformationScope.transform( currentContent, element.key, @@ -1390,7 +1399,7 @@ private inline fun <T> computeValue( // fromContent or toContent during interruptions. val content = contentState.content - val transformation = + val transformationWithRange = transformation(transition.transformationSpec.transformations(element.key, content)) val previewTransformation = @@ -1403,7 +1412,14 @@ private inline fun <T> computeValue( val idleValue = contentValue(contentState) val isEntering = content == toContent val previewTargetValue = - with(previewTransformation.transformation) { + with( + previewTransformation.transformation.requireInterpolatedTransformation( + element, + transition, + ) { + "Custom transformations in preview specs should not be possible" + } + ) { layoutImpl.propertyTransformationScope.transform( content, element.key, @@ -1413,8 +1429,15 @@ private inline fun <T> computeValue( } val targetValueOrNull = - transformation?.let { transformation -> - with(transformation.transformation) { + transformationWithRange?.let { transformation -> + with( + transformation.transformation.requireInterpolatedTransformation( + element, + transition, + ) { + "Custom transformations are not allowed for properties with a preview" + } + ) { layoutImpl.propertyTransformationScope.transform( content, element.key, @@ -1461,7 +1484,7 @@ private inline fun <T> computeValue( lerp( lerp(previewTargetValue, targetValueOrNull ?: idleValue, previewRangeProgress), idleValue, - transformation?.range?.progress(transition.progress) ?: transition.progress, + transformationWithRange?.range?.progress(transition.progress) ?: transition.progress, ) } else { if (targetValueOrNull == null) { @@ -1474,22 +1497,39 @@ private inline fun <T> computeValue( lerp( lerp(idleValue, previewTargetValue, previewRangeProgress), targetValueOrNull, - transformation.range?.progress(transition.progress) ?: transition.progress, + transformationWithRange.range?.progress(transition.progress) + ?: transition.progress, ) } } } - if (transformation == null) { + if (transformationWithRange == null) { // If there is no transformation explicitly associated to this element value, let's use // the value given by the system (like the current position and size given by the layout // pass). return currentValue() } + val transformation = transformationWithRange.transformation + when (transformation) { + is CustomPropertyTransformation -> + return with(transformation) { + layoutImpl.propertyTransformationScope.transform( + content, + element.key, + transition, + transition.coroutineScope, + ) + } + is InterpolatedPropertyTransformation -> { + /* continue */ + } + } + val idleValue = contentValue(contentState) val targetValue = - with(transformation.transformation) { + with(transformation) { layoutImpl.propertyTransformationScope.transform( content, element.key, @@ -1506,7 +1546,7 @@ private inline fun <T> computeValue( val progress = transition.progress // TODO(b/290184746): Make sure that we don't overflow transformations associated to a range. - val rangeProgress = transformation.range?.progress(progress) ?: progress + val rangeProgress = transformationWithRange.range?.progress(progress) ?: progress // Interpolate between the value at rest and the value before entering/after leaving. val isEntering = @@ -1523,6 +1563,22 @@ private inline fun <T> computeValue( } } +private inline fun <T> PropertyTransformation<T>.requireInterpolatedTransformation( + element: Element, + transition: TransitionState.Transition, + errorMessage: () -> String, +): InterpolatedPropertyTransformation<T> { + return when (this) { + is InterpolatedPropertyTransformation -> this + is CustomPropertyTransformation -> { + val elem = element.key.debugName + val fromContent = transition.fromContent + val toContent = transition.toContent + error("${errorMessage()} (element=$elem fromContent=$fromContent toContent=$toContent)") + } + } +} + private inline fun <T> interpolateSharedElement( transition: TransitionState.Transition, contentValue: (Element.State) -> T, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt index fbd1cd542c05..955be603efaf 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt @@ -16,7 +16,6 @@ package com.android.compose.animation.scene -import androidx.compose.foundation.gestures.Orientation import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollConnection @@ -69,32 +68,28 @@ enum class NestedScrollBehavior(val canStartOnPostFling: Boolean) { } internal fun Modifier.nestedScrollToScene( - layoutImpl: SceneTransitionLayoutImpl, - orientation: Orientation, + draggableHandler: DraggableHandlerImpl, topOrLeftBehavior: NestedScrollBehavior, bottomOrRightBehavior: NestedScrollBehavior, isExternalOverscrollGesture: () -> Boolean, ) = this then NestedScrollToSceneElement( - layoutImpl = layoutImpl, - orientation = orientation, + draggableHandler = draggableHandler, topOrLeftBehavior = topOrLeftBehavior, bottomOrRightBehavior = bottomOrRightBehavior, isExternalOverscrollGesture = isExternalOverscrollGesture, ) private data class NestedScrollToSceneElement( - private val layoutImpl: SceneTransitionLayoutImpl, - private val orientation: Orientation, + private val draggableHandler: DraggableHandlerImpl, private val topOrLeftBehavior: NestedScrollBehavior, private val bottomOrRightBehavior: NestedScrollBehavior, private val isExternalOverscrollGesture: () -> Boolean, ) : ModifierNodeElement<NestedScrollToSceneNode>() { override fun create() = NestedScrollToSceneNode( - layoutImpl = layoutImpl, - orientation = orientation, + draggableHandler = draggableHandler, topOrLeftBehavior = topOrLeftBehavior, bottomOrRightBehavior = bottomOrRightBehavior, isExternalOverscrollGesture = isExternalOverscrollGesture, @@ -102,8 +97,7 @@ private data class NestedScrollToSceneElement( override fun update(node: NestedScrollToSceneNode) { node.update( - layoutImpl = layoutImpl, - orientation = orientation, + draggableHandler = draggableHandler, topOrLeftBehavior = topOrLeftBehavior, bottomOrRightBehavior = bottomOrRightBehavior, isExternalOverscrollGesture = isExternalOverscrollGesture, @@ -112,16 +106,14 @@ private data class NestedScrollToSceneElement( override fun InspectorInfo.inspectableProperties() { name = "nestedScrollToScene" - properties["layoutImpl"] = layoutImpl - properties["orientation"] = orientation + properties["draggableHandler"] = draggableHandler properties["topOrLeftBehavior"] = topOrLeftBehavior properties["bottomOrRightBehavior"] = bottomOrRightBehavior } } private class NestedScrollToSceneNode( - private var layoutImpl: SceneTransitionLayoutImpl, - private var orientation: Orientation, + private var draggableHandler: DraggableHandlerImpl, private var topOrLeftBehavior: NestedScrollBehavior, private var bottomOrRightBehavior: NestedScrollBehavior, private var isExternalOverscrollGesture: () -> Boolean, @@ -129,12 +121,8 @@ private class NestedScrollToSceneNode( private var scrollBehaviorOwner: ScrollBehaviorOwner? = null private fun findScrollBehaviorOwner(): ScrollBehaviorOwner? { - var behaviorOwner = scrollBehaviorOwner - if (behaviorOwner == null) { - behaviorOwner = findScrollBehaviorOwner(layoutImpl.draggableHandler(orientation)) - scrollBehaviorOwner = behaviorOwner - } - return behaviorOwner + return scrollBehaviorOwner + ?: findScrollBehaviorOwner(draggableHandler).also { scrollBehaviorOwner = it } } private val updateScrollBehaviorsConnection = @@ -177,14 +165,12 @@ private class NestedScrollToSceneNode( } fun update( - layoutImpl: SceneTransitionLayoutImpl, - orientation: Orientation, + draggableHandler: DraggableHandlerImpl, topOrLeftBehavior: NestedScrollBehavior, bottomOrRightBehavior: NestedScrollBehavior, isExternalOverscrollGesture: () -> Boolean, ) { - this.layoutImpl = layoutImpl - this.orientation = orientation + this.draggableHandler = draggableHandler this.topOrLeftBehavior = topOrLeftBehavior this.bottomOrRightBehavior = bottomOrRightBehavior this.isExternalOverscrollGesture = isExternalOverscrollGesture diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt index e93cf8f714cd..b916b0b45e41 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt @@ -125,8 +125,8 @@ internal class SceneTransitionLayoutImpl( } // TODO(b/317958526): Lazily allocate scene gesture handlers the first time they are needed. - private val horizontalDraggableHandler: DraggableHandlerImpl - private val verticalDraggableHandler: DraggableHandlerImpl + internal val horizontalDraggableHandler: DraggableHandlerImpl + internal val verticalDraggableHandler: DraggableHandlerImpl internal val elementStateScope = ElementStateScopeImpl(this) internal val propertyTransformationScope = PropertyTransformationScopeImpl(this) @@ -163,12 +163,6 @@ internal class SceneTransitionLayoutImpl( state.checkThread() } - internal fun draggableHandler(orientation: Orientation): DraggableHandlerImpl = - when (orientation) { - Orientation.Vertical -> verticalDraggableHandler - Orientation.Horizontal -> horizontalDraggableHandler - } - internal fun scene(key: SceneKey): Scene { return scenes[key] ?: error("Scene $key is not configured") } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt index 72b29ee8848a..7eb5a3f8b362 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt @@ -32,6 +32,7 @@ import kotlin.math.absoluteValue import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.Job +import kotlinx.coroutines.cancel import kotlinx.coroutines.launch /** @@ -466,9 +467,9 @@ internal class MutableSceneTransitionLayoutStateImpl( return } - // Make sure that this transition settles in case it was force finished, for instance by - // calling snapToScene(). - transition.freezeAndAnimateToCurrentState() + // Make sure that this transition is cancelled in case it was force finished, for instance + // if snapToScene() is called. + transition.coroutineScope.cancel() val transitionStates = this.transitionStates if (!transitionStates.contains(transition)) { @@ -550,8 +551,8 @@ internal class MutableSceneTransitionLayoutStateImpl( } val shouldSnap = - (isProgressCloseTo(0f) && transition.currentScene == transition.fromContent) || - (isProgressCloseTo(1f) && transition.currentScene == transition.toContent) + (isProgressCloseTo(0f) && transition.isFromCurrentContent()) || + (isProgressCloseTo(1f) && transition.isToCurrentContent()) return if (shouldSnap) { finishAllTransitions() true diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt index b083f79aebf5..569593c3eb59 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt @@ -26,18 +26,18 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.unit.IntSize import androidx.compose.ui.util.fastForEach import com.android.compose.animation.scene.content.state.TransitionState -import com.android.compose.animation.scene.transformation.AnchoredSize -import com.android.compose.animation.scene.transformation.AnchoredTranslate -import com.android.compose.animation.scene.transformation.DrawScale -import com.android.compose.animation.scene.transformation.EdgeTranslate -import com.android.compose.animation.scene.transformation.Fade -import com.android.compose.animation.scene.transformation.OverscrollTranslate +import com.android.compose.animation.scene.transformation.CustomAlphaTransformation +import com.android.compose.animation.scene.transformation.CustomOffsetTransformation +import com.android.compose.animation.scene.transformation.CustomScaleTransformation +import com.android.compose.animation.scene.transformation.CustomSizeTransformation +import com.android.compose.animation.scene.transformation.InterpolatedAlphaTransformation +import com.android.compose.animation.scene.transformation.InterpolatedOffsetTransformation +import com.android.compose.animation.scene.transformation.InterpolatedScaleTransformation +import com.android.compose.animation.scene.transformation.InterpolatedSizeTransformation import com.android.compose.animation.scene.transformation.PropertyTransformation -import com.android.compose.animation.scene.transformation.ScaleSize import com.android.compose.animation.scene.transformation.SharedElementTransformation import com.android.compose.animation.scene.transformation.Transformation import com.android.compose.animation.scene.transformation.TransformationWithRange -import com.android.compose.animation.scene.transformation.Translate /** The transitions configuration of a [SceneTransitionLayout]. */ class SceneTransitions @@ -359,35 +359,34 @@ internal class TransformationSpecImpl( transformationWithRange as TransformationWithRange<SharedElementTransformation> } - is Translate, - is OverscrollTranslate, - is EdgeTranslate, - is AnchoredTranslate -> { + is InterpolatedOffsetTransformation, + is CustomOffsetTransformation -> { throwIfNotNull(offset, element, name = "offset") offset = transformationWithRange as TransformationWithRange<PropertyTransformation<Offset>> } - is ScaleSize, - is AnchoredSize -> { + is InterpolatedSizeTransformation, + is CustomSizeTransformation -> { throwIfNotNull(size, element, name = "size") size = transformationWithRange as TransformationWithRange<PropertyTransformation<IntSize>> } - is DrawScale -> { + is InterpolatedScaleTransformation, + is CustomScaleTransformation -> { throwIfNotNull(drawScale, element, name = "drawScale") drawScale = transformationWithRange as TransformationWithRange<PropertyTransformation<Scale>> } - is Fade -> { + is InterpolatedAlphaTransformation, + is CustomAlphaTransformation -> { throwIfNotNull(alpha, element, name = "alpha") alpha = transformationWithRange as TransformationWithRange<PropertyTransformation<Float>> } - else -> error("Unknown transformation: $transformation") } } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt index a448ee49d944..5ab306a63a7e 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt @@ -165,8 +165,7 @@ private class SwipeToSceneNode( private val nestedScrollHandlerImpl = NestedScrollHandlerImpl( - layoutImpl = draggableHandler.layoutImpl, - orientation = draggableHandler.orientation, + draggableHandler = draggableHandler, topOrLeftBehavior = NestedScrollBehavior.Default, bottomOrRightBehavior = NestedScrollBehavior.Default, isExternalOverscrollGesture = { false }, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt index dc26b6b382b4..1fdfca9d9509 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.content.state.TransitionState +import com.android.compose.animation.scene.transformation.CustomPropertyTransformation import kotlin.math.tanh /** Define the [transitions][SceneTransitions] to be used with a [SceneTransitionLayout]. */ @@ -527,6 +528,16 @@ interface PropertyTransformationBuilder { anchorWidth: Boolean = true, anchorHeight: Boolean = true, ) + + /** + * Apply a [CustomPropertyTransformation] to one or more elements. + * + * @see com.android.compose.animation.scene.transformation.CustomSizeTransformation + * @see com.android.compose.animation.scene.transformation.CustomOffsetTransformation + * @see com.android.compose.animation.scene.transformation.CustomAlphaTransformation + * @see com.android.compose.animation.scene.transformation.CustomScaleTransformation + */ + fun transformation(transformation: CustomPropertyTransformation<*>) } /** This converter lets you change a linear progress into a function of your choice. */ diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt index e461f9ccc295..79f8cd47d07d 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt @@ -30,6 +30,7 @@ import androidx.compose.ui.unit.Dp import com.android.compose.animation.scene.content.state.TransitionState import com.android.compose.animation.scene.transformation.AnchoredSize import com.android.compose.animation.scene.transformation.AnchoredTranslate +import com.android.compose.animation.scene.transformation.CustomPropertyTransformation import com.android.compose.animation.scene.transformation.DrawScale import com.android.compose.animation.scene.transformation.EdgeTranslate import com.android.compose.animation.scene.transformation.Fade @@ -173,7 +174,7 @@ internal abstract class BaseTransitionBuilderImpl : BaseTransitionBuilder { range = null } - protected fun transformation(transformation: Transformation) { + protected fun addTransformation(transformation: Transformation) { val transformationWithRange = TransformationWithRange(transformation, range) transformations.add( if (reversed) { @@ -185,11 +186,11 @@ internal abstract class BaseTransitionBuilderImpl : BaseTransitionBuilder { } override fun fade(matcher: ElementMatcher) { - transformation(Fade(matcher)) + addTransformation(Fade(matcher)) } override fun translate(matcher: ElementMatcher, x: Dp, y: Dp) { - transformation(Translate(matcher, x, y)) + addTransformation(Translate(matcher, x, y)) } override fun translate( @@ -197,19 +198,19 @@ internal abstract class BaseTransitionBuilderImpl : BaseTransitionBuilder { edge: Edge, startsOutsideLayoutBounds: Boolean, ) { - transformation(EdgeTranslate(matcher, edge, startsOutsideLayoutBounds)) + addTransformation(EdgeTranslate(matcher, edge, startsOutsideLayoutBounds)) } override fun anchoredTranslate(matcher: ElementMatcher, anchor: ElementKey) { - transformation(AnchoredTranslate(matcher, anchor)) + addTransformation(AnchoredTranslate(matcher, anchor)) } override fun scaleSize(matcher: ElementMatcher, width: Float, height: Float) { - transformation(ScaleSize(matcher, width, height)) + addTransformation(ScaleSize(matcher, width, height)) } override fun scaleDraw(matcher: ElementMatcher, scaleX: Float, scaleY: Float, pivot: Offset) { - transformation(DrawScale(matcher, scaleX, scaleY, pivot)) + addTransformation(DrawScale(matcher, scaleX, scaleY, pivot)) } override fun anchoredSize( @@ -218,7 +219,12 @@ internal abstract class BaseTransitionBuilderImpl : BaseTransitionBuilder { anchorWidth: Boolean, anchorHeight: Boolean, ) { - transformation(AnchoredSize(matcher, anchor, anchorWidth, anchorHeight)) + addTransformation(AnchoredSize(matcher, anchor, anchorWidth, anchorHeight)) + } + + override fun transformation(transformation: CustomPropertyTransformation<*>) { + check(range == null) { "Custom transformations can not be applied inside a range" } + addTransformation(transformation) } } @@ -257,7 +263,7 @@ internal class TransitionBuilderImpl(override val transition: TransitionState.Tr "(${transition.toContent.debugName})" } - transformation(SharedElementTransformation(matcher, enabled, elevateInContent)) + addTransformation(SharedElementTransformation(matcher, enabled, elevateInContent)) } override fun timestampRange( @@ -288,6 +294,6 @@ internal open class OverscrollBuilderImpl : BaseTransitionBuilderImpl(), Overscr x: OverscrollScope.() -> Float, y: OverscrollScope.() -> Float, ) { - transformation(OverscrollTranslate(matcher, x, y)) + addTransformation(OverscrollTranslate(matcher, x, y)) } } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt index 8187e3932975..255a16c6de6b 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt @@ -16,7 +16,7 @@ package com.android.compose.animation.scene.content -import androidx.compose.foundation.gestures.Orientation +import android.annotation.SuppressLint import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable @@ -72,6 +72,7 @@ internal sealed class Content( var targetSize by mutableStateOf(IntSize.Zero) var userActions by mutableStateOf(actions) + @SuppressLint("NotConstructor") @Composable fun Content(modifier: Modifier = Modifier) { Box( @@ -151,8 +152,7 @@ internal class ContentScopeImpl( isExternalOverscrollGesture: () -> Boolean, ): Modifier { return nestedScrollToScene( - layoutImpl = layoutImpl, - orientation = Orientation.Horizontal, + draggableHandler = layoutImpl.horizontalDraggableHandler, topOrLeftBehavior = leftBehavior, bottomOrRightBehavior = rightBehavior, isExternalOverscrollGesture = isExternalOverscrollGesture, @@ -165,8 +165,7 @@ internal class ContentScopeImpl( isExternalOverscrollGesture: () -> Boolean, ): Modifier { return nestedScrollToScene( - layoutImpl = layoutImpl, - orientation = Orientation.Vertical, + draggableHandler = layoutImpl.verticalDraggableHandler, topOrLeftBehavior = topBehavior, bottomOrRightBehavior = bottomBehavior, isExternalOverscrollGesture = isExternalOverscrollGesture, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt index e3118d67b434..38b1aaa7558d 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt @@ -35,6 +35,8 @@ import com.android.compose.animation.scene.SceneTransitionLayoutImpl import com.android.compose.animation.scene.TransformationSpec import com.android.compose.animation.scene.TransformationSpecImpl import com.android.compose.animation.scene.TransitionKey +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch /** The state associated to a [SceneTransitionLayout] at some specific point in time. */ @@ -128,7 +130,7 @@ sealed interface TransitionState { * starting a swipe transition to show [overlay] and will be `true` only once the swipe * transition is committed. */ - protected abstract val isEffectivelyShown: Boolean + abstract val isEffectivelyShown: Boolean init { check( @@ -163,7 +165,7 @@ sealed interface TransitionState { * [fromOverlay] by [toOverlay] and will [toOverlay] once the swipe transition is * committed. */ - protected abstract val effectivelyShownOverlay: OverlayKey + abstract val effectivelyShownOverlay: OverlayKey init { check(fromOverlay != toOverlay) @@ -279,8 +281,24 @@ sealed interface TransitionState { */ private var interruptionDecay: Animatable<Float, AnimationVector1D>? = null - /** Whether this transition was already started. */ - private var wasStarted = false + /** + * The coroutine scope associated to this transition. + * + * This coroutine scope can be used to launch animations associated to this transition, + * which will not finish until at least one animation/job is still running in the scope. + * + * Important: Make sure to never launch long-running jobs in this scope, otherwise the + * transition will never be considered as finished. + */ + internal val coroutineScope: CoroutineScope + get() = + _coroutineScope + ?: error( + "Transition.coroutineScope can only be accessed once the transition was " + + "started " + ) + + private var _coroutineScope: CoroutineScope? = null init { check(fromContent != toContent) @@ -326,6 +344,21 @@ sealed interface TransitionState { } } + /** Whether [fromContent] is effectively the current content of the transition. */ + internal fun isFromCurrentContent() = isCurrentContent(expectedFrom = true) + + /** Whether [toContent] is effectively the current content of the transition. */ + internal fun isToCurrentContent() = isCurrentContent(expectedFrom = false) + + private fun isCurrentContent(expectedFrom: Boolean): Boolean { + val expectedContent = if (expectedFrom) fromContent else toContent + return when (this) { + is ChangeScene -> currentScene == expectedContent + is ReplaceOverlay -> effectivelyShownOverlay == expectedContent + is ShowOrHideOverlay -> isEffectivelyShown == (expectedContent == overlay) + } + } + /** Run this transition and return once it is finished. */ protected abstract suspend fun run() @@ -341,10 +374,11 @@ sealed interface TransitionState { abstract fun freezeAndAnimateToCurrentState() internal suspend fun runInternal() { - check(!wasStarted) { "A Transition can be started only once." } - wasStarted = true - - run() + check(_coroutineScope == null) { "A Transition can be started only once." } + coroutineScope { + _coroutineScope = this + run() + } } internal fun updateOverscrollSpecs( diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt index 0ddeb7c7445f..85bb5336d574 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt @@ -28,7 +28,7 @@ internal class AnchoredSize( private val anchor: ElementKey, private val anchorWidth: Boolean, private val anchorHeight: Boolean, -) : PropertyTransformation<IntSize> { +) : InterpolatedSizeTransformation { override fun PropertyTransformationScope.transform( content: ContentKey, element: ElementKey, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt index 47508b41633c..04cd68344252 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt @@ -26,7 +26,7 @@ import com.android.compose.animation.scene.content.state.TransitionState internal class AnchoredTranslate( override val matcher: ElementMatcher, private val anchor: ElementKey, -) : PropertyTransformation<Offset> { +) : InterpolatedOffsetTransformation { override fun PropertyTransformationScope.transform( content: ContentKey, element: ElementKey, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/DrawScale.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/DrawScale.kt index 8488ae5178b0..45d6d4037c49 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/DrawScale.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/DrawScale.kt @@ -32,7 +32,7 @@ internal class DrawScale( private val scaleX: Float, private val scaleY: Float, private val pivot: Offset = Offset.Unspecified, -) : PropertyTransformation<Scale> { +) : InterpolatedScaleTransformation { override fun PropertyTransformationScope.transform( content: ContentKey, element: ElementKey, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt index 884aae4b8b1a..21d66d784e2d 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/EdgeTranslate.kt @@ -28,7 +28,7 @@ internal class EdgeTranslate( override val matcher: ElementMatcher, private val edge: Edge, private val startsOutsideLayoutBounds: Boolean = true, -) : PropertyTransformation<Offset> { +) : InterpolatedOffsetTransformation { override fun PropertyTransformationScope.transform( content: ContentKey, element: ElementKey, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Fade.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Fade.kt index ef769e7d0c19..d942273ab9ab 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Fade.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Fade.kt @@ -22,7 +22,7 @@ import com.android.compose.animation.scene.ElementMatcher import com.android.compose.animation.scene.content.state.TransitionState /** Fade an element in or out. */ -internal class Fade(override val matcher: ElementMatcher) : PropertyTransformation<Float> { +internal class Fade(override val matcher: ElementMatcher) : InterpolatedAlphaTransformation { override fun PropertyTransformationScope.transform( content: ContentKey, element: ElementKey, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/ScaleSize.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/ScaleSize.kt index ef3654b65b0a..5f3cdab3c572 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/ScaleSize.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/ScaleSize.kt @@ -31,7 +31,7 @@ internal class ScaleSize( override val matcher: ElementMatcher, private val width: Float = 1f, private val height: Float = 1f, -) : PropertyTransformation<IntSize> { +) : InterpolatedSizeTransformation { override fun PropertyTransformationScope.transform( content: ContentKey, element: ElementKey, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt index 74a3ead3fbd7..d5143d729f2e 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt @@ -18,7 +18,9 @@ package com.android.compose.animation.scene.transformation import androidx.compose.animation.core.Easing import androidx.compose.animation.core.LinearEasing +import androidx.compose.ui.geometry.Offset import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.util.fastCoerceAtLeast import androidx.compose.ui.util.fastCoerceAtMost @@ -27,7 +29,9 @@ import com.android.compose.animation.scene.ContentKey import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.ElementMatcher import com.android.compose.animation.scene.ElementStateScope +import com.android.compose.animation.scene.Scale import com.android.compose.animation.scene.content.state.TransitionState +import kotlinx.coroutines.CoroutineScope /** A transformation applied to one or more elements during a transition. */ sealed interface Transformation { @@ -35,12 +39,6 @@ sealed interface Transformation { * The matcher that should match the element(s) to which this transformation should be applied. */ val matcher: ElementMatcher - - /* - * Reverse this transformation. This is called when we use Transition(from = A, to = B) when - * animating from B to A and there is no Transition(from = B, to = A) defined. - */ - fun reversed(): Transformation = this } internal class SharedElementTransformation( @@ -50,7 +48,13 @@ internal class SharedElementTransformation( ) : Transformation /** A transformation that changes the value of an element property, like its size or offset. */ -interface PropertyTransformation<T> : Transformation { +sealed interface PropertyTransformation<T> : Transformation + +/** + * A transformation to a target/transformed value that is automatically interpolated using the + * transition progress and transformation range. + */ +sealed interface InterpolatedPropertyTransformation<T> : PropertyTransformation<T> { /** * Return the transformed value for the given property, i.e.: * - the value at progress = 0% for elements that are entering the layout (i.e. elements in the @@ -58,8 +62,8 @@ interface PropertyTransformation<T> : Transformation { * - the value at progress = 100% for elements that are leaving the layout (i.e. elements in the * content we are transitioning from). * - * The returned value will be interpolated using the [transition] progress and [idleValue], the - * value of the property when we are idle. + * The returned value will be automatically interpolated using the [transition] progress, the + * transformation range and [idleValue], the value of the property when we are idle. */ fun PropertyTransformationScope.transform( content: ContentKey, @@ -69,6 +73,50 @@ interface PropertyTransformation<T> : Transformation { ): T } +/** An [InterpolatedPropertyTransformation] applied to the size of one or more elements. */ +interface InterpolatedSizeTransformation : InterpolatedPropertyTransformation<IntSize> + +/** An [InterpolatedPropertyTransformation] applied to the offset of one or more elements. */ +interface InterpolatedOffsetTransformation : InterpolatedPropertyTransformation<Offset> + +/** An [InterpolatedPropertyTransformation] applied to the alpha of one or more elements. */ +interface InterpolatedAlphaTransformation : InterpolatedPropertyTransformation<Float> + +/** An [InterpolatedPropertyTransformation] applied to the scale of one or more elements. */ +interface InterpolatedScaleTransformation : InterpolatedPropertyTransformation<Scale> + +sealed interface CustomPropertyTransformation<T> : PropertyTransformation<T> { + /** + * Return the value that the property should have in the current frame for the given [content] + * and [element]. + * + * This transformation can use [transitionScope] to launch animations associated to + * [transition], which will not finish until at least one animation/job is still running in the + * scope. + * + * Important: Make sure to never launch long-running jobs in [transitionScope], otherwise + * [transition] will never be considered as finished. + */ + fun PropertyTransformationScope.transform( + content: ContentKey, + element: ElementKey, + transition: TransitionState.Transition, + transitionScope: CoroutineScope, + ): T +} + +/** A [CustomPropertyTransformation] applied to the size of one or more elements. */ +interface CustomSizeTransformation : CustomPropertyTransformation<IntSize> + +/** A [CustomPropertyTransformation] applied to the offset of one or more elements. */ +interface CustomOffsetTransformation : CustomPropertyTransformation<Offset> + +/** A [CustomPropertyTransformation] applied to the alpha of one or more elements. */ +interface CustomAlphaTransformation : CustomPropertyTransformation<Float> + +/** A [CustomPropertyTransformation] applied to the scale of one or more elements. */ +interface CustomScaleTransformation : CustomPropertyTransformation<Scale> + interface PropertyTransformationScope : Density, ElementStateScope { /** The current [direction][LayoutDirection] of the layout. */ val layoutDirection: LayoutDirection @@ -101,7 +149,7 @@ data class TransformationRange(val start: Float, val end: Float, val easing: Eas } /** Reverse this range. */ - fun reversed() = + internal fun reversed() = TransformationRange(start = reverseBound(end), end = reverseBound(start), easing = easing) /** Get the progress of this range given the global [transitionProgress]. */ @@ -128,6 +176,6 @@ data class TransformationRange(val start: Float, val end: Float, val easing: Eas } companion object { - const val BoundUnspecified = Float.MIN_VALUE + internal const val BoundUnspecified = Float.MIN_VALUE } } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt index 356ed9969458..d756c86f680c 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt @@ -30,7 +30,7 @@ internal class Translate( override val matcher: ElementMatcher, private val x: Dp = 0.dp, private val y: Dp = 0.dp, -) : PropertyTransformation<Offset> { +) : InterpolatedOffsetTransformation { override fun PropertyTransformationScope.transform( content: ContentKey, element: ElementKey, @@ -45,7 +45,7 @@ internal class OverscrollTranslate( override val matcher: ElementMatcher, val x: OverscrollScope.() -> Float = { 0f }, val y: OverscrollScope.() -> Float = { 0f }, -) : PropertyTransformation<Offset> { +) : InterpolatedOffsetTransformation { private val cachedOverscrollScope = CachedOverscrollScope() override fun PropertyTransformationScope.transform( diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt b/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt index 20a0b390a037..3f182363e20c 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt @@ -365,12 +365,16 @@ private class OnStopScopeImpl(private val controller: ScrollController) : OnStop flingBehavior: FlingBehavior, ): Float { return with(flingBehavior) { - object : ScrollScope { - override fun scrollBy(pixels: Float): Float { - return controller.onScroll(pixels, NestedScrollSource.SideEffect) + val remainingVelocity = + object : ScrollScope { + override fun scrollBy(pixels: Float): Float { + return controller.onScroll(pixels, NestedScrollSource.SideEffect) + } } - } - .performFling(initialVelocity) + .performFling(initialVelocity) + + // returns the consumed velocity + initialVelocity - remainingVelocity } } } diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt index 7e6f3a88fab1..61e9bb0db0f7 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt @@ -133,8 +133,8 @@ class DraggableHandlerTest { ) .apply { setContentsAndLayoutTargetSizeForTest(LAYOUT_SIZE) } - val draggableHandler = layoutImpl.draggableHandler(Orientation.Vertical) - val horizontalDraggableHandler = layoutImpl.draggableHandler(Orientation.Horizontal) + val draggableHandler = layoutImpl.verticalDraggableHandler + val horizontalDraggableHandler = layoutImpl.horizontalDraggableHandler var pointerInfoOwner: () -> PointersInfo = { pointersDown() } @@ -143,8 +143,7 @@ class DraggableHandlerTest { isExternalOverscrollGesture: Boolean = false, ) = NestedScrollHandlerImpl( - layoutImpl = layoutImpl, - orientation = draggableHandler.orientation, + draggableHandler = draggableHandler, topOrLeftBehavior = nestedScrollBehavior, bottomOrRightBehavior = nestedScrollBehavior, isExternalOverscrollGesture = { isExternalOverscrollGesture }, diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt index 2b7090876bad..57ad81ebf7f0 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt @@ -23,6 +23,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.test.junit4.createComposeRule import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.compose.animation.scene.TestOverlays.OverlayA import com.android.compose.animation.scene.TestScenes.SceneA import com.android.compose.animation.scene.TestScenes.SceneB import com.android.compose.animation.scene.TestScenes.SceneC @@ -35,12 +36,15 @@ import com.android.compose.test.runMonotonicClockTest import com.android.compose.test.transition import com.google.common.truth.Truth.assertThat import kotlin.coroutines.cancellation.CancellationException +import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.consumeAsFlow import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Assert.assertThrows import org.junit.Rule @@ -185,6 +189,25 @@ class SceneTransitionLayoutStateTest { } @Test + fun snapToIdleIfClose_snapToStart_overlays() = runMonotonicClockTest { + val state = MutableSceneTransitionLayoutStateImpl(SceneA, SceneTransitions.Empty) + state.startTransitionImmediately( + animationScope = backgroundScope, + transition(SceneA, OverlayA, isEffectivelyShown = { false }, progress = { 0.2f }), + ) + assertThat(state.isTransitioning()).isTrue() + + // Ignore the request if the progress is not close to 0 or 1, using the threshold. + assertThat(state.snapToIdleIfClose(threshold = 0.1f)).isFalse() + assertThat(state.isTransitioning()).isTrue() + + // Go to the initial scene if it is close to 0. + assertThat(state.snapToIdleIfClose(threshold = 0.2f)).isTrue() + assertThat(state.isTransitioning()).isFalse() + assertThat(state.transitionState).isEqualTo(TransitionState.Idle(SceneA)) + } + + @Test fun snapToIdleIfClose_snapToEnd() = runMonotonicClockTest { val state = MutableSceneTransitionLayoutStateImpl(SceneA, SceneTransitions.Empty) state.startTransitionImmediately( @@ -204,6 +227,25 @@ class SceneTransitionLayoutStateTest { } @Test + fun snapToIdleIfClose_snapToEnd_overlays() = runMonotonicClockTest { + val state = MutableSceneTransitionLayoutStateImpl(SceneA, SceneTransitions.Empty) + state.startTransitionImmediately( + animationScope = backgroundScope, + transition(SceneA, OverlayA, isEffectivelyShown = { true }, progress = { 0.8f }), + ) + assertThat(state.isTransitioning()).isTrue() + + // Ignore the request if the progress is not close to 0 or 1, using the threshold. + assertThat(state.snapToIdleIfClose(threshold = 0.1f)).isFalse() + assertThat(state.isTransitioning()).isTrue() + + // Go to the final scene if it is close to 1. + assertThat(state.snapToIdleIfClose(threshold = 0.2f)).isTrue() + assertThat(state.isTransitioning()).isFalse() + assertThat(state.transitionState).isEqualTo(TransitionState.Idle(SceneA, setOf(OverlayA))) + } + + @Test fun snapToIdleIfClose_multipleTransitions() = runMonotonicClockTest { val state = MutableSceneTransitionLayoutStateImpl(SceneA, SceneTransitions.Empty) @@ -601,4 +643,47 @@ class SceneTransitionLayoutStateTest { runBlocking { state.startTransition(transition) } } } + + @Test + fun transitionFinishedWhenScopeIsEmpty() = runTest { + val state = MutableSceneTransitionLayoutState(SceneA) + + // Start a transition. + val transition = transition(from = SceneA, to = SceneB) + state.startTransitionImmediately(backgroundScope, transition) + assertThat(state.transitionState).isSceneTransition() + + // Start a job in the transition scope. + val jobCompletable = CompletableDeferred<Unit>() + transition.coroutineScope.launch { jobCompletable.await() } + + // Finish the transition (i.e. make its #run() method return). The transition should not be + // considered as finished yet given that there is a job still running in its scope. + transition.finish() + runCurrent() + assertThat(state.transitionState).isSceneTransition() + + // Finish the job in the scope. Now the transition should be considered as finished. + jobCompletable.complete(Unit) + runCurrent() + assertThat(state.transitionState).isIdle() + } + + @Test + fun transitionScopeIsCancelledWhenTransitionIsForceFinished() = runTest { + val state = MutableSceneTransitionLayoutState(SceneA) + + // Start a transition. + val transition = transition(from = SceneA, to = SceneB) + state.startTransitionImmediately(backgroundScope, transition) + assertThat(state.transitionState).isSceneTransition() + + // Start a job in the transition scope that never finishes. + val job = transition.coroutineScope.launch { awaitCancellation() } + + // Force snap state to SceneB to force finish all current transitions. + state.snapToScene(SceneB) + assertThat(state.transitionState).isIdle() + assertThat(job.isCancelled).isTrue() + } } diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt index d31711496ff0..1f9ba9ee9372 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt @@ -22,17 +22,22 @@ import androidx.compose.animation.core.TweenSpec import androidx.compose.animation.core.spring import androidx.compose.animation.core.tween import androidx.compose.foundation.gestures.Orientation +import androidx.compose.ui.unit.IntSize import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.compose.animation.scene.TestScenes.SceneA import com.android.compose.animation.scene.TestScenes.SceneB import com.android.compose.animation.scene.TestScenes.SceneC import com.android.compose.animation.scene.content.state.TransitionState +import com.android.compose.animation.scene.transformation.CustomSizeTransformation import com.android.compose.animation.scene.transformation.OverscrollTranslate +import com.android.compose.animation.scene.transformation.PropertyTransformationScope import com.android.compose.animation.scene.transformation.TransformationRange import com.android.compose.animation.scene.transformation.TransformationWithRange import com.android.compose.test.transition import com.google.common.truth.Correspondence import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest import org.junit.Assert.assertThrows import org.junit.Test @@ -343,6 +348,33 @@ class TransitionDslTest { assertThat(transitionPassedToBuilder).isSameInstanceAs(transition) } + @Test + fun customTransitionsAreNotSupportedInRanges() = runTest { + val transitions = transitions { + from(SceneA, to = SceneB) { + fractionRange { + transformation( + object : CustomSizeTransformation { + override val matcher: ElementMatcher = TestElements.Foo + + override fun PropertyTransformationScope.transform( + content: ContentKey, + element: ElementKey, + transition: TransitionState.Transition, + transitionScope: CoroutineScope, + ): IntSize = IntSize.Zero + } + ) + } + } + } + + val state = MutableSceneTransitionLayoutState(SceneA, transitions) + assertThrows(IllegalStateException::class.java) { + runBlocking { state.startTransition(transition(from = SceneA, to = SceneB)) } + } + } + companion object { private val TRANSFORMATION_RANGE = Correspondence.transforming<TransformationWithRange<*>, TransformationRange?>( diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/CustomTransformationTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/CustomTransformationTest.kt new file mode 100644 index 000000000000..487b0992c3e5 --- /dev/null +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/CustomTransformationTest.kt @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.compose.animation.scene.transformation + +import androidx.compose.animation.core.LinearEasing +import androidx.compose.animation.core.tween +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.test.assertPositionInRootIsEqualTo +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.IntSize +import androidx.compose.ui.unit.dp +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.compose.animation.scene.ContentKey +import com.android.compose.animation.scene.ElementKey +import com.android.compose.animation.scene.ElementMatcher +import com.android.compose.animation.scene.TestElements +import com.android.compose.animation.scene.content.state.TransitionState +import com.android.compose.animation.scene.testTransition +import com.android.compose.test.assertSizeIsEqualTo +import kotlinx.coroutines.CoroutineScope +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class CustomTransformationTest { + @get:Rule val rule = createComposeRule() + + @Test + fun customSize() { + /** A size transformation that adds [add] to the size of the transformed element(s). */ + class AddSizeTransformation(override val matcher: ElementMatcher, private val add: Dp) : + CustomSizeTransformation { + override fun PropertyTransformationScope.transform( + content: ContentKey, + element: ElementKey, + transition: TransitionState.Transition, + transitionScope: CoroutineScope, + ): IntSize { + val idleSize = checkNotNull(element.targetSize(content)) + val progress = 1f - transition.progressTo(content) + val addPx = (add * progress).roundToPx() + return IntSize(width = idleSize.width + addPx, height = idleSize.height + addPx) + } + } + + rule.testTransition( + fromSceneContent = { Box(Modifier.element(TestElements.Foo).size(40.dp, 20.dp)) }, + toSceneContent = {}, + transition = { + spec = tween(16 * 4, easing = LinearEasing) + + // Add 80dp to the width and height of Foo. + transformation(AddSizeTransformation(TestElements.Foo, 80.dp)) + }, + ) { + before { onElement(TestElements.Foo).assertSizeIsEqualTo(40.dp, 20.dp) } + at(0) { onElement(TestElements.Foo).assertSizeIsEqualTo(40.dp, 20.dp) } + at(16) { onElement(TestElements.Foo).assertSizeIsEqualTo(60.dp, 40.dp) } + at(32) { onElement(TestElements.Foo).assertSizeIsEqualTo(80.dp, 60.dp) } + at(48) { onElement(TestElements.Foo).assertSizeIsEqualTo(100.dp, 80.dp) } + after { onElement(TestElements.Foo).assertDoesNotExist() } + } + } + + @Test + fun customOffset() { + /** An offset transformation that adds [add] to the offset of the transformed element(s). */ + class AddOffsetTransformation(override val matcher: ElementMatcher, private val add: Dp) : + CustomOffsetTransformation { + override fun PropertyTransformationScope.transform( + content: ContentKey, + element: ElementKey, + transition: TransitionState.Transition, + transitionScope: CoroutineScope, + ): Offset { + val idleOffset = checkNotNull(element.targetOffset(content)) + val progress = 1f - transition.progressTo(content) + val addPx = (add * progress).toPx() + return Offset(x = idleOffset.x + addPx, y = idleOffset.y + addPx) + } + } + + rule.testTransition( + fromSceneContent = { Box(Modifier.element(TestElements.Foo)) }, + toSceneContent = {}, + transition = { + spec = tween(16 * 4, easing = LinearEasing) + + // Add 80dp to the offset of Foo. + transformation(AddOffsetTransformation(TestElements.Foo, 80.dp)) + }, + ) { + before { onElement(TestElements.Foo).assertPositionInRootIsEqualTo(0.dp, 0.dp) } + at(0) { onElement(TestElements.Foo).assertPositionInRootIsEqualTo(0.dp, 0.dp) } + at(16) { onElement(TestElements.Foo).assertPositionInRootIsEqualTo(20.dp, 20.dp) } + at(32) { onElement(TestElements.Foo).assertPositionInRootIsEqualTo(40.dp, 40.dp) } + at(48) { onElement(TestElements.Foo).assertPositionInRootIsEqualTo(60.dp, 60.dp) } + after { onElement(TestElements.Foo).assertDoesNotExist() } + } + } +} diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt index 91079b89a56c..28ea2d239b54 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/PriorityNestedScrollConnectionTest.kt @@ -53,7 +53,8 @@ class PriorityNestedScrollConnectionTest { object : FlingBehavior { override suspend fun ScrollScope.performFling(initialVelocity: Float): Float { scrollBy(initialVelocity) - return initialVelocity / 2f + // returns the remaining velocity: 1/3 remained + 2/3 consumed + return initialVelocity / 3f } } @@ -207,11 +208,13 @@ class PriorityNestedScrollConnectionTest { val consumed = scrollConnection.onPreFling(available = Velocity(2f, 2f)) - assertThat(lastStop).isEqualTo(2f) + val initialVelocity = 2f + assertThat(lastStop).isEqualTo(initialVelocity) // flingToScroll should try to scroll the content, customFlingBehavior uses the velocity. assertThat(lastScroll).isEqualTo(2f) - // customFlingBehavior returns half of the vertical velocity. - assertThat(consumed).isEqualTo(Velocity(0f, 1f)) + val remainingVelocity = initialVelocity / 3f + // customFlingBehavior returns 2/3 of the vertical velocity. + assertThat(consumed).isEqualTo(Velocity(0f, initialVelocity - remainingVelocity)) } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardDisplayManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardDisplayManagerTest.java deleted file mode 100644 index dd58ea7db2bc..000000000000 --- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardDisplayManagerTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.keyguard; - -import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.hardware.display.DisplayManagerGlobal; -import android.testing.TestableLooper; -import android.view.Display; -import android.view.DisplayInfo; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.systemui.SysuiTestCase; -import com.android.systemui.navigationbar.NavigationBarController; -import com.android.systemui.settings.FakeDisplayTracker; -import com.android.systemui.statusbar.policy.KeyguardStateController; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.concurrent.Executor; - -@SmallTest -@RunWith(AndroidJUnit4.class) -@TestableLooper.RunWithLooper -public class KeyguardDisplayManagerTest extends SysuiTestCase { - - @Mock - private NavigationBarController mNavigationBarController; - @Mock - private ConnectedDisplayKeyguardPresentation.Factory - mConnectedDisplayKeyguardPresentationFactory; - @Mock - private ConnectedDisplayKeyguardPresentation mConnectedDisplayKeyguardPresentation; - @Mock - private KeyguardDisplayManager.DeviceStateHelper mDeviceStateHelper; - @Mock - private KeyguardStateController mKeyguardStateController; - - private Executor mMainExecutor = Runnable::run; - private Executor mBackgroundExecutor = Runnable::run; - private KeyguardDisplayManager mManager; - private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); - // The default and secondary displays are both in the default group - private Display mDefaultDisplay; - private Display mSecondaryDisplay; - - // This display is in a different group from the default and secondary displays. - private Display mAlwaysUnlockedDisplay; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mManager = spy(new KeyguardDisplayManager(mContext, () -> mNavigationBarController, - mDisplayTracker, mMainExecutor, mBackgroundExecutor, mDeviceStateHelper, - mKeyguardStateController, mConnectedDisplayKeyguardPresentationFactory)); - doReturn(mConnectedDisplayKeyguardPresentation).when( - mConnectedDisplayKeyguardPresentationFactory).create(any()); - doReturn(mConnectedDisplayKeyguardPresentation).when(mManager) - .createPresentation(any()); - mDefaultDisplay = new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY, - new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS); - mSecondaryDisplay = new Display(DisplayManagerGlobal.getInstance(), - Display.DEFAULT_DISPLAY + 1, - new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS); - - DisplayInfo alwaysUnlockedDisplayInfo = new DisplayInfo(); - alwaysUnlockedDisplayInfo.displayId = Display.DEFAULT_DISPLAY + 2; - alwaysUnlockedDisplayInfo.flags = Display.FLAG_ALWAYS_UNLOCKED; - mAlwaysUnlockedDisplay = new Display(DisplayManagerGlobal.getInstance(), - Display.DEFAULT_DISPLAY, - alwaysUnlockedDisplayInfo, DEFAULT_DISPLAY_ADJUSTMENTS); - } - - @Test - public void testShow_defaultDisplayOnly() { - mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay}); - mManager.show(); - verify(mManager, never()).createPresentation(any()); - } - - @Test - public void testShow_includeSecondaryDisplay() { - mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay, mSecondaryDisplay}); - mManager.show(); - verify(mManager, times(1)).createPresentation(eq(mSecondaryDisplay)); - } - - @Test - public void testShow_includeAlwaysUnlockedDisplay() { - mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay, mAlwaysUnlockedDisplay}); - - mManager.show(); - verify(mManager, never()).createPresentation(any()); - } - - @Test - public void testShow_includeSecondaryAndAlwaysUnlockedDisplays() { - mDisplayTracker.setAllDisplays( - new Display[]{mDefaultDisplay, mSecondaryDisplay, mAlwaysUnlockedDisplay}); - - mManager.show(); - verify(mManager, times(1)).createPresentation(eq(mSecondaryDisplay)); - } - - @Test - public void testShow_concurrentDisplayActive_occluded() { - mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay, mSecondaryDisplay}); - - when(mDeviceStateHelper.isConcurrentDisplayActive(mSecondaryDisplay)).thenReturn(true); - when(mKeyguardStateController.isOccluded()).thenReturn(true); - verify(mManager, never()).createPresentation(eq(mSecondaryDisplay)); - } - - @Test - public void testShow_presentationCreated() { - when(mManager.createPresentation(any())).thenCallRealMethod(); - mDisplayTracker.setAllDisplays(new Display[]{mDefaultDisplay, mSecondaryDisplay}); - - mManager.show(); - - verify(mConnectedDisplayKeyguardPresentationFactory).create(eq(mSecondaryDisplay)); - } -} diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardDisplayManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardDisplayManagerTest.kt new file mode 100644 index 000000000000..57a67973f34f --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardDisplayManagerTest.kt @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.keyguard + +import android.hardware.display.DisplayManagerGlobal +import android.platform.test.annotations.EnableFlags +import android.testing.TestableLooper.RunWithLooper +import android.view.Display +import android.view.DisplayAdjustments +import android.view.DisplayInfo +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.keyguard.KeyguardDisplayManager.DeviceStateHelper +import com.android.systemui.Flags +import com.android.systemui.SysuiTestCase +import com.android.systemui.navigationbar.NavigationBarController +import com.android.systemui.settings.FakeDisplayTracker +import com.android.systemui.shade.data.repository.FakeShadePositionRepository +import com.android.systemui.statusbar.policy.KeyguardStateController +import java.util.concurrent.Executor +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.advanceUntilIdle +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.mock +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.any +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.eq +import org.mockito.kotlin.reset +import org.mockito.kotlin.whenever + +@SmallTest +@RunWith(AndroidJUnit4::class) +@RunWithLooper +@OptIn(ExperimentalCoroutinesApi::class) +class KeyguardDisplayManagerTest : SysuiTestCase() { + @Mock private val navigationBarController = mock(NavigationBarController::class.java) + @Mock + private val presentationFactory = mock(ConnectedDisplayKeyguardPresentation.Factory::class.java) + @Mock + private val connectedDisplayKeyguardPresentation = + mock(ConnectedDisplayKeyguardPresentation::class.java) + @Mock private val deviceStateHelper = mock(DeviceStateHelper::class.java) + @Mock private val keyguardStateController = mock(KeyguardStateController::class.java) + private val shadePositionRepository = FakeShadePositionRepository() + + private val mainExecutor = Executor { it.run() } + private val backgroundExecutor = Executor { it.run() } + private lateinit var manager: KeyguardDisplayManager + private val displayTracker = FakeDisplayTracker(mContext) + // The default and secondary displays are both in the default group + private lateinit var defaultDisplay: Display + private lateinit var secondaryDisplay: Display + + private val testScope = TestScope(UnconfinedTestDispatcher()) + + // This display is in a different group from the default and secondary displays. + private lateinit var alwaysUnlockedDisplay: Display + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + manager = + KeyguardDisplayManager( + mContext, + { navigationBarController }, + displayTracker, + mainExecutor, + backgroundExecutor, + deviceStateHelper, + keyguardStateController, + presentationFactory, + { shadePositionRepository }, + testScope.backgroundScope, + ) + whenever(presentationFactory.create(any())).doReturn(connectedDisplayKeyguardPresentation) + + defaultDisplay = + Display( + DisplayManagerGlobal.getInstance(), + Display.DEFAULT_DISPLAY, + DisplayInfo(), + DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS, + ) + secondaryDisplay = + Display( + DisplayManagerGlobal.getInstance(), + Display.DEFAULT_DISPLAY + 1, + DisplayInfo(), + DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS, + ) + + val alwaysUnlockedDisplayInfo = DisplayInfo() + alwaysUnlockedDisplayInfo.displayId = Display.DEFAULT_DISPLAY + 2 + alwaysUnlockedDisplayInfo.flags = Display.FLAG_ALWAYS_UNLOCKED + alwaysUnlockedDisplay = + Display( + DisplayManagerGlobal.getInstance(), + Display.DEFAULT_DISPLAY, + alwaysUnlockedDisplayInfo, + DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS, + ) + } + + @Test + fun testShow_defaultDisplayOnly() { + displayTracker.allDisplays = arrayOf(defaultDisplay) + manager.show() + verify(presentationFactory, never()).create(any()) + } + + @Test + fun testShow_includeSecondaryDisplay() { + displayTracker.allDisplays = arrayOf(defaultDisplay, secondaryDisplay) + manager.show() + verify(presentationFactory).create(eq(secondaryDisplay)) + } + + @Test + fun testShow_includeAlwaysUnlockedDisplay() { + displayTracker.allDisplays = arrayOf(defaultDisplay, alwaysUnlockedDisplay) + + manager.show() + verify(presentationFactory, never()).create(any()) + } + + @Test + fun testShow_includeSecondaryAndAlwaysUnlockedDisplays() { + displayTracker.allDisplays = + arrayOf(defaultDisplay, secondaryDisplay, alwaysUnlockedDisplay) + + manager.show() + verify(presentationFactory).create(eq(secondaryDisplay)) + } + + @Test + fun testShow_concurrentDisplayActive_occluded() { + displayTracker.allDisplays = arrayOf(defaultDisplay, secondaryDisplay) + + whenever(deviceStateHelper.isConcurrentDisplayActive(secondaryDisplay)).thenReturn(true) + whenever(keyguardStateController.isOccluded).thenReturn(true) + verify(presentationFactory, never()).create(eq(secondaryDisplay)) + } + + @Test + fun testShow_presentationCreated() { + displayTracker.allDisplays = arrayOf(defaultDisplay, secondaryDisplay) + + manager.show() + + verify(presentationFactory).create(eq(secondaryDisplay)) + } + + @Test + @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND) + fun show_shadeMovesDisplay_newPresentationCreated() { + displayTracker.allDisplays = arrayOf(defaultDisplay, secondaryDisplay) + // Shade in the default display, we expect the presentation to be in the secondary only + shadePositionRepository.setDisplayId(defaultDisplay.displayId) + + manager.show() + + verify(presentationFactory).create(eq(secondaryDisplay)) + verify(presentationFactory, never()).create(eq(defaultDisplay)) + reset(presentationFactory) + whenever(presentationFactory.create(any())).thenReturn(connectedDisplayKeyguardPresentation) + + // Let's move it to the secondary display. We expect it will be added in the default + // one. + shadePositionRepository.setDisplayId(secondaryDisplay.displayId) + testScope.advanceUntilIdle() + + verify(presentationFactory).create(eq(defaultDisplay)) + reset(presentationFactory) + whenever(presentationFactory.create(any())).thenReturn(connectedDisplayKeyguardPresentation) + + // Let's move it back! it should be re-created (it means it was removed before) + shadePositionRepository.setDisplayId(defaultDisplay.displayId) + testScope.advanceUntilIdle() + + verify(presentationFactory).create(eq(secondaryDisplay)) + } + + @Test + @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND) + fun show_shadeInSecondaryDisplay_defaultOneHasPresentation() { + displayTracker.allDisplays = arrayOf(defaultDisplay, secondaryDisplay) + shadePositionRepository.setDisplayId(secondaryDisplay.displayId) + + manager.show() + + verify(presentationFactory).create(eq(defaultDisplay)) + } + + @Test + @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND) + fun show_shadeInDefaultDisplay_secondaryOneHasPresentation() { + displayTracker.allDisplays = arrayOf(defaultDisplay, secondaryDisplay) + shadePositionRepository.setDisplayId(defaultDisplay.displayId) + + manager.show() + + verify(presentationFactory).create(eq(secondaryDisplay)) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/BatteryMeterDrawableTest.java index d6a5b4b11521..d6a5b4b11521 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/BatteryMeterDrawableTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/BootCompleteCacheTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/BootCompleteCacheTest.kt index 0a9ce6854ca8..0a9ce6854ca8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/BootCompleteCacheTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/BootCompleteCacheTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/CameraAvailabilityListenerTest.kt index a23e82918845..a23e82918845 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/CameraAvailabilityListenerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt index a01fecaaaefe..a01fecaaaefe 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/FakeCameraProtectionLoader.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/FakeCameraProtectionLoader.kt index 6cb77cff4404..6cb77cff4404 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/FakeCameraProtectionLoader.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/FakeCameraProtectionLoader.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt index fb60ba381c40..fb60ba381c40 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java index fcb433b5db4e..9d471f45a293 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java @@ -45,9 +45,9 @@ import android.os.Handler; import android.platform.test.annotations.EnableFlags; import android.provider.Settings; import android.testing.TestableLooper; +import android.util.Pair; import android.view.View; import android.view.ViewGroup; -import android.widget.LinearLayout; import android.widget.Space; import android.widget.Spinner; @@ -166,6 +166,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { when(mCachedDevice.isActiveDevice(BluetoothProfile.HEARING_AID)).thenReturn(true); when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true); when(mCachedDevice.isConnectedHapClientDevice()).thenReturn(true); + when(mCachedDevice.getDrawableWithDescription()).thenReturn(new Pair<>(mDrawable, "")); when(mHearingDeviceItem.getCachedBluetoothDevice()).thenReturn(mCachedDevice); mContext.setMockPackageManager(mPackageManager); @@ -217,6 +218,18 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { @Test @EnableFlags(Flags.FLAG_HEARING_DEVICES_DIALOG_RELATED_TOOLS) + public void showDialog_noLiveCaption_noRelatedToolsInConfig_relatedToolLayoutGone() { + mContext.getOrCreateTestableResources().addOverride( + R.array.config_quickSettingsHearingDevicesRelatedToolName, new String[]{}); + + setUpPairNewDeviceDialog(); + mDialog.show(); + + assertToolsUi(0); + } + + @Test + @EnableFlags(Flags.FLAG_HEARING_DEVICES_DIALOG_RELATED_TOOLS) public void showDialog_hasLiveCaption_noRelatedToolsInConfig_showOneRelatedTool() { when(mPackageManager.queryIntentActivities( eq(LIVE_CAPTION_INTENT), anyInt())).thenReturn( @@ -227,8 +240,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { setUpPairNewDeviceDialog(); mDialog.show(); - LinearLayout relatedToolsView = (LinearLayout) getRelatedToolsView(mDialog); - assertThat(countChildWithoutSpace(relatedToolsView)).isEqualTo(1); + assertToolsUi(1); } @Test @@ -251,8 +263,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { setUpPairNewDeviceDialog(); mDialog.show(); - LinearLayout relatedToolsView = (LinearLayout) getRelatedToolsView(mDialog); - assertThat(countChildWithoutSpace(relatedToolsView)).isEqualTo(2); + assertToolsUi(2); } @Test @@ -263,8 +274,8 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { setUpDeviceListDialog(); mDialog.show(); - Spinner spinner = (Spinner) getPresetSpinner(mDialog); - assertThat(spinner.getVisibility()).isEqualTo(View.GONE); + ViewGroup presetLayout = getPresetLayout(mDialog); + assertThat(presetLayout.getVisibility()).isEqualTo(View.GONE); } @Test @@ -276,8 +287,9 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { setUpDeviceListDialog(); mDialog.show(); - Spinner spinner = (Spinner) getPresetSpinner(mDialog); - assertThat(spinner.getVisibility()).isEqualTo(View.VISIBLE); + ViewGroup presetLayout = getPresetLayout(mDialog); + assertThat(presetLayout.getVisibility()).isEqualTo(View.VISIBLE); + Spinner spinner = getPresetSpinner(mDialog); assertThat(spinner.getSelectedItemPosition()).isEqualTo(0); } @@ -292,8 +304,9 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { mDialogDelegate.onActiveDeviceChanged(mCachedDevice, BluetoothProfile.LE_AUDIO); mTestableLooper.processAllMessages(); - Spinner spinner = (Spinner) getPresetSpinner(mDialog); - assertThat(spinner.getVisibility()).isEqualTo(View.VISIBLE); + ViewGroup presetLayout = getPresetLayout(mDialog); + assertThat(presetLayout.getVisibility()).isEqualTo(View.VISIBLE); + Spinner spinner = getPresetSpinner(mDialog); assertThat(spinner.getSelectedItemPosition()).isEqualTo(0); } @@ -359,14 +372,23 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { return dialog.requireViewById(R.id.pair_new_device_button); } - private View getRelatedToolsView(SystemUIDialog dialog) { - return dialog.requireViewById(R.id.related_tools_container); + private ViewGroup getToolsContainer(SystemUIDialog dialog) { + return dialog.requireViewById(R.id.tools_container); + } + + private ViewGroup getToolsLayout(SystemUIDialog dialog) { + return dialog.requireViewById(R.id.tools_layout); } - private View getPresetSpinner(SystemUIDialog dialog) { + private Spinner getPresetSpinner(SystemUIDialog dialog) { return dialog.requireViewById(R.id.preset_spinner); } + private ViewGroup getPresetLayout(SystemUIDialog dialog) { + return dialog.requireViewById(R.id.preset_layout); + } + + private int countChildWithoutSpace(ViewGroup viewGroup) { int spaceCount = 0; for (int i = 0; i < viewGroup.getChildCount(); i++) { @@ -377,6 +399,15 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase { return viewGroup.getChildCount() - spaceCount; } + private void assertToolsUi(int childCount) { + ViewGroup toolsContainer = getToolsContainer(mDialog); + assertThat(countChildWithoutSpace(toolsContainer)).isEqualTo(childCount); + + int targetVisibility = childCount == 0 ? View.GONE : View.VISIBLE; + ViewGroup toolsLayout = getToolsLayout(mDialog); + assertThat(toolsLayout.getVisibility()).isEqualTo(targetVisibility); + } + @After public void reset() { if (mDialogDelegate != null) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelTest.kt index beb816cae095..32606e09a1ac 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelTest.kt @@ -17,8 +17,8 @@ package com.android.systemui.bluetooth.qsdialog import android.bluetooth.BluetoothDevice -import android.testing.AndroidTestingRunner import android.testing.TestableLooper +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.bluetooth.LeAudioProfile import com.android.settingslib.bluetooth.LocalBluetoothProfileManager @@ -48,7 +48,7 @@ import org.mockito.kotlin.mock import org.mockito.kotlin.whenever @SmallTest -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper(setAsMainLooper = true) @OptIn(ExperimentalCoroutinesApi::class) class AudioSharingDialogViewModelTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt index 25f956574274..25f956574274 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryTest.kt index c9e88136e4a0..acfe9dd45f75 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryTest.kt @@ -17,8 +17,8 @@ package com.android.systemui.bluetooth.qsdialog import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothLeBroadcastMetadata -import android.testing.AndroidTestingRunner import android.testing.TestableLooper +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant @@ -46,7 +46,7 @@ import org.mockito.kotlin.whenever @ExperimentalCoroutinesApi @SmallTest -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper(setAsMainLooper = true) class AudioSharingRepositoryTest : SysuiTestCase() { @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorTest.kt index f06b105a9e26..cee17c32925e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorTest.kt @@ -18,7 +18,9 @@ package com.android.systemui.bluetooth.qsdialog import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothDevice +import android.graphics.drawable.Drawable import android.testing.TestableLooper +import android.util.Pair import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.bluetooth.CachedBluetoothDevice @@ -64,6 +66,7 @@ class BluetoothDeviceMetadataInteractorTest : SysuiTestCase() { @Mock private lateinit var bluetoothDevice1: BluetoothDevice @Mock private lateinit var cachedDevice2: CachedBluetoothDevice @Mock private lateinit var bluetoothDevice2: BluetoothDevice + @Mock private lateinit var drawable: Drawable @Captor private lateinit var argumentCaptor: ArgumentCaptor<BluetoothAdapter.OnMetadataChangedListener> private lateinit var interactor: BluetoothDeviceMetadataInteractor @@ -77,12 +80,14 @@ class BluetoothDeviceMetadataInteractorTest : SysuiTestCase() { whenever(cachedDevice1.name).thenReturn(DEVICE_NAME) whenever(cachedDevice1.address).thenReturn(DEVICE_ADDRESS) whenever(cachedDevice1.connectionSummary).thenReturn(CONNECTION_SUMMARY) + whenever(cachedDevice1.drawableWithDescription).thenReturn(Pair.create(drawable, "")) whenever(bluetoothDevice1.address).thenReturn(DEVICE_ADDRESS) whenever(cachedDevice2.device).thenReturn(bluetoothDevice2) whenever(cachedDevice2.name).thenReturn(DEVICE_NAME) whenever(cachedDevice2.address).thenReturn(DEVICE_ADDRESS) whenever(cachedDevice2.connectionSummary).thenReturn(CONNECTION_SUMMARY) + whenever(cachedDevice2.drawableWithDescription).thenReturn(Pair.create(drawable, "")) whenever(bluetoothDevice2.address).thenReturn(DEVICE_ADDRESS) interactor = bluetoothDeviceMetadataInteractor @@ -175,14 +180,14 @@ class BluetoothDeviceMetadataInteractorTest : SysuiTestCase() { .addOnMetadataChangedListener( eq(bluetoothDevice1), any(), - argumentCaptor.capture() + argumentCaptor.capture(), ) val listener = argumentCaptor.value listener.onMetadataChanged( bluetoothDevice1, BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY, - ByteArray(0) + ByteArray(0), ) assertThat(update).isEqualTo(Unit) } @@ -203,14 +208,14 @@ class BluetoothDeviceMetadataInteractorTest : SysuiTestCase() { .addOnMetadataChangedListener( eq(bluetoothDevice1), any(), - argumentCaptor.capture() + argumentCaptor.capture(), ) val listener = argumentCaptor.value listener.onMetadataChanged( bluetoothDevice1, BluetoothDevice.METADATA_MODEL_NAME, - ByteArray(0) + ByteArray(0), ) assertThat(update).isNull() diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorTest.kt index 993cac721f48..993cac721f48 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorTest.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/log/CommunalMetricsLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/log/CommunalMetricsLoggerTest.kt index 82918a569990..af2d7e45ee5f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/log/CommunalMetricsLoggerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/log/CommunalMetricsLoggerTest.kt @@ -47,20 +47,14 @@ class CommunalMetricsLoggerTest : SysuiTestCase() { @Test fun logAddWidget_componentNotLoggable_doNotLog() { - underTest.logAddWidget( - componentName = "com.green.package/my_test_widget", - rank = 1, - ) + underTest.logAddWidget(componentName = "com.green.package/my_test_widget", rank = 1) verify(statsLogProxy, never()) - .writeCommunalHubWidgetEventReported(anyInt(), any(), anyInt()) + .writeCommunalHubWidgetEventReported(anyInt(), any(), anyInt(), anyInt()) } @Test fun logAddWidget_componentLoggable_logAddEvent() { - underTest.logAddWidget( - componentName = "com.blue.package/my_test_widget", - rank = 1, - ) + underTest.logAddWidget(componentName = "com.blue.package/my_test_widget", rank = 1) verify(statsLogProxy) .writeCommunalHubWidgetEventReported( SysUiStatsLog.COMMUNAL_HUB_WIDGET_EVENT_REPORTED__ACTION__ADD, @@ -71,20 +65,14 @@ class CommunalMetricsLoggerTest : SysuiTestCase() { @Test fun logRemoveWidget_componentNotLoggable_doNotLog() { - underTest.logRemoveWidget( - componentName = "com.yellow.package/my_test_widget", - rank = 2, - ) + underTest.logRemoveWidget(componentName = "com.yellow.package/my_test_widget", rank = 2) verify(statsLogProxy, never()) - .writeCommunalHubWidgetEventReported(anyInt(), any(), anyInt()) + .writeCommunalHubWidgetEventReported(anyInt(), any(), anyInt(), anyInt()) } @Test fun logRemoveWidget_componentLoggable_logRemoveEvent() { - underTest.logRemoveWidget( - componentName = "com.red.package/my_test_widget", - rank = 2, - ) + underTest.logRemoveWidget(componentName = "com.red.package/my_test_widget", rank = 2) verify(statsLogProxy) .writeCommunalHubWidgetEventReported( SysUiStatsLog.COMMUNAL_HUB_WIDGET_EVENT_REPORTED__ACTION__REMOVE, @@ -95,20 +83,14 @@ class CommunalMetricsLoggerTest : SysuiTestCase() { @Test fun logTapWidget_componentNotLoggable_doNotLog() { - underTest.logTapWidget( - componentName = "com.yellow.package/my_test_widget", - rank = 2, - ) + underTest.logTapWidget(componentName = "com.yellow.package/my_test_widget", rank = 2) verify(statsLogProxy, never()) - .writeCommunalHubWidgetEventReported(anyInt(), any(), anyInt()) + .writeCommunalHubWidgetEventReported(anyInt(), any(), anyInt(), anyInt()) } @Test fun logTapWidget_componentLoggable_logRemoveEvent() { - underTest.logTapWidget( - componentName = "com.red.package/my_test_widget", - rank = 2, - ) + underTest.logTapWidget(componentName = "com.red.package/my_test_widget", rank = 2) verify(statsLogProxy) .writeCommunalHubWidgetEventReported( SysUiStatsLog.COMMUNAL_HUB_WIDGET_EVENT_REPORTED__ACTION__TAP, @@ -140,4 +122,43 @@ class CommunalMetricsLoggerTest : SysuiTestCase() { ) assertThat(statsEvents).hasSize(1) } + + @Test + fun logResizeWidget_componentNotLoggable_doNotLog() { + underTest.logResizeWidget( + componentName = "com.green.package/my_test_widget", + rank = 1, + spanY = 2, + ) + verify(statsLogProxy, never()) + .writeCommunalHubWidgetEventReported(anyInt(), any(), anyInt(), anyInt()) + } + + @Test + fun logResizeWidget_componentLoggable_logResizeEvent() { + underTest.logResizeWidget( + componentName = "com.blue.package/my_test_widget", + rank = 1, + spanY = 2, + ) + verify(statsLogProxy) + .writeCommunalHubWidgetEventReported( + SysUiStatsLog.COMMUNAL_HUB_WIDGET_EVENT_REPORTED__ACTION__RESIZE, + "com.blue.package/my_test_widget", + rank = 1, + spanY = 2, + ) + } + + @Test + fun logResizeWidget_defaultSpanY_usesDefaultValue() { + underTest.logResizeWidget(componentName = "com.blue.package/my_test_widget", rank = 1) + verify(statsLogProxy) + .writeCommunalHubWidgetEventReported( + SysUiStatsLog.COMMUNAL_HUB_WIDGET_EVENT_REPORTED__ACTION__RESIZE, + "com.blue.package/my_test_widget", + rank = 1, + spanY = 0, + ) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt index cecc11e5ffd4..6b851cb017e1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt @@ -353,6 +353,32 @@ class CommunalEditModeViewModelTest : SysuiTestCase() { assertThat(event.contentDescription).isEqualTo("Test Clock widget added to lock screen") } + @Test + fun onResizeWidget_logsMetrics() = + testScope.runTest { + val appWidgetId = 123 + val spanY = 2 + val widgetIdToRankMap = mapOf(appWidgetId to 1) + val componentName = ComponentName("test.package", "TestWidget") + val rank = 1 + + underTest.onResizeWidget( + appWidgetId = appWidgetId, + spanY = spanY, + widgetIdToRankMap = widgetIdToRankMap, + componentName = componentName, + rank = rank, + ) + + verify(communalInteractor).resizeWidget(appWidgetId, spanY, widgetIdToRankMap) + verify(metricsLogger) + .logResizeWidget( + componentName = componentName.flattenToString(), + rank = rank, + spanY = spanY, + ) + } + private companion object { val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN) const val WIDGET_PICKER_PACKAGE_NAME = "widget_picker_package_name" diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryImplTest.kt index da7a723f220e..da7a723f220e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryImplTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/doze/DozeMachineTest.java index eb72f29046aa..334718049830 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/doze/DozeMachineTest.java @@ -48,10 +48,10 @@ import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.content.res.Configuration; import android.hardware.display.AmbientDisplayConfiguration; -import androidx.test.annotation.UiThreadTest; import android.view.Display; import androidx.annotation.NonNull; +import androidx.test.annotation.UiThreadTest; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt new file mode 100644 index 000000000000..aacfaed1ab4a --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:OptIn(ExperimentalCoroutinesApi::class) + +package com.android.systemui.dreams.ui.viewmodel + +import android.platform.test.annotations.DisableFlags +import android.platform.test.annotations.EnableFlags +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.compose.animation.scene.Swipe +import com.android.compose.animation.scene.UserActionResult +import com.android.systemui.SysuiTestCase +import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository +import com.android.systemui.authentication.shared.model.AuthenticationMethodModel +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor +import com.android.systemui.flags.EnableSceneContainer +import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository +import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus +import com.android.systemui.kosmos.testScope +import com.android.systemui.lifecycle.activateIn +import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest +import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest +import com.android.systemui.power.domain.interactor.powerInteractor +import com.android.systemui.scene.domain.interactor.sceneInteractor +import com.android.systemui.scene.shared.model.Overlays +import com.android.systemui.scene.shared.model.SceneFamilies +import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade +import com.android.systemui.shade.data.repository.fakeShadeRepository +import com.android.systemui.shade.shared.flag.DualShade +import com.android.systemui.shade.shared.model.ShadeMode +import com.android.systemui.testKosmos +import com.google.common.truth.Truth.assertThat +import kotlin.test.Test +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidJUnit4::class) +@EnableSceneContainer +class DreamUserActionsViewModelTest : SysuiTestCase() { + + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + + private lateinit var underTest: DreamUserActionsViewModel + + @Before + fun setUp() { + underTest = kosmos.dreamUserActionsViewModel + underTest.activateIn(testScope) + } + + @Test + @DisableFlags(DualShade.FLAG_NAME) + fun actions_singleShade() = + testScope.runTest { + val actions by collectLastValue(underTest.actions) + + setUpState( + isShadeTouchable = true, + isDeviceUnlocked = false, + shadeMode = ShadeMode.Single, + ) + assertThat(actions).isNotEmpty() + assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home)) + assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer)) + assertThat(actions?.get(Swipe.Down)) + .isEqualTo(UserActionResult(Scenes.Shade, isIrreversible = true)) + + setUpState( + isShadeTouchable = false, + isDeviceUnlocked = false, + shadeMode = ShadeMode.Single, + ) + assertThat(actions).isEmpty() + + setUpState( + isShadeTouchable = true, + isDeviceUnlocked = true, + shadeMode = ShadeMode.Single, + ) + assertThat(actions).isNotEmpty() + assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home)) + assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone)) + assertThat(actions?.get(Swipe.Down)) + .isEqualTo(UserActionResult(Scenes.Shade, isIrreversible = true)) + } + + @Test + @DisableFlags(DualShade.FLAG_NAME) + fun actions_splitShade() = + testScope.runTest { + val actions by collectLastValue(underTest.actions) + + setUpState( + isShadeTouchable = true, + isDeviceUnlocked = false, + shadeMode = ShadeMode.Split, + ) + assertThat(actions).isNotEmpty() + assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home)) + assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer)) + assertThat(actions?.get(Swipe.Down)) + .isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade, isIrreversible = true)) + + setUpState( + isShadeTouchable = false, + isDeviceUnlocked = false, + shadeMode = ShadeMode.Split, + ) + assertThat(actions).isEmpty() + + setUpState( + isShadeTouchable = true, + isDeviceUnlocked = true, + shadeMode = ShadeMode.Split, + ) + assertThat(actions).isNotEmpty() + assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home)) + assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone)) + assertThat(actions?.get(Swipe.Down)) + .isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade, isIrreversible = true)) + } + + @Test + @EnableFlags(DualShade.FLAG_NAME) + fun actions_dualShade() = + testScope.runTest { + val actions by collectLastValue(underTest.actions) + + setUpState( + isShadeTouchable = true, + isDeviceUnlocked = false, + shadeMode = ShadeMode.Dual, + ) + assertThat(actions).isNotEmpty() + assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home)) + assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer)) + assertThat(actions?.get(Swipe.Down)) + .isEqualTo( + UserActionResult.ShowOverlay(Overlays.NotificationsShade, isIrreversible = true) + ) + + setUpState( + isShadeTouchable = false, + isDeviceUnlocked = false, + shadeMode = ShadeMode.Dual, + ) + assertThat(actions).isEmpty() + + setUpState(isShadeTouchable = true, isDeviceUnlocked = true, shadeMode = ShadeMode.Dual) + assertThat(actions).isNotEmpty() + assertThat(actions?.get(Swipe.End)).isEqualTo(UserActionResult(SceneFamilies.Home)) + assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone)) + assertThat(actions?.get(Swipe.Down)) + .isEqualTo( + UserActionResult.ShowOverlay(Overlays.NotificationsShade, isIrreversible = true) + ) + } + + private fun TestScope.setUpState( + isShadeTouchable: Boolean, + isDeviceUnlocked: Boolean, + shadeMode: ShadeMode, + ) { + if (isShadeTouchable) { + kosmos.powerInteractor.setAwakeForTest() + } else { + kosmos.powerInteractor.setAsleepForTest() + } + + if (isDeviceUnlocked) { + unlockDevice() + } else { + lockDevice() + } + + if (shadeMode == ShadeMode.Dual) { + assertThat(DualShade.isEnabled).isTrue() + } else { + assertThat(DualShade.isEnabled).isFalse() + kosmos.fakeShadeRepository.setShadeLayoutWide(shadeMode == ShadeMode.Split) + } + runCurrent() + } + + private fun TestScope.lockDevice() { + val deviceUnlockStatus by + collectLastValue(kosmos.deviceUnlockedInteractor.deviceUnlockStatus) + + kosmos.fakeAuthenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) + assertThat(deviceUnlockStatus?.isUnlocked).isFalse() + kosmos.sceneInteractor.changeScene(Scenes.Lockscreen, "reason") + runCurrent() + } + + private fun TestScope.unlockDevice() { + val deviceUnlockStatus by + collectLastValue(kosmos.deviceUnlockedInteractor.deviceUnlockStatus) + + kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( + SuccessFingerprintAuthenticationStatus(0, true) + ) + assertThat(deviceUnlockStatus?.isUnlocked).isTrue() + kosmos.sceneInteractor.changeScene(Scenes.Gone, "reason") + runCurrent() + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/msdl/qs/TileHapticsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/msdl/qs/TileHapticsViewModelTest.kt index 5efb6171cdde..f6a6e5465e1b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/msdl/qs/TileHapticsViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/msdl/qs/TileHapticsViewModelTest.kt @@ -119,22 +119,6 @@ class TileHapticsViewModelTest : SysuiTestCase() { } @Test - fun onLongClick_whenTileDoesNotHandleLongClick_playsFailureHaptics() = - testScope.runTest { - // WHEN the tile is long-clicked but the tile does not handle a long-click - val state = QSTile.State().apply { handlesLongClick = false } - qsTile.changeState(state) - underTest.setTileInteractionState( - TileHapticsViewModel.TileInteractionState.LONG_CLICKED - ) - runCurrent() - - // THEN the failure token plays - assertThat(msdlPlayer.latestTokenPlayed).isEqualTo(MSDLToken.FAILURE) - assertThat(msdlPlayer.latestPropertiesPlayed).isNull() - } - - @Test fun whenLaunchingFromClick_doesNotPlayHaptics() = testScope.runTest { // WHEN the tile is clicked and its action state changes accordingly diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt index 5df9b7b8d5b8..2efa2f34e394 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt @@ -85,63 +85,62 @@ class TutorialSchedulerInteractorTest : SysuiTestCase() { @Test fun connectKeyboard_delayElapse_launchForKeyboard() = testScope.runTest { - launchAndAssert(TutorialType.KEYBOARD) - keyboardRepository.setIsAnyKeyboardConnected(true) advanceTimeBy(LAUNCH_DELAY) + + launchAndAssert(TutorialType.KEYBOARD) } @Test fun connectBothDevices_delayElapse_launchForBoth() = testScope.runTest { - launchAndAssert(TutorialType.BOTH) - keyboardRepository.setIsAnyKeyboardConnected(true) touchpadRepository.setIsAnyTouchpadConnected(true) advanceTimeBy(LAUNCH_DELAY) + + launchAndAssert(TutorialType.BOTH) } @Test fun connectBothDevice_delayNotElapse_launchNothing() = testScope.runTest { - launchAndAssert(TutorialType.NONE) - keyboardRepository.setIsAnyKeyboardConnected(true) touchpadRepository.setIsAnyTouchpadConnected(true) advanceTimeBy(A_SHORT_PERIOD_OF_TIME) + + launchAndAssert(TutorialType.NONE) } @Test fun nothingConnect_delayElapse_launchNothing() = testScope.runTest { - launchAndAssert(TutorialType.NONE) - keyboardRepository.setIsAnyKeyboardConnected(false) touchpadRepository.setIsAnyTouchpadConnected(false) advanceTimeBy(LAUNCH_DELAY) + + launchAndAssert(TutorialType.NONE) } @Test fun connectKeyboard_thenTouchpad_delayElapse_launchForBoth() = testScope.runTest { - launchAndAssert(TutorialType.BOTH) - keyboardRepository.setIsAnyKeyboardConnected(true) advanceTimeBy(A_SHORT_PERIOD_OF_TIME) touchpadRepository.setIsAnyTouchpadConnected(true) advanceTimeBy(REMAINING_TIME) + + launchAndAssert(TutorialType.BOTH) } @Test fun connectKeyboard_thenTouchpad_removeKeyboard_delayElapse_launchNothing() = testScope.runTest { - launchAndAssert(TutorialType.NONE) - keyboardRepository.setIsAnyKeyboardConnected(true) advanceTimeBy(A_SHORT_PERIOD_OF_TIME) touchpadRepository.setIsAnyTouchpadConnected(true) keyboardRepository.setIsAnyKeyboardConnected(false) advanceTimeBy(REMAINING_TIME) + launchAndAssert(TutorialType.NONE) } private suspend fun launchAndAssert(expectedTutorial: TutorialType) = diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt index 8b1341114c68..8b1341114c68 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt index c646d8f11706..cc4c7c419a11 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt @@ -218,11 +218,11 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() { simpleShortcutCategory(System, "System controls", "View recent apps"), simpleShortcutCategory(AppCategories, "Applications", "Calculator"), simpleShortcutCategory(AppCategories, "Applications", "Calendar"), - simpleShortcutCategory(AppCategories, "Applications", "Chrome"), + simpleShortcutCategory(AppCategories, "Applications", "Browser"), simpleShortcutCategory(AppCategories, "Applications", "Contacts"), - simpleShortcutCategory(AppCategories, "Applications", "Gmail"), + simpleShortcutCategory(AppCategories, "Applications", "Email"), simpleShortcutCategory(AppCategories, "Applications", "Maps"), - simpleShortcutCategory(AppCategories, "Applications", "Messages"), + simpleShortcutCategory(AppCategories, "Applications", "SMS"), simpleShortcutCategory(MultiTasking, "Recent apps", "Cycle forward through recent apps"), ) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java index cad22d360508..cad22d360508 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/WorkLockActivityControllerTest.java diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepositoryImplTest.kt index 5a597fe8e920..f537e32ac13d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepositoryImplTest.kt @@ -50,7 +50,6 @@ class KeyguardSmartspaceRepositoryImplTest : SysuiTestCase() { fakeSettings.userId = fakeUserTracker.userId underTest = KeyguardSmartspaceRepositoryImpl( - context = context, secureSettings = fakeSettings, userTracker = fakeUserTracker, applicationScope = scope.backgroundScope, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt index 3d5498b61471..7a3089f33276 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt @@ -527,6 +527,29 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() { assertEquals(0, steps.size) } + @Test + fun testForceFinishCurrentTransition_noTransitionRunning_unlocksMutex() = + testScope.runTest { + val steps by collectValues(underTest.transitions.dropWhile { step -> step.from == OFF }) + underTest.forceFinishCurrentTransition() + + assertThat(steps.isEmpty()) + + underTest.forceFinishCurrentTransition() + runCurrent() + + assertThat(steps.isEmpty()) + runner.startTransition( + this, + TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, getAnimator()), + maxFrames = 100, + ) + + advanceTimeBy(5000L) + + assertThat(steps.isNotEmpty()) + } + private fun listWithStep( step: BigDecimal, start: BigDecimal = BigDecimal.ZERO, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt index aee72de22a24..28ac169e2bbe 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt @@ -310,7 +310,7 @@ class KeyguardTouchHandlingInteractorTest : SysuiTestCase() { // read during initialization to set up flows. Maybe there is a better way to handle that. underTest = KeyguardTouchHandlingInteractor( - appContext = mContext, + context = mContext, scope = testScope.backgroundScope, transitionInteractor = kosmos.keyguardTransitionInteractor, repository = keyguardRepository, diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaTimeoutListenerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaTimeoutListenerTest.kt index 51c852531697..51c852531697 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaTimeoutListenerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/MediaTimeoutListenerTest.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/power/PowerUITest.java index 338ed7596bd6..338ed7596bd6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/power/PowerUITest.java diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSFooterViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSFooterViewControllerTest.java index 93dede5a3dae..f1f6c61a16e4 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSFooterViewControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSFooterViewControllerTest.java @@ -38,7 +38,7 @@ import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.res.R; import com.android.systemui.retail.data.repository.FakeRetailModeRepository; -import com.android.systemui.retail.domain.interactor.RetailModeInteractorImpl; +import com.android.systemui.retail.domain.interactor.impl.RetailModeInteractorImpl; import com.android.systemui.settings.UserTracker; import com.android.systemui.utils.leaks.LeakCheckedTest; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSSecurityFooterTest.java index f6d57325bb1c..f6d57325bb1c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/QSSecurityFooterTest.java diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt index 03feceb7c15a..b72668bf5be6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt @@ -18,6 +18,7 @@ package com.android.systemui.qs.composefragment.viewmodel import android.app.StatusBarManager import android.content.testableContext +import android.graphics.Rect import android.testing.TestableLooper.RunWithLooper import androidx.compose.runtime.snapshots.Snapshot import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -43,6 +44,7 @@ import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository import com.android.systemui.statusbar.sysuiStatusBarStateController +import com.android.systemui.util.animation.DisappearParameters import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope @@ -375,6 +377,92 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest() } } + @Test + fun applyQsScrollPositionForClipping() = + with(kosmos) { + testScope.testWithinLifecycle { + val left = 1f + val top = 3f + val right = 5f + val bottom = 7f + + underTest.applyNewQsScrollerBounds(left, top, right, bottom) + + assertThat(qsMediaHost.currentClipping) + .isEqualTo(Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())) + } + } + + @Test + fun shouldUpdateMediaSquishiness_inSplitShadeFalse_mediaSquishinessSet() = + with(kosmos) { + testScope.testWithinLifecycle { + underTest.isInSplitShade = false + underTest.squishinessFraction = 0.3f + + underTest.shouldUpdateSquishinessOnMedia = true + Snapshot.sendApplyNotifications() + runCurrent() + + assertThat(underTest.qsMediaHost.squishFraction).isWithin(0.01f).of(0.3f) + + underTest.shouldUpdateSquishinessOnMedia = false + Snapshot.sendApplyNotifications() + runCurrent() + assertThat(underTest.qsMediaHost.squishFraction).isWithin(0.01f).of(1f) + } + } + + @Test + fun inSplitShade_differentStatusBarState_mediaSquishinessSet() = + with(kosmos) { + testScope.testWithinLifecycle { + underTest.isInSplitShade = true + underTest.squishinessFraction = 0.3f + + sysuiStatusBarStateController.setState(StatusBarState.SHADE) + Snapshot.sendApplyNotifications() + runCurrent() + assertThat(underTest.qsMediaHost.squishFraction).isWithin(epsilon).of(0.3f) + + sysuiStatusBarStateController.setState(StatusBarState.KEYGUARD) + runCurrent() + Snapshot.sendApplyNotifications() + runCurrent() + assertThat(underTest.qsMediaHost.squishFraction).isWithin(epsilon).of(1f) + + sysuiStatusBarStateController.setState(StatusBarState.SHADE_LOCKED) + runCurrent() + Snapshot.sendApplyNotifications() + runCurrent() + assertThat(underTest.qsMediaHost.squishFraction).isWithin(epsilon).of(1f) + } + } + + @Test + fun disappearParams() = + with(kosmos) { + testScope.testWithinLifecycle { + setMediaState(ACTIVE_MEDIA) + + setConfigurationForMediaInRow(false) + Snapshot.sendApplyNotifications() + runCurrent() + + assertThat(underTest.qqsMediaHost.disappearParameters) + .isEqualTo(disappearParamsColumn) + assertThat(underTest.qsMediaHost.disappearParameters) + .isEqualTo(disappearParamsColumn) + + setConfigurationForMediaInRow(true) + Snapshot.sendApplyNotifications() + runCurrent() + + assertThat(underTest.qqsMediaHost.disappearParameters).isEqualTo(disappearParamsRow) + assertThat(underTest.qsMediaHost.disappearParameters).isEqualTo(disappearParamsRow) + } + } + private fun TestScope.setMediaState(state: MediaState) { with(kosmos) { val activeMedia = state == ACTIVE_MEDIA @@ -404,6 +492,26 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest() } private const val epsilon = 0.001f + + private val disappearParamsColumn = + DisappearParameters().apply { + fadeStartPosition = 0.95f + disappearStart = 0f + disappearEnd = 0.95f + disappearSize.set(1f, 0f) + gonePivot.set(0f, 0f) + contentTranslationFraction.set(0f, 1f) + } + + private val disappearParamsRow = + DisappearParameters().apply { + fadeStartPosition = 0.95f + disappearStart = 0f + disappearEnd = 0.6f + disappearSize.set(0f, 0.4f) + gonePivot.set(1f, 0f) + contentTranslationFraction.set(0.25f, 1f) + } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest_311121830.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest_311121830.kt index 6fce108f35a1..ee2a1d56937b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest_311121830.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest_311121830.kt @@ -19,10 +19,10 @@ package com.android.systemui.qs.tileimpl import android.animation.AnimatorTestRule import android.content.Context import android.service.quicksettings.Tile -import android.testing.AndroidTestingRunner import android.view.ContextThemeWrapper import android.view.View import android.widget.ImageView +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.annotation.UiThreadTest import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase @@ -35,7 +35,7 @@ import org.junit.Rule import org.junit.runner.RunWith /** Test for regression b/311121830 and b/323125376 */ -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) @UiThreadTest @SmallTest class QSIconViewImplTest_311121830 : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java index 296478be77e0..296478be77e0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt index 991f78a3147c..991f78a3147c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/retail/data/repository/RetailModeSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/retail/data/repository/RetailModeSettingsRepositoryTest.kt index ba7a65dd8e65..47bfda41c7ad 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/retail/data/repository/RetailModeSettingsRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/retail/data/repository/RetailModeSettingsRepositoryTest.kt @@ -21,6 +21,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.retail.data.repository.impl.RetailModeSettingsRepository import com.android.systemui.util.settings.FakeGlobalSettings import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/retail/domain/interactor/RetailModeInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/retail/domain/interactor/RetailModeInteractorImplTest.kt index b53652067755..b47dcb567135 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/retail/domain/interactor/RetailModeInteractorImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/retail/domain/interactor/RetailModeInteractorImplTest.kt @@ -20,6 +20,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.retail.data.repository.FakeRetailModeRepository +import com.android.systemui.retail.domain.interactor.impl.RetailModeInteractorImpl import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt index 152911a30524..af0274b1caaa 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt @@ -44,6 +44,7 @@ import com.android.systemui.biometrics.data.repository.fingerprintPropertyReposi import com.android.systemui.biometrics.shared.model.FingerprintSensorType import com.android.systemui.biometrics.shared.model.SensorStrength import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository +import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor import com.android.systemui.bouncer.domain.interactor.bouncerInteractor import com.android.systemui.bouncer.shared.logging.BouncerUiEvent import com.android.systemui.classifier.FalsingCollector @@ -54,6 +55,7 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository import com.android.systemui.deviceentry.domain.interactor.deviceEntryHapticsInteractor import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor +import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.deviceentry.shared.model.FailedFaceAuthenticationStatus import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus import com.android.systemui.flags.EnableSceneContainer @@ -114,6 +116,7 @@ import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runCurrent @@ -2356,6 +2359,58 @@ class SceneContainerStartableTest : SysuiTestCase() { assertThat(isLockscreenEnabled).isTrue() } + @Test + fun replacesLockscreenSceneOnBackStack_whenUnlockdViaAlternateBouncer_fromShade() = + testScope.runTest { + val transitionState = + prepareState( + isDeviceUnlocked = false, + initialSceneKey = Scenes.Lockscreen, + authenticationMethod = AuthenticationMethodModel.Pin, + ) + underTest.start() + + val isUnlocked by + collectLastValue( + kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked } + ) + val currentScene by collectLastValue(sceneInteractor.currentScene) + val backStack by collectLastValue(sceneBackInteractor.backStack) + val isAlternateBouncerVisible by + collectLastValue(kosmos.alternateBouncerInteractor.isVisible) + assertThat(isUnlocked).isFalse() + assertThat(currentScene).isEqualTo(Scenes.Lockscreen) + assertThat(isAlternateBouncerVisible).isFalse() + + // Change to shade. + sceneInteractor.changeScene(Scenes.Shade, "") + transitionState.value = ObservableTransitionState.Idle(Scenes.Shade) + runCurrent() + assertThat(isUnlocked).isFalse() + assertThat(currentScene).isEqualTo(Scenes.Shade) + assertThat(backStack?.asIterable()?.first()).isEqualTo(Scenes.Lockscreen) + assertThat(isAlternateBouncerVisible).isFalse() + + // Show the alternate bouncer. + kosmos.alternateBouncerInteractor.forceShow() + kosmos.sysuiStatusBarStateController.leaveOpen = true // leave shade open + runCurrent() + assertThat(isUnlocked).isFalse() + assertThat(currentScene).isEqualTo(Scenes.Shade) + assertThat(backStack?.asIterable()?.first()).isEqualTo(Scenes.Lockscreen) + assertThat(isAlternateBouncerVisible).isTrue() + + // Trigger a fingerprint unlock. + kosmos.deviceEntryFingerprintAuthRepository.setAuthenticationStatus( + SuccessFingerprintAuthenticationStatus(0, true) + ) + runCurrent() + assertThat(isUnlocked).isTrue() + assertThat(currentScene).isEqualTo(Scenes.Shade) + assertThat(backStack?.asIterable()?.first()).isEqualTo(Scenes.Gone) + assertThat(isAlternateBouncerVisible).isFalse() + } + private fun TestScope.emulateSceneTransition( transitionStateFlow: MutableStateFlow<ObservableTransitionState>, toScene: SceneKey, diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionExecutorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ActionExecutorTest.kt index a10d81f86d8e..1413204f7fed 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionExecutorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ActionExecutorTest.kt @@ -20,8 +20,8 @@ import android.app.PendingIntent import android.content.Intent import android.os.Bundle import android.os.UserHandle -import android.testing.AndroidTestingRunner import android.view.Window +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.util.mockito.argumentCaptor @@ -39,7 +39,7 @@ import org.mockito.kotlin.eq import org.mockito.kotlin.verify import org.mockito.kotlin.verifyBlocking -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) @SmallTest class ActionExecutorTest : SysuiTestCase() { private val scheduler = TestCoroutineScheduler() diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt index c50702868025..84b7d10c42a4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt @@ -21,10 +21,10 @@ import android.content.pm.ActivityInfo import android.content.pm.PackageManager import android.content.pm.PackageManager.MATCH_ANY_USER import android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS -import android.testing.AndroidTestingRunner import android.view.Display import android.view.IWindowManager import android.view.WindowManager +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.argThat @@ -43,7 +43,7 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) class ScreenshotDetectionControllerTest { @Mock lateinit var windowManager: IWindowManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt index 77b5c9115295..d2eca0d95a30 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt @@ -23,9 +23,9 @@ import android.content.ComponentName import android.net.Uri import android.os.UserHandle import android.os.UserManager -import android.testing.AndroidTestingRunner import android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_OTHER import android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN +import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.internal.logging.testing.UiEventLoggerFake import com.android.internal.util.ScreenshotRequest import com.android.systemui.SysuiTestCase @@ -49,7 +49,7 @@ import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.whenever -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) class TakeScreenshotServiceTest : SysuiTestCase() { private val userManager = mock<UserManager> { on { isUserUnlocked } doReturn (true) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt index 0ab4cd05fea7..0ab4cd05fea7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java index 9a8df33a0276..cd55bb23c1fc 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java @@ -38,11 +38,11 @@ import android.content.Context; import android.content.Intent; import android.os.Handler; import android.provider.Settings; -import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; import android.widget.TextView; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.keyguard.CarrierTextManager; @@ -76,7 +76,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) @TestableLooper.RunWithLooper @SmallTest public class ShadeCarrierGroupControllerTest extends LeakCheckedTest { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt new file mode 100644 index 000000000000..f192b59cb9e4 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.shade.domain.interactor + +import android.content.Context +import android.content.res.Configuration +import android.content.res.Resources +import android.view.Display +import android.view.WindowManager +import android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.display.data.repository.FakeDisplayWindowPropertiesRepository +import com.android.systemui.display.shared.model.DisplayWindowProperties +import com.android.systemui.scene.ui.view.WindowRootView +import com.android.systemui.shade.data.repository.FakeShadePositionRepository +import com.android.systemui.statusbar.phone.ConfigurationForwarder +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.advanceUntilIdle +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.verify +import org.mockito.kotlin.any +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock +import org.mockito.kotlin.verifyNoMoreInteractions +import org.mockito.kotlin.whenever + +@OptIn(ExperimentalCoroutinesApi::class) +@RunWith(AndroidJUnit4::class) +@SmallTest +class ShadeDisplaysInteractorTest : SysuiTestCase() { + + private val shadeRootview = mock<WindowRootView>() + private val positionRepository = FakeShadePositionRepository() + private val defaultContext = mock<Context>() + private val secondaryContext = mock<Context>() + private val contextStore = FakeDisplayWindowPropertiesRepository() + private val testScope = TestScope(UnconfinedTestDispatcher()) + private val configurationForwarder = mock<ConfigurationForwarder>() + private val defaultWm = mock<WindowManager>() + private val secondaryWm = mock<WindowManager>() + private val resources = mock<Resources>() + private val configuration = mock<Configuration>() + private val display = mock<Display>() + + private val interactor = + ShadeDisplaysInteractor( + shadeRootview, + positionRepository, + defaultContext, + contextStore, + testScope, + configurationForwarder, + testScope.coroutineContext, + ) + + @Before + fun setup() { + whenever(shadeRootview.display).thenReturn(display) + whenever(display.displayId).thenReturn(0) + + whenever(resources.configuration).thenReturn(configuration) + whenever(resources.configuration).thenReturn(configuration) + + whenever(defaultContext.displayId).thenReturn(0) + whenever(defaultContext.getSystemService(any())).thenReturn(defaultWm) + whenever(defaultContext.resources).thenReturn(resources) + contextStore.insert( + DisplayWindowProperties( + displayId = 0, + windowType = TYPE_NOTIFICATION_SHADE, + context = defaultContext, + windowManager = defaultWm, + layoutInflater = mock(), + ) + ) + + whenever(secondaryContext.displayId).thenReturn(1) + whenever(secondaryContext.getSystemService(any())).thenReturn(secondaryWm) + whenever(secondaryContext.resources).thenReturn(resources) + contextStore.insert( + DisplayWindowProperties( + displayId = 1, + windowType = TYPE_NOTIFICATION_SHADE, + context = secondaryContext, + windowManager = secondaryWm, + layoutInflater = mock(), + ) + ) + } + + @Test + fun start_shadeInCorrectPosition_notAddedOrRemoved() { + whenever(display.displayId).thenReturn(0) + positionRepository.setDisplayId(0) + interactor.start() + testScope.advanceUntilIdle() + + verifyNoMoreInteractions(defaultWm) + verifyNoMoreInteractions(secondaryWm) + } + + @Test + fun start_shadeInWrongPosition_changes() { + whenever(display.displayId).thenReturn(0) + positionRepository.setDisplayId(1) + interactor.start() + testScope.advanceUntilIdle() + + verify(defaultWm).removeView(eq(shadeRootview)) + verify(secondaryWm).addView(eq(shadeRootview), any()) + } + + @Test + fun start_shadePositionChanges_removedThenAdded() { + whenever(display.displayId).thenReturn(0) + positionRepository.setDisplayId(0) + interactor.start() + testScope.advanceUntilIdle() + + positionRepository.setDisplayId(1) + testScope.advanceUntilIdle() + + verify(defaultWm).removeView(eq(shadeRootview)) + verify(secondaryWm).addView(eq(shadeRootview), any()) + } + + @Test + fun start_shadePositionChanges_newConfigPropagated() { + whenever(display.displayId).thenReturn(0) + positionRepository.setDisplayId(0) + interactor.start() + testScope.advanceUntilIdle() + + positionRepository.setDisplayId(1) + testScope.advanceUntilIdle() + + verify(configurationForwarder).onConfigurationChanged(eq(configuration)) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/CommandQueueTest.java index b730b3703515..b730b3703515 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/CommandQueueTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java index 5fce08b08137..5fce08b08137 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/connectivity/CallbackHandlerTest.java diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java index c8ef663a4f81..e974c2e70f68 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/PropertyAnimatorTest.java @@ -30,13 +30,13 @@ import static org.mockito.Mockito.verify; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; -import android.testing.AndroidTestingRunner; import android.util.FloatProperty; import android.util.Property; import android.view.View; import android.view.animation.Interpolator; import androidx.test.annotation.UiThreadTest; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.app.animation.Interpolators; @@ -51,7 +51,7 @@ import org.junit.Test; import org.junit.runner.RunWith; @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) @UiThreadTest public class PropertyAnimatorTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java index e21a005b8ada..4ef9792a2ad9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java @@ -68,12 +68,12 @@ import android.platform.test.annotations.EnableFlags; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.StatusBarNotification; -import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.ArrayMap; import android.util.ArraySet; import androidx.annotation.NonNull; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.internal.statusbar.IStatusBarService; @@ -118,7 +118,7 @@ import java.util.List; import java.util.Map; @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) @TestableLooper.RunWithLooper public class NotifCollectionTest extends SysuiTestCase { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt index 9613f76c2b48..2c488e3a7242 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt @@ -28,7 +28,6 @@ import com.android.systemui.log.logcatLogBuffer import com.android.systemui.statusbar.NotificationRemoteInputManager import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips -import com.android.systemui.statusbar.notification.HeadsUpManagerPhone import com.android.systemui.statusbar.notification.NotifPipelineFlags import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder import com.android.systemui.statusbar.notification.collection.NotifPipeline @@ -52,6 +51,7 @@ import com.android.systemui.statusbar.notification.interruption.NotificationInte import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback import com.android.systemui.statusbar.phone.NotificationGroupTestHelper +import com.android.systemui.statusbar.policy.BaseHeadsUpManager import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener import com.android.systemui.testKosmos import com.android.systemui.util.concurrency.FakeExecutor @@ -101,7 +101,7 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { private val notifPipeline: NotifPipeline = mock() private val logger = HeadsUpCoordinatorLogger(logcatLogBuffer(), verbose = true) - private val headsUpManager: HeadsUpManagerPhone = mock() + private val headsUpManager: BaseHeadsUpManager = mock() private val headsUpViewBinder: HeadsUpViewBinder = mock() private val visualInterruptionDecisionProvider: VisualInterruptionDecisionProvider = mock() private val remoteInputManager: NotificationRemoteInputManager = mock() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt index ca75ca679c31..a70d24efada7 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt @@ -28,43 +28,41 @@ import com.android.systemui.statusbar.notification.collection.ShadeListBuilder import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderGroupListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener -import com.android.systemui.util.mockito.any -import com.android.systemui.util.mockito.mock -import com.android.systemui.util.mockito.withArgCaptor import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.Mockito.inOrder -import org.mockito.Mockito.never -import org.mockito.Mockito.spy -import org.mockito.Mockito.times -import org.mockito.Mockito.verify -import org.mockito.Mockito.verifyNoMoreInteractions -import org.mockito.MockitoAnnotations +import org.mockito.kotlin.any +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.inOrder +import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.spy +import org.mockito.kotlin.times +import org.mockito.kotlin.verify +import org.mockito.kotlin.verifyNoMoreInteractions @SmallTest @RunWith(AndroidJUnit4::class) class RenderStageManagerTest : SysuiTestCase() { - @Mock private lateinit var shadeListBuilder: ShadeListBuilder - @Mock private lateinit var onAfterRenderListListener: OnAfterRenderListListener - @Mock private lateinit var onAfterRenderGroupListener: OnAfterRenderGroupListener - @Mock private lateinit var onAfterRenderEntryListener: OnAfterRenderEntryListener + private val shadeListBuilder: ShadeListBuilder = mock() + private val onAfterRenderListListener: OnAfterRenderListListener = mock() + private val onAfterRenderGroupListener: OnAfterRenderGroupListener = mock() + private val onAfterRenderEntryListener: OnAfterRenderEntryListener = mock() + private val spyViewRenderer = spy(FakeNotifViewRenderer()) private lateinit var onRenderListListener: ShadeListBuilder.OnRenderListListener + private lateinit var renderStageManager: RenderStageManager - private val spyViewRenderer = spy(FakeNotifViewRenderer()) @Before fun setUp() { - MockitoAnnotations.initMocks(this) - renderStageManager = RenderStageManager() renderStageManager.attach(shadeListBuilder) - onRenderListListener = withArgCaptor { - verify(shadeListBuilder).setOnRenderListListener(capture()) - } + + val captor = argumentCaptor<ShadeListBuilder.OnRenderListListener>() + verify(shadeListBuilder).setOnRenderListListener(captor.capture()) + onRenderListListener = captor.lastValue } private fun setUpRenderer() { @@ -89,7 +87,7 @@ class RenderStageManagerTest : SysuiTestCase() { verifyNoMoreInteractions( onAfterRenderListListener, onAfterRenderGroupListener, - onAfterRenderEntryListener + onAfterRenderEntryListener, ) } @@ -171,7 +169,7 @@ class RenderStageManagerTest : SysuiTestCase() { verifyNoMoreInteractions( onAfterRenderListListener, onAfterRenderGroupListener, - onAfterRenderEntryListener + onAfterRenderEntryListener, ) } @@ -191,30 +189,27 @@ class RenderStageManagerTest : SysuiTestCase() { verifyNoMoreInteractions( onAfterRenderListListener, onAfterRenderGroupListener, - onAfterRenderEntryListener + onAfterRenderEntryListener, ) } - private fun listWith2Groups8Entries() = listOf( - group( - notif(1), - notif(2), - notif(3) - ), - notif(4), - group( - notif(5), - notif(6), - notif(7) - ), - notif(8) - ) + private fun listWith2Groups8Entries() = + listOf( + group(notif(1), notif(2), notif(3)), + notif(4), + group(notif(5), notif(6), notif(7)), + notif(8), + ) private class FakeNotifViewRenderer : NotifViewRenderer { override fun onRenderList(notifList: List<ListEntry>) {} + override fun getStackController(): NotifStackController = mock() + override fun getGroupController(group: GroupEntry): NotifGroupController = mock() + override fun getRowController(entry: NotificationEntry): NotifRowController = mock() + override fun onDispatchComplete() {} } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifLayoutInflaterFactoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifLayoutInflaterFactoryTest.kt index fd4192151c57..371e1c569cef 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifLayoutInflaterFactoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotifLayoutInflaterFactoryTest.kt @@ -16,13 +16,13 @@ package com.android.systemui.statusbar.notification.row import android.content.Context -import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.util.AttributeSet import android.view.View import android.widget.Button import android.widget.FrameLayout import android.widget.LinearLayout +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED @@ -38,7 +38,7 @@ import org.mockito.Mockito.verify /** Tests for [NotifLayoutInflaterFactory] */ @SmallTest -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) @RunWithLooper class NotifLayoutInflaterFactoryTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java index 3669e3d8fed1..b8745b3e95b2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java @@ -21,12 +21,12 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; @@ -47,7 +47,7 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) @TestableLooper.RunWithLooper(setAsMainLooper = true) public class NotificationSectionsManagerTest extends SysuiTestCase { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt index b2a485c48860..b877456ab604 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt @@ -32,23 +32,19 @@ import com.android.systemui.statusbar.notification.row.ExpandableView import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import com.android.systemui.statusbar.policy.AvalancheController -import com.android.systemui.util.mockito.mock import com.google.common.truth.Expect import com.google.common.truth.Truth.assertThat -import junit.framework.Assert.assertEquals -import junit.framework.Assert.assertFalse -import junit.framework.Assert.assertTrue import kotlinx.coroutines.ExperimentalCoroutinesApi import org.junit.Assume import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mockito.any -import org.mockito.Mockito.eq -import org.mockito.Mockito.mock -import org.mockito.Mockito.verify -import org.mockito.Mockito.`when` as whenever +import org.mockito.kotlin.any +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @@ -846,7 +842,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { val viewStart = 0f val shelfStart = 1f - val expandableView = mock(ExpandableView::class.java) + val expandableView = mock<ExpandableView>() whenever(expandableView.isExpandAnimationRunning).thenReturn(false) whenever(expandableView.hasExpandingChild()).thenReturn(false) @@ -854,7 +850,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState.yTranslation = viewStart stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart) - assertFalse(expandableViewState.hidden) + assertThat(expandableViewState.hidden).isFalse() } @Test @@ -862,7 +858,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { val shelfStart = 0f val viewStart = 1f - val expandableView = mock(ExpandableView::class.java) + val expandableView = mock<ExpandableView>() whenever(expandableView.isExpandAnimationRunning).thenReturn(false) whenever(expandableView.hasExpandingChild()).thenReturn(false) @@ -870,7 +866,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState.yTranslation = viewStart stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart) - assertTrue(expandableViewState.hidden) + assertThat(expandableViewState.hidden).isTrue() } @Test @@ -878,7 +874,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { val shelfStart = 0f val viewStart = 1f - val expandableView = mock(ExpandableView::class.java) + val expandableView = mock<ExpandableView>() whenever(expandableView.isExpandAnimationRunning).thenReturn(true) whenever(expandableView.hasExpandingChild()).thenReturn(true) @@ -886,7 +882,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState.yTranslation = viewStart stackScrollAlgorithm.updateViewWithShelf(expandableView, expandableViewState, shelfStart) - assertFalse(expandableViewState.hidden) + assertThat(expandableViewState.hidden).isFalse() } @Test @@ -898,12 +894,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ true, /* mustStayOnScreen= */ true, - /* isViewEndVisible= */ true, + /* topVisible = */ true, /* viewEnd= */ 0f, - /* maxHunY= */ 10f, + /* hunMax = */ 10f, ) - assertTrue(expandableViewState.headsUpIsVisible) + assertThat(expandableViewState.headsUpIsVisible).isTrue() } @Test @@ -915,12 +911,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ true, /* mustStayOnScreen= */ true, - /* isViewEndVisible= */ true, + /* topVisible = */ true, /* viewEnd= */ 10f, - /* maxHunY= */ 0f, + /* hunMax = */ 0f, ) - assertFalse(expandableViewState.headsUpIsVisible) + assertThat(expandableViewState.headsUpIsVisible).isFalse() } @Test @@ -932,12 +928,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ false, /* mustStayOnScreen= */ true, - /* isViewEndVisible= */ true, + /* topVisible = */ true, /* viewEnd= */ 10f, - /* maxHunY= */ 1f, + /* hunMax = */ 1f, ) - assertTrue(expandableViewState.headsUpIsVisible) + assertThat(expandableViewState.headsUpIsVisible).isTrue() } @Test @@ -949,12 +945,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ true, /* mustStayOnScreen= */ false, - /* isViewEndVisible= */ true, + /* topVisible = */ true, /* viewEnd= */ 10f, - /* maxHunY= */ 1f, + /* hunMax = */ 1f, ) - assertTrue(expandableViewState.headsUpIsVisible) + assertThat(expandableViewState.headsUpIsVisible).isTrue() } @Test @@ -966,12 +962,12 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { expandableViewState, /* isShadeExpanded= */ true, /* mustStayOnScreen= */ true, - /* isViewEndVisible= */ false, + /* topVisible = */ false, /* viewEnd= */ 10f, - /* maxHunY= */ 1f, + /* hunMax = */ 1f, ) - assertTrue(expandableViewState.headsUpIsVisible) + assertThat(expandableViewState.headsUpIsVisible).isTrue() } @Test @@ -986,7 +982,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { ) // qqs (10 + 0) < viewY (50) - assertEquals(50f, expandableViewState.yTranslation) + assertThat(expandableViewState.yTranslation).isEqualTo(50f) } @Test @@ -1001,7 +997,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { ) // qqs (10 + 0) > viewY (-10) - assertEquals(10f, expandableViewState.yTranslation) + assertThat(expandableViewState.yTranslation).isEqualTo(10f) } @Test @@ -1019,7 +1015,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { // newTranslation = max(10, -100) = 10 // distToRealY = 10 - (-100f) = 110 // height = max(20 - 110, 10f) - assertEquals(10, expandableViewState.height) + assertThat(expandableViewState.height).isEqualTo(10) } @Test @@ -1037,7 +1033,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { // newTranslation = max(10, 5) = 10 // distToRealY = 10 - 5 = 5 // height = max(20 - 5, 10) = 15 - assertEquals(15, expandableViewState.height) + assertThat(expandableViewState.height).isEqualTo(15) } @Test @@ -1047,9 +1043,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { /* hostViewHeight= */ 100f, /* stackY= */ 110f, /* viewMaxHeight= */ 20f, - /* originalCornerRoundness= */ 0f, + /* originalCornerRadius = */ 0f, ) - assertEquals(1f, currentRoundness) + assertThat(currentRoundness).isEqualTo(1f) } @Test @@ -1059,9 +1055,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { /* hostViewHeight= */ 100f, /* stackY= */ 90f, /* viewMaxHeight= */ 20f, - /* originalCornerRoundness= */ 0f, + /* originalCornerRadius = */ 0f, ) - assertEquals(0.5f, currentRoundness) + assertThat(currentRoundness).isEqualTo(0.5f) } @Test @@ -1071,9 +1067,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { /* hostViewHeight= */ 100f, /* stackY= */ 0f, /* viewMaxHeight= */ 20f, - /* originalCornerRoundness= */ 0f, + /* originalCornerRadius = */ 0f, ) - assertEquals(0f, currentRoundness) + assertThat(currentRoundness).isZero() } @Test @@ -1083,9 +1079,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { /* hostViewHeight= */ 100f, /* stackY= */ 0f, /* viewMaxHeight= */ 20f, - /* originalCornerRoundness= */ 1f, + /* originalCornerRadius = */ 1f, ) - assertEquals(1f, currentRoundness) + assertThat(currentRoundness).isEqualTo(1f) } @Test @@ -1105,13 +1101,14 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, - /* StackScrollAlgorithmState= */ algorithmState, + /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, - /* shouldElevateHun= */ true, + /* isTopHun = */ true, ) // Then: full shadow would be applied - assertEquals(px(R.dimen.heads_up_pinned_elevation), childHunView.viewState.zTranslation) + assertThat(childHunView.viewState.zTranslation) + .isEqualTo(px(R.dimen.heads_up_pinned_elevation)) } @Test @@ -1133,9 +1130,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, - /* StackScrollAlgorithmState= */ algorithmState, + /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, - /* shouldElevateHun= */ true, + /* isTopHun = */ true, ) // Then: HUN should have shadow, but not as full size @@ -1166,13 +1163,13 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, - /* StackScrollAlgorithmState= */ algorithmState, + /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, - /* shouldElevateHun= */ true, + /* isTopHun = */ true, ) // Then: HUN should not have shadow - assertEquals(0f, childHunView.viewState.zTranslation) + assertThat(childHunView.viewState.zTranslation).isZero() } @Test @@ -1195,13 +1192,14 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, - /* StackScrollAlgorithmState= */ algorithmState, + /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, - /* shouldElevateHun= */ true, + /* isTopHun = */ true, ) // Then: HUN should have full shadow - assertEquals(px(R.dimen.heads_up_pinned_elevation), childHunView.viewState.zTranslation) + assertThat(childHunView.viewState.zTranslation) + .isEqualTo(px(R.dimen.heads_up_pinned_elevation)) } @Test @@ -1225,9 +1223,9 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updateChildZValue( /* i= */ 0, /* childrenOnTop= */ 0.0f, - /* StackScrollAlgorithmState= */ algorithmState, + /* algorithmState = */ algorithmState, /* ambientState= */ ambientState, - /* shouldElevateHun= */ true, + /* isTopHun = */ true, ) // Then: HUN should have shadow, but not as full size @@ -1251,7 +1249,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState) // Then: ambientState.pulsingRow should still be pulsingNotificationView - assertTrue(ambientState.isPulsingRow(pulsingNotificationView)) + assertThat(ambientState.isPulsingRow(pulsingNotificationView)).isTrue() } @Test @@ -1268,7 +1266,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState) // Then: ambientState.pulsingRow should record the pulsingNotificationView - assertTrue(ambientState.isPulsingRow(pulsingNotificationView)) + assertThat(ambientState.isPulsingRow(pulsingNotificationView)).isTrue() } @Test @@ -1287,7 +1285,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.updatePulsingStates(algorithmState, ambientState) // Then: ambientState.pulsingRow should be null - assertTrue(ambientState.isPulsingRow(null)) + assertThat(ambientState.isPulsingRow(null)).isTrue() } @Test @@ -1310,10 +1308,8 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { stackScrollAlgorithm.resetViewStates(ambientState, 0) // Then: pulsingNotificationView should show at full height - assertEquals( - stackScrollAlgorithm.getMaxAllowedChildHeight(pulsingNotificationView), - pulsingNotificationView.viewState.height, - ) + assertThat(pulsingNotificationView.viewState.height) + .isEqualTo(stackScrollAlgorithm.getMaxAllowedChildHeight(pulsingNotificationView)) // After: reset dozeAmount and expansionFraction ambientState.dozeAmount = 0f @@ -1418,7 +1414,7 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { yTranslation = ambientState.maxHeadsUpTranslation - height // move it to the max } - assertTrue(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)) + assertThat(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)).isTrue() } @Test @@ -1431,7 +1427,8 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { ambientState.maxHeadsUpTranslation - height - 1 // move it below the max } - assertFalse(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)) + assertThat(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)) + .isFalse() } // endregion @@ -1579,13 +1576,13 @@ class StackScrollAlgorithmTest(flags: FlagsParameterization) : SysuiTestCase() { } private fun mockExpandableNotificationRow(): ExpandableNotificationRow { - return mock(ExpandableNotificationRow::class.java).apply { + return mock<ExpandableNotificationRow>().apply { whenever(viewState).thenReturn(ExpandableViewState()) } } private fun mockFooterView(height: Int): FooterView { - return mock(FooterView::class.java).apply { + return mock<FooterView>().apply { whenever(viewState).thenReturn(FooterViewState()) whenever(intrinsicHeight).thenReturn(height) } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt index 778e8228ab9b..7a51b2ddb020 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt @@ -1088,7 +1088,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() { @Test @DisableFlags(StatusBarConnectedDisplays.FLAG_NAME) - fun onMaxBoundsChanged_beforeStart_flagDisabled_listenerNotNotified() { + fun onMaxBoundsChanged_beforeStart_flagDisabled_listenerNotified() { // Start out with an existing configuration with bounds configuration.windowConfiguration.setMaxBounds(0, 0, 100, 100) configurationController.onConfigurationChanged(configuration) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt index cdc7aa2dea2a..9888574071e6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt @@ -32,6 +32,8 @@ class FakeHomeStatusBarViewBinder : HomeStatusBarViewBinder { override fun bind( view: View, viewModel: HomeStatusBarViewModel, + systemEventChipAnimateIn: ((View) -> Unit)?, + systemEventChipAnimateOut: ((View) -> Unit)?, listener: StatusBarVisibilityChangeListener, ) { this.listener = listener diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt index 02c1540d3d8b..eef5753cef8a 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel import android.view.View import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -53,11 +54,14 @@ class FakeHomeStatusBarViewModel : HomeStatusBarViewModel { ) ) - override val isSystemInfoVisible = + override val systemInfoCombinedVis = MutableStateFlow( - HomeStatusBarViewModel.VisibilityModel( - visibility = View.GONE, - shouldAnimateChange = false, + HomeStatusBarViewModel.SystemInfoCombinedVisibilityModel( + HomeStatusBarViewModel.VisibilityModel( + visibility = View.GONE, + shouldAnimateChange = false, + ), + Idle, ) ) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt index b3a73d82122f..c4d2569bba89 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt @@ -60,11 +60,16 @@ import com.android.systemui.statusbar.data.repository.FakeStatusBarModeRepositor import com.android.systemui.statusbar.data.repository.fakeStatusBarModeRepository import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository +import com.android.systemui.statusbar.events.data.repository.systemStatusEventAnimationRepository +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingIn +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingOut +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle import com.android.systemui.statusbar.notification.data.model.activeNotificationModel import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor +import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel.VisibilityModel import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.emptyFlow @@ -90,6 +95,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { private val activeNotificationListRepository = kosmos.activeNotificationListRepository private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository private val disableFlagsRepository = kosmos.fakeDisableFlagsRepository + private val systemStatusEventAnimationRepository = kosmos.systemStatusEventAnimationRepository private lateinit var underTest: HomeStatusBarViewModel @@ -546,25 +552,50 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { @Test fun isSystemInfoVisible_allowedByDisableFlags_visible() = testScope.runTest { - val latest by collectLastValue(underTest.isSystemInfoVisible) + val latest by collectLastValue(underTest.systemInfoCombinedVis) transitionKeyguardToGone() disableFlagsRepository.disableFlags.value = DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) - assertThat(latest!!.visibility).isEqualTo(View.VISIBLE) + assertThat(latest!!.baseVisibility.visibility).isEqualTo(View.VISIBLE) } @Test fun isSystemInfoVisible_notAllowedByDisableFlags_gone() = testScope.runTest { - val latest by collectLastValue(underTest.isSystemInfoVisible) + val latest by collectLastValue(underTest.systemInfoCombinedVis) transitionKeyguardToGone() disableFlagsRepository.disableFlags.value = DisableFlagsModel(DISABLE_SYSTEM_INFO, DISABLE2_NONE) - assertThat(latest!!.visibility).isEqualTo(View.GONE) + assertThat(latest!!.baseVisibility.visibility).isEqualTo(View.GONE) + } + + @Test + fun systemInfoCombineVis_animationsPassThrough() = + testScope.runTest { + val latest by collectLastValue(underTest.systemInfoCombinedVis) + transitionKeyguardToGone() + + assertThat(latest!!.baseVisibility) + .isEqualTo(VisibilityModel(visibility = View.VISIBLE, shouldAnimateChange = false)) + assertThat(latest!!.animationState).isEqualTo(Idle) + + // WHEN the animation state changes, but the visibility state doesn't change + systemStatusEventAnimationRepository.animationState.value = AnimatingIn + + // THEN the visibility is the same + assertThat(latest!!.baseVisibility) + .isEqualTo(VisibilityModel(visibility = View.VISIBLE, shouldAnimateChange = false)) + // THEN the animation state updates + assertThat(latest!!.animationState).isEqualTo(AnimatingIn) + + systemStatusEventAnimationRepository.animationState.value = AnimatingOut + assertThat(latest!!.baseVisibility) + .isEqualTo(VisibilityModel(visibility = View.VISIBLE, shouldAnimateChange = false)) + assertThat(latest!!.animationState).isEqualTo(AnimatingOut) } @Test @@ -573,7 +604,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) keyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.GONE, @@ -583,7 +614,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { assertThat(clockVisible!!.visibility).isEqualTo(View.GONE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE) } @Test @@ -592,13 +623,13 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen) assertThat(clockVisible!!.visibility).isEqualTo(View.GONE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE) } @Test @@ -607,7 +638,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) keyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, @@ -617,7 +648,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { assertThat(clockVisible!!.visibility).isEqualTo(View.GONE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE) } @Test @@ -626,13 +657,13 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer) assertThat(clockVisible!!.visibility).isEqualTo(View.GONE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE) } @Test @@ -641,7 +672,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) keyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, @@ -651,7 +682,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.VISIBLE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE) } @Test @@ -660,14 +691,14 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen) kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, taskInfo = null) assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.VISIBLE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE) } @Test @@ -676,13 +707,13 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) transitionKeyguardToGone() assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.VISIBLE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE) } @Test @@ -691,14 +722,14 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) transitionKeyguardToGone() kosmos.shadeTestUtil.setShadeExpansion(0f) assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.VISIBLE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE) } @Test @@ -707,13 +738,13 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) kosmos.sceneContainerRepository.snapToScene(Scenes.Gone) assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.VISIBLE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE) } @Test @@ -722,14 +753,14 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) transitionKeyguardToGone() kosmos.shadeTestUtil.setShadeExpansion(1f) assertThat(clockVisible!!.visibility).isEqualTo(View.GONE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE) } @Test @@ -738,14 +769,14 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) transitionKeyguardToGone() kosmos.sceneContainerRepository.snapToScene(Scenes.Shade) assertThat(clockVisible!!.visibility).isEqualTo(View.GONE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE) } @Test @@ -754,7 +785,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) // Secure camera is an occluding activity keyguardTransitionRepository.sendTransitionSteps( @@ -766,7 +797,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { assertThat(clockVisible!!.visibility).isEqualTo(View.GONE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE) } @Test @@ -775,7 +806,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { testScope.runTest { val clockVisible by collectLastValue(underTest.isClockVisible) val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible) - val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible) + val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis) kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen) // Secure camera is an occluding activity @@ -784,7 +815,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { assertThat(clockVisible!!.visibility).isEqualTo(View.GONE) assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE) - assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE) + assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE) } private fun activeNotificationsStore(notifications: List<ActiveNotificationModel>) = diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt index d823bf57c824..d823bf57c824 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt index 9a862fc6a18f..c5eed7365d92 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt @@ -24,11 +24,19 @@ import androidx.test.filters.SmallTest import com.android.internal.logging.testing.UiEventLoggerFake import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager +import com.android.systemui.kosmos.testScope import com.android.systemui.log.logcatLogBuffer +import com.android.systemui.plugins.statusbar.statusBarStateController +import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder +import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider +import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun +import com.android.systemui.statusbar.phone.keyguardBypassController import com.android.systemui.statusbar.policy.HeadsUpManagerTestUtil.createFullScreenIntentEntry +import com.android.systemui.testKosmos import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.kotlin.JavaAdapter import com.android.systemui.util.settings.FakeGlobalSettings import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat @@ -48,6 +56,7 @@ import org.mockito.junit.MockitoRule @RunWith(AndroidJUnit4::class) @EnableFlags(NotificationThrottleHun.FLAG_NAME) class AvalancheControllerTest : SysuiTestCase() { + private val kosmos = testKosmos() // For creating mocks @get:Rule var rule: MockitoRule = MockitoJUnit.rule() @@ -61,7 +70,6 @@ class AvalancheControllerTest : SysuiTestCase() { @Mock private val mAccessibilityMgr: AccessibilityManagerWrapper? = null private val mUiEventLoggerFake = UiEventLoggerFake() @Mock private lateinit var mHeadsUpManagerLogger: HeadsUpManagerLogger - @Mock private lateinit var mBgHandler: Handler private val mLogger = Mockito.spy(HeadsUpManagerLogger(logcatLogBuffer())) @@ -76,26 +84,33 @@ class AvalancheControllerTest : SysuiTestCase() { Mockito.`when`( mAccessibilityMgr!!.getRecommendedTimeoutMillis( ArgumentMatchers.anyInt(), - ArgumentMatchers.anyInt() + ArgumentMatchers.anyInt(), ) ) .then { i: InvocationOnMock -> i.getArgument(0) } // Initialize AvalancheController and TestableHeadsUpManager during setUp instead of // declaration, where mocks are null - mAvalancheController = AvalancheController(dumpManager, mUiEventLoggerFake, - mHeadsUpManagerLogger, mBgHandler) + mAvalancheController = + AvalancheController(dumpManager, mUiEventLoggerFake, mHeadsUpManagerLogger, mBgHandler) testableHeadsUpManager = TestableHeadsUpManager( mContext, mLogger, + kosmos.statusBarStateController, + kosmos.keyguardBypassController, + GroupMembershipManagerImpl(), + kosmos.visualStabilityProvider, + kosmos.configurationController, mExecutor, mGlobalSettings, mSystemClock, mAccessibilityMgr, mUiEventLoggerFake, - mAvalancheController + JavaAdapter(kosmos.testScope), + kosmos.shadeInteractor, + mAvalancheController, ) } @@ -270,7 +285,6 @@ class AvalancheControllerTest : SysuiTestCase() { assertThat(mAvalancheController.headsUpEntryShowing).isEqualTo(nextEntry) } - @Test fun testDelete_deleteSecondToLastEntry_showingEntryKeyBecomesPreviousHunKey() { mAvalancheController.previousHunKey = "" @@ -305,7 +319,7 @@ class AvalancheControllerTest : SysuiTestCase() { mAvalancheController.delete(showingEntry, runnableMock!!, "testLabel") // Next entry is shown - assertThat(mAvalancheController.previousHunKey).isEqualTo(""); + assertThat(mAvalancheController.previousHunKey).isEqualTo("") } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java index 89aa670e5f0c..abb3e6e0c1f2 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java @@ -35,6 +35,8 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow; + import android.app.Notification; import android.app.PendingIntent; import android.app.Person; @@ -49,15 +51,21 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.testing.UiEventLoggerFake; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; +import com.android.systemui.kosmos.KosmosJavaAdapter; import com.android.systemui.res.R; +import com.android.systemui.shade.domain.interactor.ShadeInteractor; +import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; +import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun; import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.kotlin.JavaAdapter; import com.android.systemui.util.settings.FakeGlobalSettings; import com.android.systemui.util.time.FakeSystemClock; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -73,7 +81,10 @@ import java.util.List; @SmallTest @TestableLooper.RunWithLooper @RunWith(ParameterizedAndroidJunit4.class) +// TODO(b/378142453): Merge this with BaseHeadsUpManagerTest. public class BaseHeadsUpManagerTest extends SysuiTestCase { + protected KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this); + @Rule public MockitoRule rule = MockitoJUnit.rule(); @@ -85,6 +96,7 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase { private final HeadsUpManagerLogger mLogger = spy(new HeadsUpManagerLogger(logcatLogBuffer())); @Mock private Handler mBgHandler; @Mock private DumpManager dumpManager; + @Mock private ShadeInteractor mShadeInteractor; private AvalancheController mAvalancheController; @Mock private AccessibilityManagerWrapper mAccessibilityMgr; @@ -108,8 +120,22 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase { } private BaseHeadsUpManager createHeadsUpManager() { - return new TestableHeadsUpManager(mContext, mLogger, mExecutor, mGlobalSettings, - mSystemClock, mAccessibilityMgr, mUiEventLoggerFake, mAvalancheController); + return new TestableHeadsUpManager( + mContext, + mLogger, + mKosmos.getStatusBarStateController(), + mKosmos.getKeyguardBypassController(), + new GroupMembershipManagerImpl(), + mKosmos.getVisualStabilityProvider(), + mKosmos.getConfigurationController(), + mExecutor, + mGlobalSettings, + mSystemClock, + mAccessibilityMgr, + mUiEventLoggerFake, + new JavaAdapter(mKosmos.getTestScope()), + mShadeInteractor, + mAvalancheController); } private NotificationEntry createStickyEntry(int id) { @@ -152,6 +178,8 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase { super.SysuiSetup(); mAvalancheController = new AvalancheController(dumpManager, mUiEventLoggerFake, mLogger, mBgHandler); + when(mShadeInteractor.isAnyExpanded()).thenReturn(MutableStateFlow(true)); + when(mKosmos.getKeyguardBypassController().getBypassEnabled()).thenReturn(false); } @Test @@ -298,46 +326,6 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase { verify(mLogger, times(1)).logNotificationActuallyRemoved(eq(notifEntry)); } - @Test - public void testShouldHeadsUpBecomePinned_hasFSI_notUnpinned_true() { - final BaseHeadsUpManager hum = createHeadsUpManager(); - final NotificationEntry notifEntry = - HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext); - - // Add notifEntry to ANM mAlertEntries map and make it NOT unpinned - hum.showNotification(notifEntry); - - final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry( - notifEntry.getKey()); - headsUpEntry.mWasUnpinned = false; - - assertTrue(hum.shouldHeadsUpBecomePinned(notifEntry)); - } - - @Test - public void testShouldHeadsUpBecomePinned_wasUnpinned_false() { - final BaseHeadsUpManager hum = createHeadsUpManager(); - final NotificationEntry notifEntry = - HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext); - - // Add notifEntry to ANM mAlertEntries map and make it unpinned - hum.showNotification(notifEntry); - - final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry( - notifEntry.getKey()); - headsUpEntry.mWasUnpinned = true; - - assertFalse(hum.shouldHeadsUpBecomePinned(notifEntry)); - } - - @Test - public void testShouldHeadsUpBecomePinned_noFSI_false() { - final BaseHeadsUpManager hum = createHeadsUpManager(); - final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext); - - assertFalse(hum.shouldHeadsUpBecomePinned(entry)); - } - @Test public void testShowNotification_autoDismissesIncludingTouchAcceptanceDelay() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryStateNotifierTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BatteryStateNotifierTest.kt index c2460f93b862..c2460f93b862 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryStateNotifierTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BatteryStateNotifierTest.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt index 1915e8ede7e7..8ebdbaaa6bf0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.kt @@ -15,7 +15,6 @@ */ package com.android.systemui.statusbar.policy -import android.content.Context import android.os.Handler import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization @@ -26,27 +25,19 @@ import com.android.systemui.dump.DumpManager import com.android.systemui.flags.andSceneContainer import com.android.systemui.kosmos.testScope import com.android.systemui.log.logcatLogBuffer -import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.res.R import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.FakeStatusBarStateController import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.StatusBarState -import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun import com.android.systemui.statusbar.phone.ConfigurationControllerImpl -import com.android.systemui.statusbar.notification.HeadsUpManagerPhone import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.testKosmos -import com.android.systemui.util.concurrency.DelayableExecutor import com.android.systemui.util.concurrency.mockExecutorHandler import com.android.systemui.util.kotlin.JavaAdapter -import com.android.systemui.util.mockito.mock -import com.android.systemui.util.settings.GlobalSettings -import com.android.systemui.util.time.SystemClock import com.google.common.truth.Truth.assertThat import junit.framework.Assert import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -78,7 +69,7 @@ class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : BaseHeadsUpManager @Mock private lateinit var mVSProvider: VisualStabilityProvider - @Mock private lateinit var mStatusBarStateController: StatusBarStateController + val statusBarStateController = FakeStatusBarStateController() @Mock private lateinit var mBypassController: KeyguardBypassController @@ -97,61 +88,16 @@ class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : BaseHeadsUpManager @Mock private lateinit var mBgHandler: Handler - private class TestableHeadsUpManagerPhone( - context: Context, - headsUpManagerLogger: HeadsUpManagerLogger, - groupManager: GroupMembershipManager, - visualStabilityProvider: VisualStabilityProvider, - statusBarStateController: StatusBarStateController, - keyguardBypassController: KeyguardBypassController, - configurationController: ConfigurationController, - globalSettings: GlobalSettings, - systemClock: SystemClock, - executor: DelayableExecutor, - accessibilityManagerWrapper: AccessibilityManagerWrapper, - uiEventLogger: UiEventLogger, - javaAdapter: JavaAdapter, - shadeInteractor: ShadeInteractor, - avalancheController: AvalancheController - ) : - HeadsUpManagerPhone( - context, - headsUpManagerLogger, - statusBarStateController, - keyguardBypassController, - groupManager, - visualStabilityProvider, - configurationController, - mockExecutorHandler(executor), - globalSettings, - systemClock, - executor, - accessibilityManagerWrapper, - uiEventLogger, - javaAdapter, - shadeInteractor, - avalancheController - ) { - init { - mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME - mAutoDismissTime = TEST_AUTO_DISMISS_TIME - } - - /** Wrapper for [BaseHeadsUpManager.shouldHeadsUpBecomePinned] for testing */ - fun shouldHeadsUpBecomePinnedWrapper(entry: NotificationEntry): Boolean { - return shouldHeadsUpBecomePinned(entry) - } - } - - private fun createHeadsUpManagerPhone(): HeadsUpManagerPhone { - return TestableHeadsUpManagerPhone( + private fun createHeadsUpManagerPhone(): BaseHeadsUpManager { + return BaseHeadsUpManager( mContext, mHeadsUpManagerLogger, + statusBarStateController, + mBypassController, mGroupManager, mVSProvider, - mStatusBarStateController, - mBypassController, mConfigurationController, + mockExecutorHandler(mExecutor), mGlobalSettings, mSystemClock, mExecutor, @@ -159,20 +105,22 @@ class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : BaseHeadsUpManager mUiEventLogger, mJavaAdapter, mShadeInteractor, - mAvalancheController + mAvalancheController, ) } @Before fun setUp() { whenever(mShadeInteractor.isAnyExpanded).thenReturn(MutableStateFlow(false)) + whenever(mShadeInteractor.isQsExpanded).thenReturn(MutableStateFlow(false)) + whenever(mBypassController.bypassEnabled).thenReturn(false) whenever(mVSProvider.isReorderingAllowed).thenReturn(true) val accessibilityMgr = mDependency.injectMockDependency(AccessibilityManagerWrapper::class.java) whenever( accessibilityMgr.getRecommendedTimeoutMillis( ArgumentMatchers.anyInt(), - ArgumentMatchers.anyInt() + ArgumentMatchers.anyInt(), ) ) .thenReturn(TEST_AUTO_DISMISS_TIME) @@ -205,7 +153,7 @@ class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : BaseHeadsUpManager hmp.removeNotification( entry.key, /* releaseImmediately= */ false, - /* reason= */ "swipe out" + /* reason= */ "swipe out", ) Assert.assertTrue(removedImmediately) Assert.assertFalse(hmp.isHeadsUpEntry(entry.key)) @@ -245,6 +193,7 @@ class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : BaseHeadsUpManager mSystemClock.advanceTime((TEST_AUTO_DISMISS_TIME + hmp.mExtensionTime / 2).toLong()) Assert.assertTrue(hmp.isHeadsUpEntry(entry.key)) } + @Test @EnableFlags(NotificationThrottleHun.FLAG_NAME) fun testShowNotification_removeWhenReorderingAllowedTrue() { @@ -253,7 +202,7 @@ class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : BaseHeadsUpManager val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext) hmp.showNotification(notifEntry) - assertThat(hmp.mEntriesToRemoveWhenReorderingAllowed.contains(notifEntry)).isTrue(); + assertThat(hmp.mEntriesToRemoveWhenReorderingAllowed.contains(notifEntry)).isTrue() } @Test @@ -264,7 +213,7 @@ class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : BaseHeadsUpManager val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext) hmp.showNotification(notifEntry) - assertThat(notifEntry.isSeenInShade).isTrue(); + assertThat(notifEntry.isSeenInShade).isTrue() } @Test @@ -275,197 +224,136 @@ class HeadsUpManagerPhoneTest(flags: FlagsParameterization) : BaseHeadsUpManager val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext) hmp.showNotification(notifEntry) - assertThat(notifEntry.isSeenInShade).isFalse(); + assertThat(notifEntry.isSeenInShade).isFalse() } @Test + fun testShouldHeadsUpBecomePinned_noFSI_false() = + testScope.runTest { + val hum = createHeadsUpManagerPhone() + statusBarStateController.setState(StatusBarState.KEYGUARD) + + val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext) + + Assert.assertFalse(hum.shouldHeadsUpBecomePinned(entry)) + } + + @Test + fun testShouldHeadsUpBecomePinned_hasFSI_notUnpinned_true() = + testScope.runTest { + val hum = createHeadsUpManagerPhone() + statusBarStateController.setState(StatusBarState.KEYGUARD) + + val notifEntry = + HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id= */ 0, mContext) + + // Add notifEntry to ANM mAlertEntries map and make it NOT unpinned + hum.showNotification(notifEntry) + + val headsUpEntry = hum.getHeadsUpEntry(notifEntry.key) + headsUpEntry!!.mWasUnpinned = false + + Assert.assertTrue(hum.shouldHeadsUpBecomePinned(notifEntry)) + } + + @Test + fun testShouldHeadsUpBecomePinned_wasUnpinned_false() = + testScope.runTest { + val hum = createHeadsUpManagerPhone() + statusBarStateController.setState(StatusBarState.KEYGUARD) + + val notifEntry = + HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id= */ 0, mContext) + + // Add notifEntry to ANM mAlertEntries map and make it unpinned + hum.showNotification(notifEntry) + + val headsUpEntry = hum.getHeadsUpEntry(notifEntry.key) + headsUpEntry!!.mWasUnpinned = true + + Assert.assertFalse(hum.shouldHeadsUpBecomePinned(notifEntry)) + } + + @Test fun shouldHeadsUpBecomePinned_shadeNotExpanded_true() = testScope.runTest { // GIVEN - val statusBarStateController = FakeStatusBarStateController() whenever(mShadeInteractor.isAnyFullyExpanded).thenReturn(MutableStateFlow(false)) - val hmp = - TestableHeadsUpManagerPhone( - mContext, - mHeadsUpManagerLogger, - mGroupManager, - mVSProvider, - statusBarStateController, - mBypassController, - mConfigurationController, - mGlobalSettings, - mSystemClock, - mExecutor, - mAccessibilityManagerWrapper, - mUiEventLogger, - mJavaAdapter, - mShadeInteractor, - mAvalancheController - ) + val hmp = createHeadsUpManagerPhone() val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext) statusBarStateController.setState(StatusBarState.SHADE) runCurrent() // THEN - Assert.assertTrue(hmp.shouldHeadsUpBecomePinnedWrapper(entry)) + Assert.assertTrue(hmp.shouldHeadsUpBecomePinned(entry)) } @Test fun shouldHeadsUpBecomePinned_shadeLocked_false() = testScope.runTest { // GIVEN - val statusBarStateController = FakeStatusBarStateController() - val hmp = - TestableHeadsUpManagerPhone( - mContext, - mHeadsUpManagerLogger, - mGroupManager, - mVSProvider, - statusBarStateController, - mBypassController, - mConfigurationController, - mGlobalSettings, - mSystemClock, - mExecutor, - mAccessibilityManagerWrapper, - mUiEventLogger, - mJavaAdapter, - mShadeInteractor, - mAvalancheController - ) + val hmp = createHeadsUpManagerPhone() val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext) statusBarStateController.setState(StatusBarState.SHADE_LOCKED) runCurrent() // THEN - Assert.assertFalse(hmp.shouldHeadsUpBecomePinnedWrapper(entry)) + Assert.assertFalse(hmp.shouldHeadsUpBecomePinned(entry)) } @Test fun shouldHeadsUpBecomePinned_shadeUnknown_false() = testScope.runTest { // GIVEN - val statusBarStateController = FakeStatusBarStateController() - val hmp = - TestableHeadsUpManagerPhone( - mContext, - mHeadsUpManagerLogger, - mGroupManager, - mVSProvider, - statusBarStateController, - mBypassController, - mConfigurationController, - mGlobalSettings, - mSystemClock, - mExecutor, - mAccessibilityManagerWrapper, - mUiEventLogger, - mJavaAdapter, - mShadeInteractor, - mAvalancheController - ) + val hmp = createHeadsUpManagerPhone() val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext) statusBarStateController.setState(1207) runCurrent() // THEN - Assert.assertFalse(hmp.shouldHeadsUpBecomePinnedWrapper(entry)) + Assert.assertFalse(hmp.shouldHeadsUpBecomePinned(entry)) } @Test fun shouldHeadsUpBecomePinned_keyguardWithBypassOn_true() = testScope.runTest { // GIVEN - val statusBarStateController = FakeStatusBarStateController() whenever(mBypassController.bypassEnabled).thenReturn(true) - val hmp = - TestableHeadsUpManagerPhone( - mContext, - mHeadsUpManagerLogger, - mGroupManager, - mVSProvider, - statusBarStateController, - mBypassController, - mConfigurationController, - mGlobalSettings, - mSystemClock, - mExecutor, - mAccessibilityManagerWrapper, - mUiEventLogger, - mJavaAdapter, - mShadeInteractor, - mAvalancheController - ) + val hmp = createHeadsUpManagerPhone() val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext) statusBarStateController.setState(StatusBarState.KEYGUARD) runCurrent() // THEN - Assert.assertTrue(hmp.shouldHeadsUpBecomePinnedWrapper(entry)) + Assert.assertTrue(hmp.shouldHeadsUpBecomePinned(entry)) } @Test fun shouldHeadsUpBecomePinned_keyguardWithBypassOff_false() = testScope.runTest { // GIVEN - val statusBarStateController = FakeStatusBarStateController() whenever(mBypassController.bypassEnabled).thenReturn(false) - val hmp = - TestableHeadsUpManagerPhone( - mContext, - mHeadsUpManagerLogger, - mGroupManager, - mVSProvider, - statusBarStateController, - mBypassController, - mConfigurationController, - mGlobalSettings, - mSystemClock, - mExecutor, - mAccessibilityManagerWrapper, - mUiEventLogger, - mJavaAdapter, - mShadeInteractor, - mAvalancheController - ) + val hmp = createHeadsUpManagerPhone() val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext) statusBarStateController.setState(StatusBarState.KEYGUARD) runCurrent() // THEN - Assert.assertFalse(hmp.shouldHeadsUpBecomePinnedWrapper(entry)) + Assert.assertFalse(hmp.shouldHeadsUpBecomePinned(entry)) } @Test fun shouldHeadsUpBecomePinned_shadeExpanded_false() = testScope.runTest { // GIVEN - val statusBarStateController = FakeStatusBarStateController() whenever(mShadeInteractor.isAnyExpanded).thenReturn(MutableStateFlow(true)) - val hmp = - TestableHeadsUpManagerPhone( - mContext, - mHeadsUpManagerLogger, - mGroupManager, - mVSProvider, - statusBarStateController, - mBypassController, - mConfigurationController, - mGlobalSettings, - mSystemClock, - mExecutor, - mAccessibilityManagerWrapper, - mUiEventLogger, - mJavaAdapter, - mShadeInteractor, - mAvalancheController - ) + val hmp = createHeadsUpManagerPhone() val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext) statusBarStateController.setState(StatusBarState.SHADE) runCurrent() // THEN - Assert.assertFalse(hmp.shouldHeadsUpBecomePinnedWrapper(entry)) + Assert.assertFalse(hmp.shouldHeadsUpBecomePinned(entry)) } companion object { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/RotationLockControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/RotationLockControllerImplTest.java index 3f33d2f89f5e..8593f6a08b5a 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/RotationLockControllerImplTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/RotationLockControllerImplTest.java @@ -21,9 +21,9 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; -import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.internal.view.RotationPolicy; @@ -37,7 +37,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) @TestableLooper.RunWithLooper @SmallTest public class RotationLockControllerImplTest extends SysuiTestCase { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/TestableHeadsUpManager.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/TestableHeadsUpManager.java index 3efabd743141..59987f413ad6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/TestableHeadsUpManager.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/TestableHeadsUpManager.java @@ -16,7 +16,6 @@ package com.android.systemui.statusbar.policy; -import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED; import static com.android.systemui.util.concurrency.MockExecutorHandlerKt.mockExecutorHandler; import static org.mockito.Mockito.spy; @@ -28,8 +27,14 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.logging.UiEventLogger; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; +import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; +import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.util.concurrency.DelayableExecutor; +import com.android.systemui.util.kotlin.JavaAdapter; import com.android.systemui.util.settings.GlobalSettings; import com.android.systemui.util.time.SystemClock; @@ -37,16 +42,39 @@ class TestableHeadsUpManager extends BaseHeadsUpManager { private HeadsUpEntry mLastCreatedEntry; - TestableHeadsUpManager(Context context, + TestableHeadsUpManager( + Context context, HeadsUpManagerLogger logger, + StatusBarStateController statusBarStateController, + KeyguardBypassController bypassController, + GroupMembershipManager groupMembershipManager, + VisualStabilityProvider visualStabilityProvider, + ConfigurationController configurationController, DelayableExecutor executor, GlobalSettings globalSettings, SystemClock systemClock, AccessibilityManagerWrapper accessibilityManagerWrapper, UiEventLogger uiEventLogger, + JavaAdapter javaAdapter, + ShadeInteractor shadeInteractor, AvalancheController avalancheController) { - super(context, logger, mockExecutorHandler(executor), globalSettings, systemClock, - executor, accessibilityManagerWrapper, uiEventLogger, avalancheController); + super( + context, + logger, + statusBarStateController, + bypassController, + groupMembershipManager, + visualStabilityProvider, + configurationController, + mockExecutorHandler(executor), + globalSettings, + systemClock, + executor, + accessibilityManagerWrapper, + uiEventLogger, + javaAdapter, + shadeInteractor, + avalancheController); mTouchAcceptanceDelay = BaseHeadsUpManagerTest.TEST_TOUCH_ACCEPTANCE_TIME; mMinimumDisplayTime = BaseHeadsUpManagerTest.TEST_MINIMUM_DISPLAY_TIME; @@ -61,11 +89,6 @@ class TestableHeadsUpManager extends BaseHeadsUpManager { return mLastCreatedEntry; } - @Override - public int getContentFlag() { - return FLAG_CONTENT_VIEW_CONTRACTED; - } - // The following are only implemented by HeadsUpManagerPhone. If you need them, use that. @Override public void addHeadsUpPhoneListener(@NonNull OnHeadsUpPhoneListenerChange listener) { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt index 39836e2ce32f..0e32c9526df2 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModelTest.kt @@ -18,9 +18,12 @@ package com.android.systemui.statusbar.policy.ui.dialog.viewmodel +import android.app.AutomaticZenRule import android.content.Intent import android.content.applicationContext import android.provider.Settings +import android.service.notification.SystemZenRules +import android.service.notification.ZenModeConfig import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.notification.modes.TestModeBuilder @@ -35,6 +38,7 @@ import com.android.systemui.statusbar.policy.ui.dialog.mockModesDialogDelegate import com.android.systemui.statusbar.policy.ui.dialog.mockModesDialogEventLogger import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat +import java.util.Calendar import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.test.runCurrent @@ -60,6 +64,8 @@ class ModesDialogViewModelTest : SysuiTestCase() { private lateinit var underTest: ModesDialogViewModel + private lateinit var timeScheduleMode: ZenMode + @Before fun setUp() { MockitoAnnotations.initMocks(this) @@ -71,6 +77,21 @@ class ModesDialogViewModelTest : SysuiTestCase() { kosmos.mockModesDialogDelegate, kosmos.mockModesDialogEventLogger, ) + + val scheduleInfo = ZenModeConfig.ScheduleInfo() + scheduleInfo.days = intArrayOf(Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY) + scheduleInfo.startHour = 11 + scheduleInfo.endHour = 15 + timeScheduleMode = + TestModeBuilder() + .setPackage(SystemZenRules.PACKAGE_ANDROID) + .setType(AutomaticZenRule.TYPE_SCHEDULE_TIME) + .setManualInvocationAllowed(true) + .setConditionId(ZenModeConfig.toScheduleConditionId(scheduleInfo)) + .setTriggerDescription( + SystemZenRules.getTriggerDescriptionForScheduleTime(mContext, scheduleInfo) + ) + .build() } @Test @@ -325,17 +346,19 @@ class ModesDialogViewModelTest : SysuiTestCase() { .setTriggerDescription(null) .setEnabled(false, /* byUser= */ false) .build(), + timeScheduleMode, ) ) runCurrent() - assertThat(tiles!!).hasSize(6) + assertThat(tiles!!).hasSize(7) assertThat(tiles!![0].subtext).isEqualTo("When the going gets tough") assertThat(tiles!![1].subtext).isEqualTo("On • When in Rome") assertThat(tiles!![2].subtext).isEqualTo("Not set") assertThat(tiles!![3].subtext).isEqualTo("Off") assertThat(tiles!![4].subtext).isEqualTo("On") assertThat(tiles!![5].subtext).isEqualTo("Not set") + assertThat(tiles!![6].subtext).isEqualTo("Mon - Wed, 11:00 AM - 3:00 PM") } @Test @@ -381,11 +404,12 @@ class ModesDialogViewModelTest : SysuiTestCase() { .setTriggerDescription(null) .setEnabled(false, /* byUser= */ false) .build(), + timeScheduleMode, ) ) runCurrent() - assertThat(tiles!!).hasSize(6) + assertThat(tiles!!).hasSize(7) with(tiles?.elementAt(0)!!) { assertThat(this.stateDescription).isEqualTo("Off") assertThat(this.subtextDescription).isEqualTo("When the going gets tough") @@ -410,6 +434,11 @@ class ModesDialogViewModelTest : SysuiTestCase() { assertThat(this.stateDescription).isEqualTo("Off") assertThat(this.subtextDescription).isEqualTo("Not set") } + with(tiles?.elementAt(6)!!) { + assertThat(this.stateDescription).isEqualTo("Off") + assertThat(this.subtextDescription) + .isEqualTo("Monday to Wednesday, 11:00 AM - 3:00 PM") + } // All tiles have the same long click info tiles!!.forEach { assertThat(it.onLongClickLabel).isEqualTo("Open settings") } diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt index 9592b280be34..798380a92002 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/stylus/StylusUsiPowerStartableTest.kt @@ -18,8 +18,8 @@ package com.android.systemui.stylus import android.hardware.BatteryState import android.hardware.input.InputManager -import android.testing.AndroidTestingRunner import android.view.InputDevice +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags @@ -35,7 +35,7 @@ import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.MockitoAnnotations -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) @SmallTest class StylusUsiPowerStartableTest : SysuiTestCase() { @Mock lateinit var inputManager: InputManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/TestableAlertDialogTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/TestableAlertDialogTest.kt index 01dd60ae2200..4351d28ecf45 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/TestableAlertDialogTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/TestableAlertDialogTest.kt @@ -21,8 +21,8 @@ import android.content.DialogInterface import android.content.DialogInterface.BUTTON_NEGATIVE import android.content.DialogInterface.BUTTON_NEUTRAL import android.content.DialogInterface.BUTTON_POSITIVE -import android.testing.AndroidTestingRunner import android.testing.TestableLooper +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.util.mockito.any @@ -36,7 +36,7 @@ import org.mockito.Mockito.never import org.mockito.Mockito.verify @SmallTest -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class TestableAlertDialogTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java index 1ff9548486ab..c6bfb351b57d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java @@ -21,9 +21,9 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.animation.Animator; -import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; @@ -36,7 +36,7 @@ import org.mockito.MockitoAnnotations; @SmallTest @TestableLooper.RunWithLooper -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class KeepAwakeAnimationListenerTest extends SysuiTestCase { @Mock WakeLock mWakeLock; KeepAwakeAnimationListener mKeepAwakeAnimationListener; diff --git a/packages/SystemUI/pods/Android.bp b/packages/SystemUI/pods/Android.bp new file mode 100644 index 000000000000..e45f3170d9ad --- /dev/null +++ b/packages/SystemUI/pods/Android.bp @@ -0,0 +1,22 @@ +// +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package { + default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"], + // The package default_visibility specified here is inherited to subpackages that do not + // specify default_visibility: + default_visibility: ["//visibility:private"], +} diff --git a/packages/SystemUI/pods/com/android/systemui/dagger/Android.bp b/packages/SystemUI/pods/com/android/systemui/dagger/Android.bp new file mode 100644 index 000000000000..df90be8ecb97 --- /dev/null +++ b/packages/SystemUI/pods/com/android/systemui/dagger/Android.bp @@ -0,0 +1,34 @@ +// +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +soong_namespace { +} + +package { + default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"], +} + +java_library { + name: "api", + srcs: [ + "**/*.java", + "**/*.kt", + ], + libs: [ + "jsr330", + ], + visibility: ["//frameworks/base/packages/SystemUI:__subpackages__"], +} diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUISingleton.java b/packages/SystemUI/pods/com/android/systemui/dagger/SysUISingleton.java index a4b33427cbda..a4b33427cbda 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SysUISingleton.java +++ b/packages/SystemUI/pods/com/android/systemui/dagger/SysUISingleton.java diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/Application.java b/packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/Application.java index 21e53a5b51d0..21e53a5b51d0 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/Application.java +++ b/packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/Application.java diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/Background.java b/packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/Background.java index 141c9019b3e4..141c9019b3e4 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/Background.java +++ b/packages/SystemUI/pods/com/android/systemui/dagger/qualifiers/Background.java diff --git a/packages/SystemUI/pods/com/android/systemui/retail/Android.bp b/packages/SystemUI/pods/com/android/systemui/retail/Android.bp new file mode 100644 index 000000000000..f04784885c10 --- /dev/null +++ b/packages/SystemUI/pods/com/android/systemui/retail/Android.bp @@ -0,0 +1,38 @@ +// +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +soong_namespace { +} + +package { + default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"], +} + +java_library { + name: "impl", + srcs: ["*.kt"], + libs: [ + "jsr330", + "dagger2", + "SystemUICommon", + "kotlinx_coroutines", + ], + static_libs: [ + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail/data:impl", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail/domain:impl", + ], + visibility: ["//frameworks/base/packages/SystemUI"], +} diff --git a/packages/SystemUI/src/com/android/systemui/retail/dagger/RetailModeModule.kt b/packages/SystemUI/pods/com/android/systemui/retail/RetailModeModule.kt index e8639498b7c0..c20e368f1690 100644 --- a/packages/SystemUI/src/com/android/systemui/retail/dagger/RetailModeModule.kt +++ b/packages/SystemUI/pods/com/android/systemui/retail/RetailModeModule.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.systemui.retail.dagger +package com.android.systemui.retail import com.android.systemui.retail.data.repository.RetailModeRepository -import com.android.systemui.retail.data.repository.RetailModeSettingsRepository +import com.android.systemui.retail.data.repository.impl.RetailModeSettingsRepository import com.android.systemui.retail.domain.interactor.RetailModeInteractor -import com.android.systemui.retail.domain.interactor.RetailModeInteractorImpl +import com.android.systemui.retail.domain.interactor.impl.RetailModeInteractorImpl import dagger.Binds import dagger.Module diff --git a/packages/SystemUI/pods/com/android/systemui/retail/data/Android.bp b/packages/SystemUI/pods/com/android/systemui/retail/data/Android.bp new file mode 100644 index 000000000000..f148a7c69ecc --- /dev/null +++ b/packages/SystemUI/pods/com/android/systemui/retail/data/Android.bp @@ -0,0 +1,55 @@ +// +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +soong_namespace { +} + +package { + default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"], +} + +java_library { + name: "api", + srcs: ["repository/*.kt"], + libs: [ + "kotlinx_coroutines", + ], + visibility: [ + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail/dagger", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail/domain", + ], +} + +java_library { + name: "impl", + srcs: ["repository/impl/*.kt"], + libs: [ + "jsr330", + "kotlinx_coroutines", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/dagger:api", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/util/settings:api", + "SystemUICommon", + ], + static_libs: [ + "api", + ], + visibility: [ + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail/dagger", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail/domain", + ], +} diff --git a/packages/SystemUI/pods/com/android/systemui/retail/data/repository/RetailModeRepository.kt b/packages/SystemUI/pods/com/android/systemui/retail/data/repository/RetailModeRepository.kt new file mode 100644 index 000000000000..c9eac2588811 --- /dev/null +++ b/packages/SystemUI/pods/com/android/systemui/retail/data/repository/RetailModeRepository.kt @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.retail.data.repository + +import kotlinx.coroutines.flow.StateFlow + +/** Repository to track if the device is in Retail mode */ +interface RetailModeRepository { + /** Flow of whether the device is currently in retail mode. */ + val retailMode: StateFlow<Boolean> + + /** Last value of whether the device is in retail mode. */ + val inRetailMode: Boolean + get() = retailMode.value +} diff --git a/packages/SystemUI/src/com/android/systemui/retail/data/repository/RetailModeRepository.kt b/packages/SystemUI/pods/com/android/systemui/retail/data/repository/impl/RetailModeSettingsRepository.kt index 09fd7df15dc2..8955263595f3 100644 --- a/packages/SystemUI/src/com/android/systemui/retail/data/repository/RetailModeRepository.kt +++ b/packages/SystemUI/pods/com/android/systemui/retail/data/repository/impl/RetailModeSettingsRepository.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.retail.data.repository +package com.android.systemui.retail.data.repository.impl import android.database.ContentObserver import android.provider.Settings @@ -22,6 +22,7 @@ import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCall import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.retail.data.repository.RetailModeRepository import com.android.systemui.util.settings.GlobalSettings import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher @@ -34,16 +35,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn -/** Repository to track if the device is in Retail mode */ -interface RetailModeRepository { - /** Flow of whether the device is currently in retail mode. */ - val retailMode: StateFlow<Boolean> - - /** Last value of whether the device is in retail mode. */ - val inRetailMode: Boolean - get() = retailMode.value -} - /** * Tracks [Settings.Global.DEVICE_DEMO_MODE]. * diff --git a/packages/SystemUI/pods/com/android/systemui/retail/domain/Android.bp b/packages/SystemUI/pods/com/android/systemui/retail/domain/Android.bp new file mode 100644 index 000000000000..787861ce5eb8 --- /dev/null +++ b/packages/SystemUI/pods/com/android/systemui/retail/domain/Android.bp @@ -0,0 +1,46 @@ +// +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +soong_namespace { +} + +package { + default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"], +} + +java_library { + name: "api", + srcs: ["interactor/*.kt"], + visibility: [ + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail", + ], +} + +java_library { + name: "impl", + srcs: ["interactor/impl/*.kt"], + libs: [ + "jsr330", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/dagger:api", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail/data:api", + ], + static_libs: [ + "api", + ], + visibility: [ + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/retail", + ], +} diff --git a/packages/SystemUI/pods/com/android/systemui/retail/domain/interactor/RetailModeInteractor.kt b/packages/SystemUI/pods/com/android/systemui/retail/domain/interactor/RetailModeInteractor.kt new file mode 100644 index 000000000000..748e34d430d8 --- /dev/null +++ b/packages/SystemUI/pods/com/android/systemui/retail/domain/interactor/RetailModeInteractor.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.retail.domain.interactor + +/** Interactor to determine if the device is currently in retail mode */ +interface RetailModeInteractor { + /** Whether the device is currently in retail mode */ + val isInRetailMode: Boolean +} diff --git a/packages/SystemUI/src/com/android/systemui/retail/domain/interactor/RetailModeInteractor.kt b/packages/SystemUI/pods/com/android/systemui/retail/domain/interactor/impl/RetailModeInteractorImpl.kt index eea452c78ea5..8dbe562c2ed7 100644 --- a/packages/SystemUI/src/com/android/systemui/retail/domain/interactor/RetailModeInteractor.kt +++ b/packages/SystemUI/pods/com/android/systemui/retail/domain/interactor/impl/RetailModeInteractorImpl.kt @@ -14,18 +14,13 @@ * limitations under the License. */ -package com.android.systemui.retail.domain.interactor +package com.android.systemui.retail.domain.interactor.impl import com.android.systemui.dagger.SysUISingleton import com.android.systemui.retail.data.repository.RetailModeRepository +import com.android.systemui.retail.domain.interactor.RetailModeInteractor import javax.inject.Inject -/** Interactor to determine if the device is currently in retail mode */ -interface RetailModeInteractor { - /** Whether the device is currently in retail mode */ - val isInRetailMode: Boolean -} - @SysUISingleton class RetailModeInteractorImpl @Inject diff --git a/packages/SystemUI/pods/com/android/systemui/util/settings/Android.bp b/packages/SystemUI/pods/com/android/systemui/util/settings/Android.bp new file mode 100644 index 000000000000..1aa772961408 --- /dev/null +++ b/packages/SystemUI/pods/com/android/systemui/util/settings/Android.bp @@ -0,0 +1,40 @@ +// +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +soong_namespace { +} + +package { + default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"], +} + +java_library { + name: "api", + srcs: [ + "*.java", + "*.kt", + ], + libs: [ + "//frameworks/libs/systemui:tracinglib-platform", + "//frameworks/base/packages/SystemUI/pods/com/android/systemui/dagger:api", + "SystemUICommon", + "androidx.annotation_annotation", + "kotlinx_coroutines_android", + "jsr330", + ], + kotlincflags: ["-Xjvm-default=all"], + visibility: ["//frameworks/base/packages/SystemUI:__subpackages__"], +} diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettings.java b/packages/SystemUI/pods/com/android/systemui/util/settings/GlobalSettings.java index 84ab66b66a7c..84ab66b66a7c 100644 --- a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettings.java +++ b/packages/SystemUI/pods/com/android/systemui/util/settings/GlobalSettings.java diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java b/packages/SystemUI/pods/com/android/systemui/util/settings/GlobalSettingsImpl.java index 7fcabe4a4363..d68501f69bc0 100644 --- a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java +++ b/packages/SystemUI/pods/com/android/systemui/util/settings/GlobalSettingsImpl.java @@ -23,7 +23,7 @@ import android.content.ContentResolver; import android.net.Uri; import android.provider.Settings; -import com.android.systemui.util.kotlin.SettingsSingleThreadBackground; +import com.android.systemui.util.settings.SettingsSingleThreadBackground; import kotlinx.coroutines.CoroutineDispatcher; diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettings.java b/packages/SystemUI/pods/com/android/systemui/util/settings/SecureSettings.java index 6031a4e05629..6031a4e05629 100644 --- a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettings.java +++ b/packages/SystemUI/pods/com/android/systemui/util/settings/SecureSettings.java diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java b/packages/SystemUI/pods/com/android/systemui/util/settings/SecureSettingsImpl.java index c29648186d54..211a6f48e475 100644 --- a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java +++ b/packages/SystemUI/pods/com/android/systemui/util/settings/SecureSettingsImpl.java @@ -21,7 +21,7 @@ import android.content.ContentResolver; import android.net.Uri; import android.provider.Settings; -import com.android.systemui.util.kotlin.SettingsSingleThreadBackground; +import com.android.systemui.util.settings.SettingsSingleThreadBackground; import kotlinx.coroutines.CoroutineDispatcher; diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt b/packages/SystemUI/pods/com/android/systemui/util/settings/SettingsProxy.kt index 5d0b0d55e1f6..5d0b0d55e1f6 100644 --- a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt +++ b/packages/SystemUI/pods/com/android/systemui/util/settings/SettingsProxy.kt diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxyExt.kt b/packages/SystemUI/pods/com/android/systemui/util/settings/SettingsProxyExt.kt index 364681444c1b..364681444c1b 100644 --- a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxyExt.kt +++ b/packages/SystemUI/pods/com/android/systemui/util/settings/SettingsProxyExt.kt diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/SettingsSingleThreadBackground.java b/packages/SystemUI/pods/com/android/systemui/util/settings/SettingsSingleThreadBackground.java index e13981dfe5c7..5632a36a2942 100644 --- a/packages/SystemUI/src/com/android/systemui/util/kotlin/SettingsSingleThreadBackground.java +++ b/packages/SystemUI/pods/com/android/systemui/util/settings/SettingsSingleThreadBackground.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.util.kotlin; +package com.android.systemui.util.settings; import static java.lang.annotation.RetentionPolicy.RUNTIME; diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettings.java b/packages/SystemUI/pods/com/android/systemui/util/settings/SystemSettings.java index c67c60375b2c..c67c60375b2c 100644 --- a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettings.java +++ b/packages/SystemUI/pods/com/android/systemui/util/settings/SystemSettings.java diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java b/packages/SystemUI/pods/com/android/systemui/util/settings/SystemSettingsImpl.java index e670b2c2edd0..1b3f74e0c983 100644 --- a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java +++ b/packages/SystemUI/pods/com/android/systemui/util/settings/SystemSettingsImpl.java @@ -21,7 +21,7 @@ import android.content.ContentResolver; import android.net.Uri; import android.provider.Settings; -import com.android.systemui.util.kotlin.SettingsSingleThreadBackground; +import com.android.systemui.util.settings.SettingsSingleThreadBackground; import kotlinx.coroutines.CoroutineDispatcher; diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt b/packages/SystemUI/pods/com/android/systemui/util/settings/UserSettingsProxy.kt index 4b03df6b0070..4b03df6b0070 100644 --- a/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt +++ b/packages/SystemUI/pods/com/android/systemui/util/settings/UserSettingsProxy.kt diff --git a/packages/SystemUI/res/drawable/hearing_devices_preset_spinner_background.xml b/packages/SystemUI/res/drawable/hearing_devices_spinner_background.xml index c83b6d38a0e1..dfefb9d166af 100644 --- a/packages/SystemUI/res/drawable/hearing_devices_preset_spinner_background.xml +++ b/packages/SystemUI/res/drawable/hearing_devices_spinner_background.xml @@ -14,7 +14,8 @@ limitations under the License. --> -<layer-list xmlns:android="http://schemas.android.com/apk/res/android" +<layer-list + xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:paddingMode="stack"> <item> @@ -30,8 +31,8 @@ android:end="20dp" android:gravity="end|center_vertical"> <vector - android:width="@dimen/hearing_devices_preset_spinner_arrow_size" - android:height="@dimen/hearing_devices_preset_spinner_arrow_size" + android:width="@dimen/hearing_devices_preset_spinner_icon_size" + android:height="@dimen/hearing_devices_preset_spinner_icon_size" android:viewportWidth="24" android:viewportHeight="24" android:tint="?androidprv:attr/colorControlNormal"> diff --git a/packages/SystemUI/res/drawable/hearing_devices_preset_spinner_popup_background.xml b/packages/SystemUI/res/drawable/hearing_devices_spinner_popup_background.xml index f35975ee8548..f35975ee8548 100644 --- a/packages/SystemUI/res/drawable/hearing_devices_preset_spinner_popup_background.xml +++ b/packages/SystemUI/res/drawable/hearing_devices_spinner_popup_background.xml diff --git a/packages/SystemUI/res/layout/hearing_devices_preset_dropdown_item.xml b/packages/SystemUI/res/drawable/hearing_devices_spinner_selected_background.xml index 17c0222ef69e..c708d2280161 100644 --- a/packages/SystemUI/res/layout/hearing_devices_preset_dropdown_item.xml +++ b/packages/SystemUI/res/drawable/hearing_devices_spinner_selected_background.xml @@ -1,3 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright (C) 2024 The Android Open Source Project @@ -13,14 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. --> - -<TextView xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/hearing_devices_preset_option_text" - style="?android:attr/spinnerDropDownItemStyle" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:minHeight="@dimen/hearing_devices_preset_spinner_height" - android:paddingStart="@dimen/hearing_devices_preset_spinner_text_padding_start" - android:gravity="center_vertical" - android:textDirection="locale" - android:ellipsize="end" />
\ No newline at end of file +<inset xmlns:android="http://schemas.android.com/apk/res/android" + android:drawable="@drawable/settingslib_switch_bar_bg_on" + android:insetTop="8dp" + android:insetBottom="8dp" + android:insetLeft="11dp" + android:insetRight="11dp" />
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_check.xml b/packages/SystemUI/res/drawable/ic_check.xml new file mode 100644 index 000000000000..80707d876146 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_check.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2024 The Android Open Source Project + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24"> + <path + android:pathData="M0 0h24v24H0z"/> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/> +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/bluetooth_device_item.xml b/packages/SystemUI/res/layout/bluetooth_device_item.xml index b9314c7ae0e0..124aec6a92dd 100644 --- a/packages/SystemUI/res/layout/bluetooth_device_item.xml +++ b/packages/SystemUI/res/layout/bluetooth_device_item.xml @@ -27,8 +27,8 @@ <ImageView android:id="@+id/bluetooth_device_icon" - android:layout_width="24dp" - android:layout_height="24dp" + android:layout_width="36dp" + android:layout_height="36dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" @@ -36,8 +36,8 @@ <TextView android:layout_width="0dp" + android:layout_height="wrap_content" android:id="@+id/bluetooth_device_name" - style="@style/BluetoothTileDialog.DeviceName" android:textDirection="locale" android:textAlignment="gravity" android:paddingStart="20dp" @@ -54,8 +54,8 @@ <TextView android:layout_width="0dp" + android:layout_height="wrap_content" android:id="@+id/bluetooth_device_summary" - style="@style/BluetoothTileDialog.DeviceSummary" android:paddingStart="20dp" android:paddingEnd="10dp" android:paddingBottom="15dp" @@ -65,7 +65,8 @@ app:layout_constraintStart_toEndOf="@+id/bluetooth_device_icon" app:layout_constraintEnd_toStartOf="@+id/guideline" app:layout_constraintBottom_toBottomOf="parent" - android:gravity="center_vertical" /> + android:gravity="center_vertical" + android:textSize="14sp" /> <androidx.constraintlayout.widget.Guideline android:layout_width="wrap_content" diff --git a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml index b4eaa407889a..1f937174dea3 100644 --- a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml +++ b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml @@ -32,7 +32,7 @@ android:ellipsize="end" android:gravity="center_vertical|center_horizontal" android:text="@string/quick_settings_bluetooth_label" - android:textAppearance="@style/TextAppearance.Dialog.Title" + android:textAppearance="@style/TextAppearance.BluetoothTileDialog" android:textSize="24sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -49,7 +49,8 @@ android:gravity="center_vertical|center_horizontal" android:maxLines="2" android:text="@string/quick_settings_bluetooth_tile_subtitle" - android:textAppearance="@style/TextAppearance.Dialog.Body.Message" + android:textSize="14sp" + android:textAppearance="@style/TextAppearance.BluetoothTileDialog" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/bluetooth_tile_dialog_title" /> @@ -105,7 +106,7 @@ android:paddingStart="36dp" android:text="@string/turn_on_bluetooth" android:clickable="false" - android:textAppearance="@style/TextAppearance.Dialog.Title" + android:textAppearance="@style/TextAppearance.BluetoothTileDialog" android:textSize="16sp" app:layout_constraintEnd_toStartOf="@+id/bluetooth_toggle" app:layout_constraintStart_toStartOf="parent" @@ -146,7 +147,7 @@ android:paddingEnd="15dp" android:paddingStart="36dp" android:clickable="false" - android:textAppearance="@style/TextAppearance.Dialog.Title" + android:textAppearance="@style/TextAppearance.BluetoothTileDialog" android:textSize="16sp" app:layout_constraintEnd_toStartOf="@+id/bluetooth_auto_on_toggle" app:layout_constraintStart_toStartOf="parent" @@ -187,7 +188,8 @@ android:layout_marginTop="20dp" android:paddingStart="36dp" android:paddingEnd="40dp" - android:textAppearance="@style/TextAppearance.Dialog.Body.Message" + android:textSize="14sp" + android:textAppearance="@style/TextAppearance.BluetoothTileDialog" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/bluetooth_auto_on_toggle_info_icon" /> @@ -204,7 +206,7 @@ android:id="@+id/see_all_button" style="@style/BluetoothTileDialog.Device" android:paddingEnd="0dp" - android:paddingStart="20dp" + android:paddingStart="26dp" android:background="@drawable/bluetooth_tile_dialog_bg_off" android:layout_width="0dp" android:layout_height="64dp" @@ -214,11 +216,11 @@ app:layout_constraintTop_toBottomOf="@+id/device_list" app:layout_constraintBottom_toTopOf="@+id/pair_new_device_button" android:drawableStart="@drawable/ic_arrow_forward" - android:drawablePadding="20dp" + android:drawablePadding="26dp" android:drawableTint="?android:attr/textColorPrimary" android:text="@string/see_all_bluetooth_devices" android:textSize="14sp" - android:textAppearance="@style/TextAppearance.Dialog.Title" + android:textAppearance="@style/TextAppearance.BluetoothTileDialog" android:textDirection="locale" android:textAlignment="viewStart" android:maxLines="1" @@ -229,7 +231,7 @@ android:id="@+id/pair_new_device_button" style="@style/BluetoothTileDialog.Device" android:paddingEnd="0dp" - android:paddingStart="20dp" + android:paddingStart="26dp" android:background="@drawable/bluetooth_tile_dialog_bg_off" android:layout_width="0dp" android:layout_height="64dp" @@ -238,11 +240,11 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/see_all_button" android:drawableStart="@drawable/ic_add" - android:drawablePadding="20dp" + android:drawablePadding="26dp" android:drawableTint="?android:attr/textColorPrimary" android:text="@string/pair_new_bluetooth_devices" android:textSize="14sp" - android:textAppearance="@style/TextAppearance.Dialog.Title" + android:textAppearance="@style/TextAppearance.BluetoothTileDialog" android:textDirection="locale" android:textAlignment="viewStart" android:maxLines="1" @@ -259,6 +261,7 @@ <Button android:id="@+id/audio_sharing_button" style="@style/BluetoothTileDialog.AudioSharingButton" + android:textAppearance="@style/TextAppearance.BluetoothTileDialog" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="9dp" @@ -282,6 +285,7 @@ <Button android:id="@+id/done_button" style="@style/Widget.Dialog.Button" + android:textAppearance="@style/TextAppearance.BluetoothTileDialog" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="9dp" diff --git a/packages/SystemUI/res/layout/hearing_devices_preset_spinner_selected.xml b/packages/SystemUI/res/layout/hearing_devices_preset_spinner_selected.xml deleted file mode 100644 index d512e7c3a433..000000000000 --- a/packages/SystemUI/res/layout/hearing_devices_preset_spinner_selected.xml +++ /dev/null @@ -1,48 +0,0 @@ -<!-- - Copyright (C) 2024 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:minHeight="@dimen/hearing_devices_preset_spinner_height" - android:paddingStart="@dimen/hearing_devices_preset_spinner_text_padding_start" - android:paddingTop="@dimen/hearing_devices_preset_spinner_text_padding_vertical" - android:paddingBottom="@dimen/hearing_devices_preset_spinner_text_padding_vertical" - android:orientation="vertical"> - <TextView - android:layout_width="match_parent" - android:layout_height="0dp" - android:textAppearance="@style/TextAppearance.Dialog.Title" - android:lineSpacingExtra="6dp" - android:text="@string/hearing_devices_preset_label" - android:fontFamily="@*android:string/config_headlineFontFamilyMedium" - android:textSize="14sp" - android:gravity="center_vertical" - android:textDirection="locale" - android:layout_weight="1" /> - <TextView - android:id="@+id/hearing_devices_preset_option_text" - android:layout_width="match_parent" - android:layout_height="0dp" - android:textAppearance="@style/TextAppearance.Dialog.Body" - android:lineSpacingExtra="6dp" - android:gravity="center_vertical" - android:ellipsize="end" - android:maxLines="1" - android:textDirection="locale" - android:layout_weight="1" /> -</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/hearing_devices_spinner_dropdown_view.xml b/packages/SystemUI/res/layout/hearing_devices_spinner_dropdown_view.xml new file mode 100644 index 000000000000..70f2cd5fcc28 --- /dev/null +++ b/packages/SystemUI/res/layout/hearing_devices_spinner_dropdown_view.xml @@ -0,0 +1,45 @@ +<!-- + Copyright (C) 2024 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" + android:layout_width="match_parent" + android:layout_height="@dimen/bluetooth_dialog_device_height" + android:paddingStart="@dimen/hearing_devices_preset_spinner_padding" + android:paddingEnd="@dimen/hearing_devices_preset_spinner_padding" + android:orientation="horizontal"> + + <ImageView + android:id="@+id/hearing_devices_spinner_check_icon" + android:layout_width="@dimen/hearing_devices_preset_spinner_icon_size" + android:layout_height="@dimen/hearing_devices_preset_spinner_icon_size" + android:layout_gravity="center_vertical" + android:layout_marginEnd="@dimen/hearing_devices_layout_margin" + android:tint="?androidprv:attr/materialColorOnPrimaryContainer" + android:src="@drawable/ic_check" + android:contentDescription="@string/hearing_devices_spinner_item_selected"/> + <TextView + android:id="@+id/hearing_devices_spinner_text" + style="?android:attr/spinnerDropDownItemStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:textDirection="locale" + android:paddingStart="0dp" + android:maxLines="1" + android:ellipsize="end" /> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/hearing_devices_spinner_view.xml b/packages/SystemUI/res/layout/hearing_devices_spinner_view.xml new file mode 100644 index 000000000000..75742440e889 --- /dev/null +++ b/packages/SystemUI/res/layout/hearing_devices_spinner_view.xml @@ -0,0 +1,32 @@ +<!-- + Copyright (C) 2024 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="@dimen/bluetooth_dialog_device_height" + android:paddingStart="@dimen/hearing_devices_preset_spinner_padding" + android:paddingEnd="@dimen/hearing_devices_preset_spinner_padding"> + <TextView + android:id="@+id/hearing_devices_spinner_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.Dialog.Body" + android:layout_gravity="center_vertical" + android:ellipsize="end" + android:maxLines="1" + android:textDirection="locale" /> +</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml b/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml index 80692f9481b7..bf04a6f64d6a 100644 --- a/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml +++ b/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml @@ -28,50 +28,16 @@ android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintBottom_toTopOf="@id/preset_spinner" /> - - <Spinner - android:id="@+id/preset_spinner" - style="@style/BluetoothTileDialog.Device" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/hearing_devices_layout_margin" - android:minHeight="@dimen/hearing_devices_preset_spinner_height" - android:gravity="center_vertical" - android:background="@drawable/hearing_devices_preset_spinner_background" - android:popupBackground="@drawable/hearing_devices_preset_spinner_popup_background" - android:dropDownVerticalOffset="@dimen/hearing_devices_preset_spinner_height" - android:dropDownWidth="match_parent" - android:paddingStart="0dp" - android:paddingEnd="0dp" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@id/device_list" - app:layout_constraintBottom_toTopOf="@id/pair_new_device_button" - android:longClickable="false" - android:visibility="gone"/> - - <androidx.constraintlayout.widget.Barrier - android:id="@+id/device_function_barrier" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:barrierAllowsGoneWidgets="false" - app:barrierDirection="bottom" - app:constraint_referenced_ids="device_list,preset_spinner" /> + app:layout_constraintEnd_toEndOf="parent" /> <Button android:id="@+id/pair_new_device_button" style="@style/BluetoothTileDialog.Device" - android:paddingEnd="0dp" - android:paddingStart="20dp" - android:background="@drawable/bluetooth_tile_dialog_bg_off" - android:layout_width="0dp" - android:layout_height="64dp" - android:contentDescription="@string/accessibility_hearing_device_pair_new_device" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@id/device_function_barrier" + app:layout_constraintTop_toBottomOf="@id/device_list" + android:layout_height="@dimen/bluetooth_dialog_device_height" + android:contentDescription="@string/accessibility_hearing_device_pair_new_device" android:drawableStart="@drawable/ic_add" android:drawablePadding="20dp" android:drawableTint="?android:attr/textColorPrimary" @@ -81,26 +47,75 @@ android:textDirection="locale" android:textAlignment="viewStart" android:maxLines="1" - android:ellipsize="end" /> + android:ellipsize="end" + android:background="@drawable/bluetooth_tile_dialog_bg_off" /> - <androidx.constraintlayout.widget.Barrier - android:id="@+id/device_barrier" - android:layout_width="wrap_content" + <LinearLayout + android:id="@+id/preset_layout" + android:layout_width="match_parent" android:layout_height="wrap_content" - app:barrierAllowsGoneWidgets="false" - app:barrierDirection="bottom" - app:constraint_referenced_ids="device_function_barrier, pair_new_device_button" /> + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/pair_new_device_button" + android:layout_marginTop="@dimen/hearing_devices_layout_margin" + android:orientation="vertical"> + <TextView + android:id="@+id/preset_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/bluetooth_dialog_layout_margin" + android:layout_marginEnd="@dimen/bluetooth_dialog_layout_margin" + android:paddingStart="@dimen/hearing_devices_small_title_padding_horizontal" + android:text="@string/hearing_devices_preset_label" + android:textAppearance="@style/TextAppearance.Dialog.Title" + android:textSize="14sp" + android:gravity="center_vertical" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" + android:textDirection="locale"/> + <Spinner + android:id="@+id/preset_spinner" + style="@style/BluetoothTileDialog.Device" + android:layout_height="@dimen/bluetooth_dialog_device_height" + android:layout_marginTop="4dp" + android:paddingStart="0dp" + android:paddingEnd="0dp" + android:background="@drawable/hearing_devices_spinner_background" + android:popupBackground="@drawable/hearing_devices_spinner_popup_background" + android:dropDownWidth="match_parent" + android:longClickable="false"/> + </LinearLayout> <LinearLayout - android:id="@+id/related_tools_container" + android:id="@+id/tools_layout" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/bluetooth_dialog_layout_margin" - android:layout_marginEnd="@dimen/bluetooth_dialog_layout_margin" - android:layout_marginTop="@dimen/hearing_devices_layout_margin" - android:orientation="horizontal" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@id/device_barrier" /> + app:layout_constraintTop_toBottomOf="@id/preset_layout" + android:layout_marginTop="@dimen/hearing_devices_layout_margin" + android:orientation="vertical"> + <TextView + android:id="@+id/tools_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/bluetooth_dialog_layout_margin" + android:layout_marginEnd="@dimen/bluetooth_dialog_layout_margin" + android:paddingStart="@dimen/hearing_devices_small_title_padding_horizontal" + android:text="@string/hearing_devices_tools_label" + android:textAppearance="@style/TextAppearance.Dialog.Title" + android:textSize="14sp" + android:gravity="center_vertical" + android:fontFamily="@*android:string/config_headlineFontFamilyMedium" + android:textDirection="locale"/> + <LinearLayout + android:id="@+id/tools_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/bluetooth_dialog_layout_margin" + android:layout_marginEnd="@dimen/bluetooth_dialog_layout_margin" + android:layout_marginTop="4dp" + android:orientation="horizontal"/> + </LinearLayout> + </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/hearing_tool_item.xml b/packages/SystemUI/res/layout/hearing_tool_item.xml index f5baf2aaf6dc..da9178b56d73 100644 --- a/packages/SystemUI/res/layout/hearing_tool_item.xml +++ b/packages/SystemUI/res/layout/hearing_tool_item.xml @@ -46,7 +46,7 @@ android:textAlignment="center" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/hearing_devices_layout_margin" + android:layout_marginTop="4dp" android:ellipsize="end" android:textSize="12sp" android:maxLines="3" diff --git a/packages/SystemUI/res/layout/split_clock_view.xml b/packages/SystemUI/res/layout/split_clock_view.xml deleted file mode 100644 index 8198f0333a94..000000000000 --- a/packages/SystemUI/res/layout/split_clock_view.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (C) 2014 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License - --> - -<!-- Extends LinearLayout --> -<com.android.systemui.statusbar.policy.SplitClockView - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - > - <TextClock - android:id="@+id/time_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:singleLine="true" - android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock" - android:textSize="@dimen/qs_time_collapsed_size" - android:textColor="?android:attr/textColorPrimary" - /> - <TextClock - android:id="@+id/am_pm_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:singleLine="true" - android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock" - android:textSize="@dimen/qs_time_collapsed_size" - android:textColor="?android:attr/textColorPrimary" - android:importantForAccessibility="no" - /> - - <!-- Empty text view so we have the same height when expanded/collapsed--> - <TextView - android:id="@+id/empty_time_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:visibility="gone" - android:singleLine="true" - android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock" - android:textColor="?android:attr/textColorPrimary" - /> -</com.android.systemui.statusbar.policy.SplitClockView> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 67eb5b0fdf6b..7af005721e13 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1805,10 +1805,9 @@ <!-- Hearing devices dialog related dimensions --> <dimen name="hearing_devices_layout_margin">12dp</dimen> - <dimen name="hearing_devices_preset_spinner_height">72dp</dimen> - <dimen name="hearing_devices_preset_spinner_text_padding_start">20dp</dimen> - <dimen name="hearing_devices_preset_spinner_text_padding_vertical">15dp</dimen> - <dimen name="hearing_devices_preset_spinner_arrow_size">24dp</dimen> + <dimen name="hearing_devices_small_title_padding_horizontal">16dp</dimen> + <dimen name="hearing_devices_preset_spinner_padding">22dp</dimen> + <dimen name="hearing_devices_preset_spinner_icon_size">24dp</dimen> <dimen name="hearing_devices_preset_spinner_background_radius">28dp</dimen> <dimen name="hearing_devices_tool_icon_size">28dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 53ab686ff0d7..b45aaddef183 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1002,6 +1002,10 @@ <string name="hearing_devices_presets_error">Couldn\'t update preset</string> <!-- QuickSettings: Title for hearing aids presets. Preset is a set of hearing aid settings. User can apply different settings in different environments (e.g. Outdoor, Restaurant, Home) [CHAR LIMIT=40]--> <string name="hearing_devices_preset_label">Preset</string> + <!-- QuickSettings: Content description for the icon that indicates the item is selected [CHAR LIMIT=NONE]--> + <string name="hearing_devices_spinner_item_selected">Selected</string> + <!-- QuickSettings: Title for related tools of hearing. [CHAR LIMIT=40]--> + <string name="hearing_devices_tools_label">Tools</string> <!-- QuickSettings: Tool name for hearing devices dialog related tools [CHAR LIMIT=40] [BACKUP_MESSAGE_ID=8916875614623730005]--> <string name="quick_settings_hearing_devices_live_caption_title">Live Caption</string> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index c69b98c8c37f..e14008a7773b 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -1481,28 +1481,14 @@ <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item> </style> - <style name="BluetoothTileDialog.Device.Active"> - <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item> - </style> - - <style name="BluetoothTileDialog.DeviceName"> - <item name="android:textSize">14sp</item> - <item name="android:textAppearance">@style/TextAppearance.Dialog.Title</item> + <style name="TextAppearance.BluetoothTileDialog"> + <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item> + <item name="android:textDirection">locale</item> + <item name="android:textAlignment">gravity</item> <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item> </style> - <style name="BluetoothTileDialog.DeviceSummary"> - <item name="android:ellipsize">end</item> - <item name="android:maxLines">2</item> - <item name="android:textAppearance">@style/TextAppearance.Dialog.Body.Message</item> - <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item> - </style> - - <style name="BluetoothTileDialog.DeviceName.Active"> - <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item> - </style> - - <style name="BluetoothTileDialog.DeviceSummary.Active"> + <style name="TextAppearance.BluetoothTileDialog.Active"> <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item> </style> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java index 1342dd05d7f2..95830b5f4ed7 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java @@ -15,6 +15,8 @@ */ package com.android.keyguard; +import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; + import android.annotation.NonNull; import android.app.Presentation; import android.content.Context; @@ -36,18 +38,24 @@ import android.view.WindowManager; import androidx.annotation.Nullable; import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.dagger.qualifiers.Application; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.navigationbar.NavigationBarController; import com.android.systemui.navigationbar.views.NavigationBarView; import com.android.systemui.settings.DisplayTracker; +import com.android.systemui.shade.data.repository.ShadePositionRepository; +import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround; import com.android.systemui.statusbar.policy.KeyguardStateController; import dagger.Lazy; +import kotlinx.coroutines.CoroutineScope; + import java.util.concurrent.Executor; import javax.inject.Inject; +import javax.inject.Provider; @SysUISingleton public class KeyguardDisplayManager { @@ -58,6 +66,7 @@ public class KeyguardDisplayManager { private final DisplayManager mDisplayService; private final DisplayTracker mDisplayTracker; private final Lazy<NavigationBarController> mNavigationBarControllerLazy; + private final Provider<ShadePositionRepository> mShadePositionRepositoryProvider; private final ConnectedDisplayKeyguardPresentation.Factory mConnectedDisplayKeyguardPresentationFactory; private final Context mContext; @@ -102,9 +111,12 @@ public class KeyguardDisplayManager { DeviceStateHelper deviceStateHelper, KeyguardStateController keyguardStateController, ConnectedDisplayKeyguardPresentation.Factory - connectedDisplayKeyguardPresentationFactory) { + connectedDisplayKeyguardPresentationFactory, + Provider<ShadePositionRepository> shadePositionRepositoryProvider, + @Application CoroutineScope appScope) { mContext = context; mNavigationBarControllerLazy = navigationBarControllerLazy; + mShadePositionRepositoryProvider = shadePositionRepositoryProvider; uiBgExecutor.execute(() -> mMediaRouter = mContext.getSystemService(MediaRouter.class)); mDisplayService = mContext.getSystemService(DisplayManager.class); mDisplayTracker = displayTracker; @@ -112,6 +124,17 @@ public class KeyguardDisplayManager { mDeviceStateHelper = deviceStateHelper; mKeyguardStateController = keyguardStateController; mConnectedDisplayKeyguardPresentationFactory = connectedDisplayKeyguardPresentationFactory; + if (ShadeWindowGoesAround.isEnabled()) { + collectFlow(appScope, shadePositionRepositoryProvider.get().getDisplayId(), + (id) -> onShadeWindowMovedToDisplayId(id)); + } + } + + private void onShadeWindowMovedToDisplayId(int shadeDisplayId) { + if (mShowing) { + hidePresentation(shadeDisplayId); + updateDisplays(/* showing= */ true); + } } private boolean isKeyguardShowable(Display display) { @@ -119,9 +142,20 @@ public class KeyguardDisplayManager { if (DEBUG) Log.i(TAG, "Cannot show Keyguard on null display"); return false; } - if (display.getDisplayId() == mDisplayTracker.getDefaultDisplayId()) { - if (DEBUG) Log.i(TAG, "Do not show KeyguardPresentation on the default display"); - return false; + if (ShadeWindowGoesAround.isEnabled()) { + int shadeDisplayId = mShadePositionRepositoryProvider.get().getDisplayId().getValue(); + if (display.getDisplayId() == shadeDisplayId) { + if (DEBUG) { + Log.i(TAG, + "Do not show KeyguardPresentation on the shade window display"); + } + return false; + } + } else { + if (display.getDisplayId() == mDisplayTracker.getDefaultDisplayId()) { + if (DEBUG) Log.i(TAG, "Do not show KeyguardPresentation on the default display"); + return false; + } } display.getDisplayInfo(mTmpDisplayInfo); if ((mTmpDisplayInfo.flags & Display.FLAG_PRIVATE) != 0) { diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java index 1978bb89b5b2..1f21af80cebb 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java @@ -35,10 +35,9 @@ import android.provider.Settings; import android.util.Log; import android.view.LayoutInflater; import android.view.View; -import android.view.View.Visibility; +import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.AdapterView; -import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; @@ -114,10 +113,9 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, private SystemUIDialog mDialog; private RecyclerView mDeviceList; private List<DeviceItem> mHearingDeviceItemList; + private View mPresetLayout; private Spinner mPresetSpinner; - private ArrayAdapter<String> mPresetInfoAdapter; - private Button mPairButton; - private LinearLayout mRelatedToolsContainer; + private HearingDevicesSpinnerAdapter mPresetInfoAdapter; private final HearingDevicesPresetsController.PresetCallback mPresetCallback = new HearingDevicesPresetsController.PresetCallback() { @Override @@ -245,7 +243,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, mPresetsController.getAllPresetInfo(); final int activePresetIndex = mPresetsController.getActivePresetIndex(); refreshPresetInfoAdapter(presetInfos, activePresetIndex); - mPresetSpinner.setVisibility( + mPresetLayout.setVisibility( (activeHearingDevice != null && activeHearingDevice.isConnectedHapClientDevice() && !mPresetInfoAdapter.isEmpty()) ? VISIBLE : GONE); }); @@ -291,14 +289,13 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, } mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_DIALOG_SHOW, mLaunchSourceId); - mPairButton = dialog.requireViewById(R.id.pair_new_device_button); mDeviceList = dialog.requireViewById(R.id.device_list); + mPresetLayout = dialog.requireViewById(R.id.preset_layout); mPresetSpinner = dialog.requireViewById(R.id.preset_spinner); - mRelatedToolsContainer = dialog.requireViewById(R.id.related_tools_container); setupDeviceListView(dialog); setupPresetSpinner(dialog); - setupPairNewDeviceButton(dialog, mShowPairNewDevice ? VISIBLE : GONE); + setupPairNewDeviceButton(dialog); if (com.android.systemui.Flags.hearingDevicesDialogRelatedTools()) { setupRelatedToolsView(dialog); } @@ -353,11 +350,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, mHearingDeviceItemList); mPresetsController.setHearingDeviceIfSupportHap(activeHearingDevice); - mPresetInfoAdapter = new ArrayAdapter<>(dialog.getContext(), - R.layout.hearing_devices_preset_spinner_selected, - R.id.hearing_devices_preset_option_text); - mPresetInfoAdapter.setDropDownViewResource( - R.layout.hearing_devices_preset_dropdown_item); + mPresetInfoAdapter = new HearingDevicesSpinnerAdapter(dialog.getContext()); mPresetSpinner.setAdapter(mPresetInfoAdapter); // disable redundant Touch & Hold accessibility action for Switch Access @@ -378,6 +371,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, mPresetSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { + mPresetInfoAdapter.setSelected(position); mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_PRESET_SELECT, mLaunchSourceId); mPresetsController.selectPreset( @@ -389,14 +383,17 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, // Do nothing } }); - mPresetSpinner.setVisibility( + mPresetLayout.setVisibility( (activeHearingDevice != null && activeHearingDevice.isConnectedHapClientDevice() && !mPresetInfoAdapter.isEmpty()) ? VISIBLE : GONE); } - private void setupPairNewDeviceButton(SystemUIDialog dialog, @Visibility int visibility) { - if (visibility == VISIBLE) { - mPairButton.setOnClickListener(v -> { + private void setupPairNewDeviceButton(SystemUIDialog dialog) { + final Button pairButton = dialog.requireViewById(R.id.pair_new_device_button); + + pairButton.setVisibility(mShowPairNewDevice ? VISIBLE : GONE); + if (mShowPairNewDevice) { + pairButton.setOnClickListener(v -> { mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_PAIR, mLaunchSourceId); dismissDialogIfExists(); final Intent intent = new Intent(Settings.ACTION_HEARING_DEVICE_PAIRING_SETTINGS); @@ -404,12 +401,11 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, mActivityStarter.postStartActivityDismissingKeyguard(intent, /* delay= */ 0, mDialogTransitionAnimator.createActivityTransitionController(dialog)); }); - } else { - mPairButton.setVisibility(GONE); } } private void setupRelatedToolsView(SystemUIDialog dialog) { + final Context context = dialog.getContext(); final List<ToolItem> toolItemList = new ArrayList<>(); final String[] toolNameArray; @@ -430,15 +426,20 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, } catch (Resources.NotFoundException e) { Log.i(TAG, "No hearing devices related tool config resource"); } + + final View toolsLayout = dialog.requireViewById(R.id.tools_layout); + toolsLayout.setVisibility(toolItemList.isEmpty() ? GONE : VISIBLE); + + final LinearLayout toolsContainer = dialog.requireViewById(R.id.tools_container); for (int i = 0; i < toolItemList.size(); i++) { - View view = createHearingToolView(context, toolItemList.get(i)); - mRelatedToolsContainer.addView(view); + View view = createHearingToolView(context, toolItemList.get(i), toolsContainer); + toolsContainer.addView(view); if (i != toolItemList.size() - 1) { final int spaceSize = context.getResources().getDimensionPixelSize( R.dimen.hearing_devices_layout_margin); Space space = new Space(context); space.setLayoutParams(new LinearLayout.LayoutParams(spaceSize, 0)); - mRelatedToolsContainer.addView(space); + toolsContainer.addView(space); } } } @@ -453,6 +454,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, for (int position = 0; position < size; position++) { if (presetInfos.get(position).getIndex() == activePresetIndex) { mPresetSpinner.setSelection(position, /* animate= */ false); + mPresetInfoAdapter.setSelected(position); } } } @@ -493,9 +495,9 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, } @NonNull - private View createHearingToolView(Context context, ToolItem item) { - View view = LayoutInflater.from(context).inflate(R.layout.hearing_tool_item, - mRelatedToolsContainer, false); + private View createHearingToolView(Context context, ToolItem item, ViewGroup container) { + View view = LayoutInflater.from(context).inflate(R.layout.hearing_tool_item, container, + false); ImageView icon = view.requireViewById(R.id.tool_icon); TextView text = view.requireViewById(R.id.tool_name); view.setContentDescription(item.getToolName()); diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java index 9367cb5c0198..e47e4b27d58a 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java @@ -138,19 +138,18 @@ public class HearingDevicesListAdapter extends RecyclerView.Adapter<RecyclerView Pair<Drawable, String> iconPair = item.getIconWithDescription(); if (iconPair != null) { - Drawable drawable = iconPair.getFirst().mutate(); - drawable.setTint(tintColor); + Drawable drawable = iconPair.getFirst(); mIconView.setImageDrawable(drawable); mIconView.setContentDescription(iconPair.getSecond()); } mNameView.setTextAppearance( - item.isActive() ? R.style.BluetoothTileDialog_DeviceName_Active - : R.style.BluetoothTileDialog_DeviceName); + item.isActive() ? R.style.TextAppearance_BluetoothTileDialog_Active + : R.style.TextAppearance_BluetoothTileDialog); mNameView.setText(item.getDeviceName()); mSummaryView.setTextAppearance( - item.isActive() ? R.style.BluetoothTileDialog_DeviceSummary_Active - : R.style.BluetoothTileDialog_DeviceSummary); + item.isActive() ? R.style.TextAppearance_BluetoothTileDialog_Active + : R.style.TextAppearance_BluetoothTileDialog); mSummaryView.setText(item.getConnectionSummary()); mGearIcon.getDrawable().mutate().setTint(tintColor); diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesSpinnerAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesSpinnerAdapter.java new file mode 100644 index 000000000000..28d742cfa49b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesSpinnerAdapter.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.accessibility.hearingaid; + +import static android.view.View.GONE; +import static android.view.View.VISIBLE; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.settingslib.Utils; +import com.android.systemui.res.R; + +/** + * An ArrayAdapter which was used by Spinner in hearing devices dialog. + */ +public class HearingDevicesSpinnerAdapter extends ArrayAdapter<String> { + + private final Context mContext; + private int mSelectedPosition; + + public HearingDevicesSpinnerAdapter(@NonNull Context context) { + super(context, R.layout.hearing_devices_spinner_view, + R.id.hearing_devices_spinner_text); + setDropDownViewResource(R.layout.hearing_devices_spinner_dropdown_view); + mContext = context; + } + + @Override + public View getDropDownView(int position, @Nullable View convertView, + @NonNull ViewGroup parent) { + + View view = super.getDropDownView(position, convertView, parent); + + final boolean isSelected = position == mSelectedPosition; + view.setBackgroundResource(isSelected + ? R.drawable.hearing_devices_spinner_selected_background + : R.drawable.bluetooth_tile_dialog_bg_off); + + View checkIcon = view.findViewById(R.id.hearing_devices_spinner_check_icon); + if (checkIcon != null) { + checkIcon.setVisibility(isSelected ? VISIBLE : GONE); + } + + TextView text = view.findViewById(R.id.hearing_devices_spinner_text); + if (text != null) { + int tintColor = Utils.getColorAttr(mContext, + isSelected ? com.android.internal.R.attr.materialColorOnPrimaryContainer + : com.android.internal.R.attr.materialColorOnSurface).getDefaultColor(); + text.setTextColor(tintColor); + } + return view; + } + + /** + * Sets the selected position into this adapter. The selected item will have different UI in + * the dropdown view. + * + * @param position the selected position + */ + public void setSelected(int position) { + mSelectedPosition = position; + notifyDataSetChanged(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt index a9c5c69ca26e..d7a0fc9770ee 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt @@ -100,7 +100,7 @@ internal constructor( initialUiProperties: BluetoothTileDialogViewModel.UiProperties, cachedContentHeight: Int, dialogCallback: BluetoothTileDialogCallback, - dimissListener: Runnable + dimissListener: Runnable, ): BluetoothTileDialogDelegate } @@ -135,7 +135,7 @@ internal constructor( object : AccessibilityDelegate() { override fun onInitializeAccessibilityNodeInfo( host: View, - info: AccessibilityNodeInfo + info: AccessibilityNodeInfo, ) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction( @@ -144,7 +144,7 @@ internal constructor( context.getString( R.string .quick_settings_bluetooth_audio_sharing_button_accessibility - ) + ), ) ) } @@ -180,7 +180,7 @@ internal constructor( dialog: SystemUIDialog, deviceItem: List<DeviceItem>, showSeeAll: Boolean, - showPairNewDevice: Boolean + showPairNewDevice: Boolean, ) { withContext(mainDispatcher) { val start = systemClock.elapsedRealtime() @@ -207,7 +207,7 @@ internal constructor( internal fun onBluetoothStateUpdated( dialog: SystemUIDialog, isEnabled: Boolean, - uiProperties: BluetoothTileDialogViewModel.UiProperties + uiProperties: BluetoothTileDialogViewModel.UiProperties, ) { getToggleView(dialog).apply { isChecked = isEnabled @@ -221,7 +221,7 @@ internal constructor( internal fun onBluetoothAutoOnUpdated( dialog: SystemUIDialog, isEnabled: Boolean, - @StringRes infoResId: Int + @StringRes infoResId: Int, ) { getAutoOnToggle(dialog).isChecked = isEnabled getAutoOnToggleInfoTextView(dialog).text = dialog.context.getString(infoResId) @@ -231,7 +231,7 @@ internal constructor( dialog: SystemUIDialog, visibility: Int, label: String?, - isActive: Boolean + isActive: Boolean, ) { getAudioSharingButtonView(dialog).apply { this.visibility = visibility @@ -339,14 +339,14 @@ internal constructor( object : DiffUtil.ItemCallback<DeviceItem>() { override fun areItemsTheSame( deviceItem1: DeviceItem, - deviceItem2: DeviceItem + deviceItem2: DeviceItem, ): Boolean { return deviceItem1.cachedBluetoothDevice == deviceItem2.cachedBluetoothDevice } override fun areContentsTheSame( deviceItem1: DeviceItem, - deviceItem2: DeviceItem + deviceItem2: DeviceItem, ): Boolean { return deviceItem1.type == deviceItem2.type && deviceItem1.cachedBluetoothDevice == deviceItem2.cachedBluetoothDevice && @@ -394,7 +394,7 @@ internal constructor( internal fun bind( item: DeviceItem, - deviceItemOnClickCallback: BluetoothTileDialogCallback + deviceItemOnClickCallback: BluetoothTileDialogCallback, ) { container.apply { isEnabled = item.isEnabled @@ -409,14 +409,14 @@ internal constructor( com.android.settingslib.Utils.getColorAttr( context, if (item.isActive) InternalR.attr.materialColorOnPrimaryContainer - else InternalR.attr.materialColorOnSurface + else InternalR.attr.materialColorOnSurface, ) .defaultColor // update icons iconView.apply { item.iconWithDescription?.let { - setImageDrawable(it.first.apply { mutate()?.setTint(tintColor) }) + setImageDrawable(it.first) contentDescription = it.second } } @@ -427,25 +427,25 @@ internal constructor( // update text styles nameView.setTextAppearance( - if (item.isActive) R.style.BluetoothTileDialog_DeviceName_Active - else R.style.BluetoothTileDialog_DeviceName + if (item.isActive) R.style.TextAppearance_BluetoothTileDialog_Active + else R.style.TextAppearance_BluetoothTileDialog ) summaryView.setTextAppearance( - if (item.isActive) R.style.BluetoothTileDialog_DeviceSummary_Active - else R.style.BluetoothTileDialog_DeviceSummary + if (item.isActive) R.style.TextAppearance_BluetoothTileDialog_Active + else R.style.TextAppearance_BluetoothTileDialog ) accessibilityDelegate = object : AccessibilityDelegate() { override fun onInitializeAccessibilityNodeInfo( host: View, - info: AccessibilityNodeInfo + info: AccessibilityNodeInfo, ) { super.onInitializeAccessibilityNodeInfo(host, info) info.addAction( AccessibilityAction( AccessibilityAction.ACTION_CLICK.id, - item.actionAccessibilityLabel + item.actionAccessibilityLabel, ) ) } diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt index 292137377f55..92f05803f7cf 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt @@ -57,7 +57,6 @@ abstract class DeviceItemFactory { companion object { @JvmStatic fun createDeviceItem( - context: Context, cachedDevice: CachedBluetoothDevice, type: DeviceItemType, connectionSummary: String, @@ -71,9 +70,7 @@ abstract class DeviceItemFactory { deviceName = cachedDevice.name, connectionSummary = connectionSummary, iconWithDescription = - BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { - Pair(it.first, it.second) - }, + cachedDevice.drawableWithDescription.let { Pair(it.first, it.second) }, background = background, isEnabled = !cachedDevice.isBusy, actionAccessibilityLabel = actionAccessibilityLabel, @@ -96,7 +93,6 @@ internal open class ActiveMediaDeviceItemFactory : DeviceItemFactory() { override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem { return createDeviceItem( - context, cachedDevice, DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE, cachedDevice.connectionSummary ?: "", @@ -122,7 +118,6 @@ internal class AudioSharingMediaDeviceItemFactory( override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem { return createDeviceItem( - context, cachedDevice, DeviceItemType.AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE, cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() } @@ -153,7 +148,6 @@ internal class AvailableAudioSharingMediaDeviceItemFactory( override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem { return createDeviceItem( - context, cachedDevice, DeviceItemType.AVAILABLE_AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE, context.getString( @@ -191,7 +185,6 @@ open class AvailableMediaDeviceItemFactory : DeviceItemFactory() { override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem { return createDeviceItem( - context, cachedDevice, DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE, cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() } @@ -232,7 +225,6 @@ internal class ConnectedDeviceItemFactory : DeviceItemFactory() { override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem { return createDeviceItem( - context, cachedDevice, DeviceItemType.CONNECTED_BLUETOOTH_DEVICE, cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() } @@ -262,7 +254,6 @@ internal open class SavedDeviceItemFactory : DeviceItemFactory() { override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem { return createDeviceItem( - context, cachedDevice, DeviceItemType.SAVED_BLUETOOTH_DEVICE, cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() } diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt index 917a4ff9036b..ccd953de7d03 100644 --- a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt +++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt @@ -24,6 +24,7 @@ import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CornerSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -31,7 +32,6 @@ import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue @@ -61,6 +61,7 @@ import com.android.systemui.haptics.slider.SeekableSliderTrackerConfig import com.android.systemui.haptics.slider.SliderHapticFeedbackConfig import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel import com.android.systemui.lifecycle.rememberViewModel +import com.android.systemui.qs.ui.compose.borderOnFocus import com.android.systemui.res.R import com.android.systemui.utils.PolicyRestriction @@ -102,11 +103,12 @@ private fun BrightnessSlider( null } - val overriddenByAppState by if (Flags.showToastWhenAppControlBrightness()) { - viewModel.brightnessOverriddenByWindow.collectAsStateWithLifecycle() - } else { - mutableStateOf(false) - } + val overriddenByAppState = + if (Flags.showToastWhenAppControlBrightness()) { + viewModel.brightnessOverriddenByWindow.collectAsStateWithLifecycle().value + } else { + false + } PlatformSlider( value = animatedValue, @@ -160,7 +162,7 @@ private fun BrightnessSlider( if (interaction is DragInteraction.Start && overriddenByAppState) { viewModel.showToast( context, - R.string.quick_settings_brightness_unable_adjust_msg + R.string.quick_settings_brightness_unable_adjust_msg, ) } } @@ -213,7 +215,11 @@ fun BrightnessSliderContainer( coroutineScope.launch { viewModel.onDrag(Drag.Stopped(GammaBrightness(it))) } }, modifier = - Modifier.then(if (viewModel.showMirror) Modifier.drawInOverlay() else Modifier) + Modifier.borderOnFocus( + color = MaterialTheme.colorScheme.secondary, + cornerSize = CornerSize(32.dp), + ) + .then(if (viewModel.showMirror) Modifier.drawInOverlay() else Modifier) .sliderBackground(containerColor) .fillMaxWidth(), formatter = viewModel::formatValue, diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/log/CommunalMetricsLogger.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/log/CommunalMetricsLogger.kt index 7cfad60b84cd..6423f8f7783b 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/shared/log/CommunalMetricsLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/shared/log/CommunalMetricsLogger.kt @@ -30,6 +30,7 @@ constructor( @Named(LOGGABLE_PREFIXES) private val loggablePrefixes: List<String>, private val statsLogProxy: StatsLogProxy, ) { + /** Logs an add widget event for metrics. No-op if widget is not loggable. */ fun logAddWidget(componentName: String, rank: Int?) { if (!componentName.isLoggable()) { @@ -69,11 +70,21 @@ constructor( ) } + fun logResizeWidget(componentName: String, rank: Int, spanY: Int = 0) { + if (!componentName.isLoggable()) { + return + } + + statsLogProxy.writeCommunalHubWidgetEventReported( + SysUiStatsLog.COMMUNAL_HUB_WIDGET_EVENT_REPORTED__ACTION__RESIZE, + componentName, + rank = rank, + spanY = spanY, + ) + } + /** Logs loggable widgets and the total widget count as a [StatsEvent]. */ - fun logWidgetsSnapshot( - statsEvents: MutableList<StatsEvent>, - componentNames: List<String>, - ) { + fun logWidgetsSnapshot(statsEvents: MutableList<StatsEvent>, componentNames: List<String>) { val loggableComponentNames = componentNames.filter { it.isLoggable() }.toTypedArray() statsEvents.add( statsLogProxy.buildCommunalHubSnapshotStatsEvent( @@ -95,6 +106,7 @@ constructor( action: Int, componentName: String, rank: Int, + spanY: Int = 0, ) /** Builds a [SysUiStatsLog.COMMUNAL_HUB_SNAPSHOT] stats event. */ @@ -112,12 +124,14 @@ class CommunalStatsLogProxyImpl @Inject constructor() : CommunalMetricsLogger.St action: Int, componentName: String, rank: Int, + spanY: Int, ) { SysUiStatsLog.write( SysUiStatsLog.COMMUNAL_HUB_WIDGET_EVENT_REPORTED, action, componentName, rank, + spanY, ) } diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt index e25ea4cbfb25..4e0e11226faa 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt @@ -178,7 +178,13 @@ abstract class BaseCommunalViewModel( * alongside the resize, in case resizing also requires re-ordering. This ensures the * re-ordering is done in the same database transaction as the resize. */ - open fun onResizeWidget(appWidgetId: Int, spanY: Int, widgetIdToRankMap: Map<Int, Int>) {} + open fun onResizeWidget( + appWidgetId: Int, + spanY: Int, + widgetIdToRankMap: Map<Int, Int>, + componentName: ComponentName, + rank: Int, + ) {} /** Called as the UI requests opening the widget editor with an optional preselected widget. */ open fun onOpenWidgetEditor(shouldOpenWidgetPickerOnStart: Boolean = false) {} diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt index 6508e4b574a3..ccff23003aa0 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt @@ -141,8 +141,19 @@ constructor( override fun onReorderWidgets(widgetIdToRankMap: Map<Int, Int>) = communalInteractor.updateWidgetOrder(widgetIdToRankMap) - override fun onResizeWidget(appWidgetId: Int, spanY: Int, widgetIdToRankMap: Map<Int, Int>) { + override fun onResizeWidget( + appWidgetId: Int, + spanY: Int, + widgetIdToRankMap: Map<Int, Int>, + componentName: ComponentName, + rank: Int, + ) { communalInteractor.resizeWidget(appWidgetId, spanY, widgetIdToRankMap) + metricsLogger.logResizeWidget( + componentName = componentName.flattenToString(), + rank = rank, + spanY = spanY, + ) } override fun onReorderWidgetStart() { diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 4447dff7af00..b7d3c9253f51 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -100,7 +100,7 @@ import com.android.systemui.qs.QSFragmentStartableModule; import com.android.systemui.qs.footer.dagger.FooterActionsModule; import com.android.systemui.recents.Recents; import com.android.systemui.recordissue.RecordIssueModule; -import com.android.systemui.retail.dagger.RetailModeModule; +import com.android.systemui.retail.RetailModeModule; import com.android.systemui.scene.shared.model.SceneContainerConfig; import com.android.systemui.scene.shared.model.SceneDataSource; import com.android.systemui.scene.shared.model.SceneDataSourceDelegator; diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt index 80eb9eea6c9b..f310b30c1a81 100644 --- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt @@ -27,6 +27,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.display.shared.model.DisplayWindowProperties import com.android.systemui.res.R +import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround import com.android.systemui.statusbar.core.StatusBarConnectedDisplays import com.google.common.collect.HashBasedTable import com.google.common.collect.Table @@ -60,7 +61,10 @@ constructor( ) : DisplayWindowPropertiesRepository, CoreStartable { init { - StatusBarConnectedDisplays.assertInNewMode() + check(StatusBarConnectedDisplays.isEnabled || ShadeWindowGoesAround.isEnabled) { + "This should be instantiated only when wither StatusBarConnectedDisplays or " + + "ShadeWindowGoesAround are enabled." + } } private val properties: Table<Int, Int, DisplayWindowProperties> = HashBasedTable.create() diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt index ecddef6ee843..711534f9dbf0 100644 --- a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt +++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt @@ -17,13 +17,12 @@ package com.android.systemui.display.data.repository import android.view.Display +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.CoreStartable import com.android.systemui.dagger.qualifiers.Background import java.io.PrintWriter import java.util.concurrent.ConcurrentHashMap -import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope -import com.android.app.tracing.coroutines.launchTraced as launch /** Provides per display instances of [T]. */ interface PerDisplayStore<T> { diff --git a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt index 8b6cc8cb4540..b8ac0d282229 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt @@ -16,17 +16,64 @@ package com.android.systemui.dreams.ui.viewmodel +import com.android.compose.animation.scene.Swipe import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult +import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor +import com.android.systemui.scene.shared.model.SceneFamilies +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel +import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.shade.shared.model.ShadeMode +import com.android.systemui.shade.ui.viewmodel.dualShadeActions +import com.android.systemui.shade.ui.viewmodel.singleShadeActions +import com.android.systemui.shade.ui.viewmodel.splitShadeActions +import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map /** Handles user input for the dream scene. */ -class DreamUserActionsViewModel @AssistedInject constructor() : UserActionsViewModel() { +class DreamUserActionsViewModel +@AssistedInject +constructor( + private val deviceUnlockedInteractor: DeviceUnlockedInteractor, + private val shadeInteractor: ShadeInteractor, +) : UserActionsViewModel() { override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) { - setActions(emptyMap()) + shadeInteractor.isShadeTouchable + .flatMapLatestConflated { isShadeTouchable -> + if (!isShadeTouchable) { + flowOf(emptyMap()) + } else { + combine( + deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked }, + shadeInteractor.shadeMode, + ) { isDeviceUnlocked, shadeMode -> + buildList { + val bouncerOrGone = + if (isDeviceUnlocked) Scenes.Gone else Scenes.Bouncer + add(Swipe.Up to bouncerOrGone) + + // "Home" is either Dream, Lockscreen, or Gone. + add(Swipe.End to SceneFamilies.Home) + + addAll( + when (shadeMode) { + ShadeMode.Single -> singleShadeActions() + ShadeMode.Split -> splitShadeActions() + ShadeMode.Dual -> dualShadeActions() + } + ) + } + .associate { it } + } + } + } + .collect { setActions(it) } } @AssistedFactory diff --git a/packages/SystemUI/src/com/android/systemui/graphics/ImageLoader.kt b/packages/SystemUI/src/com/android/systemui/graphics/ImageLoader.kt index ca43871415e6..25f99207ad28 100644 --- a/packages/SystemUI/src/com/android/systemui/graphics/ImageLoader.kt +++ b/packages/SystemUI/src/com/android/systemui/graphics/ImageLoader.kt @@ -27,7 +27,6 @@ import android.content.res.Resources import android.content.res.Resources.NotFoundException import android.graphics.Bitmap import android.graphics.ImageDecoder -import android.graphics.ImageDecoder.DecodeException import android.graphics.drawable.AdaptiveIconDrawable import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable @@ -39,7 +38,6 @@ import com.android.app.tracing.traceSection import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background -import java.io.IOException import javax.inject.Inject import kotlin.math.min import kotlinx.coroutines.CoroutineDispatcher @@ -54,7 +52,7 @@ class ImageLoader @Inject constructor( @Application private val defaultContext: Context, - @Background private val backgroundDispatcher: CoroutineDispatcher + @Background private val backgroundDispatcher: CoroutineDispatcher, ) { /** Source of the image data. */ @@ -103,7 +101,7 @@ constructor( source: Source, @Px maxWidth: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, @Px maxHeight: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, - allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT + allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT, ): Bitmap? = withContext(backgroundDispatcher) { loadBitmapSync(source, maxWidth, maxHeight, allocator) } @@ -127,14 +125,14 @@ constructor( source: Source, @Px maxWidth: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, @Px maxHeight: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, - allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT + allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT, ): Bitmap? { return try { loadBitmapSync( toImageDecoderSource(source, defaultContext), maxWidth, maxHeight, - allocator + allocator, ) } catch (e: NotFoundException) { Log.w(TAG, "Couldn't load resource $source", e) @@ -162,7 +160,7 @@ constructor( source: ImageDecoder.Source, @Px maxWidth: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, @Px maxHeight: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, - allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT + allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT, ): Bitmap? = traceSection("ImageLoader#loadBitmap") { return try { @@ -170,12 +168,11 @@ constructor( configureDecoderForMaximumSize(decoder, info.size, maxWidth, maxHeight) decoder.allocator = allocator } - } catch (e: IOException) { + } catch (e: Exception) { + // If we're loading an Uri, we can receive any exception from the other side. + // So we have to catch them all. Log.w(TAG, "Failed to load source $source", e) return null - } catch (e: DecodeException) { - Log.w(TAG, "Failed to decode source $source", e) - return null } } @@ -199,7 +196,7 @@ constructor( source: Source, @Px maxWidth: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, @Px maxHeight: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, - allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT + allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT, ): Drawable? = withContext(backgroundDispatcher) { loadDrawableSync(source, maxWidth, maxHeight, allocator) @@ -227,7 +224,7 @@ constructor( context: Context = defaultContext, @Px maxWidth: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, @Px maxHeight: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, - allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT + allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT, ): Drawable? = withContext(backgroundDispatcher) { loadDrawableSync(icon, context, maxWidth, maxHeight, allocator) @@ -254,7 +251,7 @@ constructor( source: Source, @Px maxWidth: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, @Px maxHeight: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, - allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT + allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT, ): Drawable? = traceSection("ImageLoader#loadDrawable") { return try { @@ -262,7 +259,7 @@ constructor( toImageDecoderSource(source, defaultContext), maxWidth, maxHeight, - allocator + allocator, ) ?: // If we have a resource, retry fallback using the "normal" Resource loading @@ -301,7 +298,7 @@ constructor( source: ImageDecoder.Source, @Px maxWidth: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, @Px maxHeight: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, - allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT + allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT, ): Drawable? = traceSection("ImageLoader#loadDrawable") { return try { @@ -309,12 +306,11 @@ constructor( configureDecoderForMaximumSize(decoder, info.size, maxWidth, maxHeight) decoder.allocator = allocator } - } catch (e: IOException) { + } catch (e: Exception) { + // If we're loading from an Uri, any exception can happen on the + // other side. We have to catch them all. Log.w(TAG, "Failed to load source $source", e) return null - } catch (e: DecodeException) { - Log.w(TAG, "Failed to decode source $source", e) - return null } } @@ -325,7 +321,7 @@ constructor( context: Context = defaultContext, @Px maxWidth: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, @Px maxHeight: Int = DEFAULT_MAX_SAFE_BITMAP_SIZE_PX, - allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT + allocator: Int = ImageDecoder.ALLOCATOR_DEFAULT, ): Drawable? = traceSection("ImageLoader#loadDrawable") { return when (icon.type) { @@ -341,7 +337,7 @@ constructor( ImageDecoder.createSource(it, icon.resId), maxWidth, maxHeight, - allocator + allocator, ) } // Fallback to non-ImageDecoder load if the attempt failed (e.g. the @@ -360,7 +356,7 @@ constructor( ImageDecoder.createSource(icon.dataBytes, icon.dataOffset, icon.dataLength), maxWidth, maxHeight, - allocator + allocator, ) } else -> { @@ -421,12 +417,10 @@ constructor( fun loadSizeSync(source: ImageDecoder.Source): Size? { return try { ImageDecoder.decodeHeader(source).size - } catch (e: IOException) { + } catch (e: Exception) { + // Any exception can happen when loading Uris, so we have to catch them all. Log.w(TAG, "Failed to load source $source", e) return null - } catch (e: DecodeException) { - Log.w(TAG, "Failed to decode source $source", e) - return null } } @@ -472,7 +466,7 @@ constructor( decoder: ImageDecoder, imgSize: Size, @Px maxWidth: Int, - @Px maxHeight: Int + @Px maxHeight: Int, ) { if (maxWidth == DO_NOT_RESIZE && maxHeight == DO_NOT_RESIZE) { return @@ -547,7 +541,7 @@ constructor( pm.getApplicationInfo( resPackage, PackageManager.MATCH_UNINSTALLED_PACKAGES or - PackageManager.GET_SHARED_LIBRARY_FILES + PackageManager.GET_SHARED_LIBRARY_FILES, ) if (ai != null) { return pm.getResourcesForApplication(ai) diff --git a/packages/SystemUI/src/com/android/systemui/haptics/msdl/qs/TileHapticsViewModel.kt b/packages/SystemUI/src/com/android/systemui/haptics/msdl/qs/TileHapticsViewModel.kt index ed7d1823648a..316964a47753 100644 --- a/packages/SystemUI/src/com/android/systemui/haptics/msdl/qs/TileHapticsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/haptics/msdl/qs/TileHapticsViewModel.kt @@ -83,9 +83,6 @@ constructor( interactionState == TileInteractionState.LONG_CLICKED && animationState == TileAnimationState.ACTIVITY_LAUNCH -> TileHapticsState.LONG_PRESS - interactionState == TileInteractionState.LONG_CLICKED && - !tileViewModel.currentState.handlesLongClick -> - TileHapticsState.FAILED_LONGPRESS else -> TileHapticsState.NO_HAPTICS } } @@ -102,7 +99,6 @@ constructor( TileHapticsState.TOGGLE_ON -> MSDLToken.SWITCH_ON TileHapticsState.TOGGLE_OFF -> MSDLToken.SWITCH_OFF TileHapticsState.LONG_PRESS -> MSDLToken.LONG_PRESS - TileHapticsState.FAILED_LONGPRESS -> MSDLToken.FAILURE TileHapticsState.NO_HAPTICS -> null } tokenToPlay?.let { @@ -154,7 +150,6 @@ constructor( TOGGLE_ON, TOGGLE_OFF, LONG_PRESS, - FAILED_LONGPRESS, NO_HAPTICS, } diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt index 4a369e7e849e..7758dcc0fc88 100644 --- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt @@ -17,12 +17,14 @@ package com.android.systemui.inputdevice.tutorial.domain.interactor import android.os.SystemProperties +import com.android.internal.annotations.VisibleForTesting import com.android.systemui.dagger.SysUISingleton import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.KEYBOARD import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.TOUCHPAD import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository +import com.android.systemui.inputdevice.tutorial.domain.interactor.TutorialSchedulerInteractor.Companion.LAUNCH_DELAY import com.android.systemui.keyboard.data.repository.KeyboardRepository import com.android.systemui.statusbar.commandline.Command import com.android.systemui.statusbar.commandline.CommandRegistry @@ -35,6 +37,7 @@ import kotlin.time.Duration.Companion.hours import kotlin.time.toKotlinDuration import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow @@ -96,6 +99,9 @@ constructor( private suspend fun waitForDeviceConnection(deviceType: DeviceType) = isAnyDeviceConnected[deviceType]!!.filter { it }.first() + // Only for testing notifications. This should behave independently from scheduling + @VisibleForTesting val commandTutorials = MutableStateFlow(TutorialType.NONE) + // Merging two flows ensures that tutorial is launched consecutively to avoid race condition val tutorials: Flow<TutorialType> = merge(touchpadScheduleFlow, keyboardScheduleFlow).map { @@ -146,6 +152,15 @@ constructor( pw.println("Touchpad connect time = ${repo.firstConnectionTime(TOUCHPAD)}") pw.println(" launch time = ${repo.launchTime(TOUCHPAD)}") } + "notify" -> { + if (args.size != 2) help(pw) + when (args[1]) { + "keyboard" -> commandTutorials.value = TutorialType.KEYBOARD + "touchpad" -> commandTutorials.value = TutorialType.TOUCHPAD + "both" -> commandTutorials.value = TutorialType.BOTH + else -> help(pw) + } + } else -> help(pw) } } @@ -155,6 +170,7 @@ constructor( pw.println("Available commands:") pw.println(" clear") pw.println(" info") + pw.println(" notify [keyboard|touchpad|both]") } } diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt index 3b26f2ff9deb..9dae64921d26 100644 --- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt @@ -24,6 +24,7 @@ import android.content.Context import android.content.Intent import android.os.Bundle import androidx.core.app.NotificationCompat +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background @@ -41,7 +42,7 @@ import com.android.systemui.res.R import com.android.systemui.settings.UserTracker import javax.inject.Inject import kotlinx.coroutines.CoroutineScope -import com.android.app.tracing.coroutines.launchTraced as launch +import kotlinx.coroutines.flow.merge /** When the scheduler is due, show a notification to launch tutorial */ @SysUISingleton @@ -56,7 +57,11 @@ constructor( ) { fun start() { backgroundScope.launch { - tutorialSchedulerInteractor.tutorials.collect { showNotification(it) } + merge( + tutorialSchedulerInteractor.tutorials, + tutorialSchedulerInteractor.commandTutorials, + ) + .collect { showNotification(it) } } } diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt index fa494150cbbf..fee08b31bd93 100644 --- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt @@ -27,6 +27,7 @@ import androidx.compose.runtime.getValue import androidx.lifecycle.Lifecycle.State.STARTED import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.lifecycleScope +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.compose.theme.PlatformTheme import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger.TutorialContext @@ -40,7 +41,6 @@ import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.BACK_GESTUR import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.HOME_GESTURE import java.util.Optional import javax.inject.Inject -import com.android.app.tracing.coroutines.launchTraced as launch /** * Activity for out of the box experience for keyboard and touchpad. Note that it's possible that @@ -90,6 +90,7 @@ constructor( setContent { PlatformTheme { KeyboardTouchpadTutorialContainer(vm, touchpadTutorialScreensProvider) } } + // TODO(b/376692701): Update launchTime when the activity is launched by Companion App if (savedInstanceState == null) { metricsLogger.logPeripheralTutorialLaunched( intent.getStringExtra(INTENT_TUTORIAL_ENTRY_POINT_KEY), diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt index 7f8fbb5065aa..ec1d358b6bd2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt @@ -49,6 +49,7 @@ constructor( @Background private val backgroundScope: CoroutineScope, @Background private val backgroundDispatcher: CoroutineDispatcher, private val shortcutCategoriesUtils: ShortcutCategoriesUtils, + private val context: Context, ) : ShortcutCategoriesRepository { private val userContext: Context @@ -147,25 +148,23 @@ constructor( private fun fetchGroupLabelByGestureType( @KeyGestureEvent.KeyGestureType keyGestureType: Int ): String? { - return InputGestures.gestureToInternalKeyboardShortcutGroupLabelMap.getOrDefault( - keyGestureType, - null, - ) + InputGestures.gestureToInternalKeyboardShortcutGroupLabelMap[keyGestureType]?.let { + return context.getString(it) + } ?: return null } private fun fetchShortcutInfoLabelByGestureType( @KeyGestureEvent.KeyGestureType keyGestureType: Int ): String? { - return InputGestures.gestureToInternalKeyboardShortcutInfoLabelMap.getOrDefault( - keyGestureType, - null, - ) + InputGestures.gestureToInternalKeyboardShortcutInfoLabelMap[keyGestureType]?.let { + return context.getString(it) + } ?: return null } private fun fetchShortcutCategoryTypeByGestureType( @KeyGestureEvent.KeyGestureType keyGestureType: Int ): ShortcutCategoryType? { - return InputGestures.gestureToShortcutCategoryTypeMap.getOrDefault(keyGestureType, null) + return InputGestures.gestureToShortcutCategoryTypeMap[keyGestureType] } private data class InternalGroupsSource( diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestures.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestures.kt index 28134db4d588..90be9888e622 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestures.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestures.kt @@ -44,6 +44,7 @@ import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATI import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.AppCategories import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MultiTasking import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.System +import com.android.systemui.res.R object InputGestures { val gestureToShortcutCategoryTypeMap = @@ -80,77 +81,97 @@ object InputGestures { KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING to AppCategories, ) - // TODO move all string to to resources use the same resources as the original shortcuts - // - that way when the strings are translated there are no discrepancies val gestureToInternalKeyboardShortcutGroupLabelMap = mapOf( // System Category - KEY_GESTURE_TYPE_HOME to "System controls", - KEY_GESTURE_TYPE_RECENT_APPS to "System controls", - KEY_GESTURE_TYPE_BACK to "System controls", - KEY_GESTURE_TYPE_TAKE_SCREENSHOT to "System controls", - KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER to "System controls", - KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL to "System controls", - KEY_GESTURE_TYPE_LOCK_SCREEN to "System controls", - KEY_GESTURE_TYPE_ALL_APPS to "System controls", - KEY_GESTURE_TYPE_OPEN_NOTES to "System apps", - KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS to "System apps", - KEY_GESTURE_TYPE_LAUNCH_ASSISTANT to "System apps", - KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT to "System apps", + KEY_GESTURE_TYPE_HOME to R.string.shortcut_helper_category_system_controls, + KEY_GESTURE_TYPE_RECENT_APPS to R.string.shortcut_helper_category_system_controls, + KEY_GESTURE_TYPE_BACK to R.string.shortcut_helper_category_system_controls, + KEY_GESTURE_TYPE_TAKE_SCREENSHOT to R.string.shortcut_helper_category_system_controls, + KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER to + R.string.shortcut_helper_category_system_controls, + KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL to + R.string.shortcut_helper_category_system_controls, + KEY_GESTURE_TYPE_LOCK_SCREEN to R.string.shortcut_helper_category_system_controls, + KEY_GESTURE_TYPE_ALL_APPS to R.string.shortcut_helper_category_system_controls, + KEY_GESTURE_TYPE_OPEN_NOTES to R.string.shortcut_helper_category_system_apps, + KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS to + R.string.shortcut_helper_category_system_apps, + KEY_GESTURE_TYPE_LAUNCH_ASSISTANT to R.string.shortcut_helper_category_system_apps, + KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT to + R.string.shortcut_helper_category_system_apps, // Multitasking Category - KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER to "Recent apps", - KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT to "Split screen", - KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT to "Split screen", - KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION to "Split screen", - KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT to "Split screen", - KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT to "Split screen", + KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER to R.string.shortcutHelper_category_recent_apps, + KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT to + R.string.shortcutHelper_category_split_screen, + KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT to + R.string.shortcutHelper_category_split_screen, + KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION to + R.string.shortcutHelper_category_split_screen, + KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT to + R.string.shortcutHelper_category_split_screen, + KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT to + R.string.shortcutHelper_category_split_screen, // App Category - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR to "Applications", - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR to "Applications", - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER to "Applications", - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS to "Applications", - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL to "Applications", - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS to "Applications", - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING to "Applications", + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR to + R.string.keyboard_shortcut_group_applications, + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR to + R.string.keyboard_shortcut_group_applications, + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER to + R.string.keyboard_shortcut_group_applications, + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS to + R.string.keyboard_shortcut_group_applications, + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL to R.string.keyboard_shortcut_group_applications, + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS to R.string.keyboard_shortcut_group_applications, + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING to + R.string.keyboard_shortcut_group_applications, ) val gestureToInternalKeyboardShortcutInfoLabelMap = mapOf( // System Category - KEY_GESTURE_TYPE_HOME to "Go to home screen", - KEY_GESTURE_TYPE_RECENT_APPS to "View recent apps", - KEY_GESTURE_TYPE_BACK to "Go back", - KEY_GESTURE_TYPE_TAKE_SCREENSHOT to "Take screenshot", - KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER to "Show shortcuts", - KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL to "View notifications", - KEY_GESTURE_TYPE_LOCK_SCREEN to "Lock screen", - KEY_GESTURE_TYPE_ALL_APPS to "Open apps list", - KEY_GESTURE_TYPE_OPEN_NOTES to "Take a note", - KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS to "Open settings", - KEY_GESTURE_TYPE_LAUNCH_ASSISTANT to "Open assistant", - KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT to "Open assistant", + KEY_GESTURE_TYPE_HOME to R.string.group_system_access_home_screen, + KEY_GESTURE_TYPE_RECENT_APPS to R.string.group_system_overview_open_apps, + KEY_GESTURE_TYPE_BACK to R.string.group_system_go_back, + KEY_GESTURE_TYPE_TAKE_SCREENSHOT to R.string.group_system_full_screenshot, + KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER to + R.string.group_system_access_system_app_shortcuts, + KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL to + R.string.group_system_access_notification_shade, + KEY_GESTURE_TYPE_LOCK_SCREEN to R.string.group_system_lock_screen, + KEY_GESTURE_TYPE_ALL_APPS to R.string.group_system_access_all_apps_search, + KEY_GESTURE_TYPE_OPEN_NOTES to R.string.group_system_quick_memo, + KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS to R.string.group_system_access_system_settings, + KEY_GESTURE_TYPE_LAUNCH_ASSISTANT to R.string.group_system_access_google_assistant, + KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT to + R.string.group_system_access_google_assistant, // Multitasking Category - KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER to "Cycle forward through recent apps", - KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT to - "Use split screen with current app on the left", - KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT to - "Use split screen with current app on the right", - KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION to "Switch from split screen to full screen", + KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER to R.string.group_system_cycle_forward, + KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT to R.string.system_multitasking_lhs, + KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT to R.string.system_multitasking_rhs, + KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION to R.string.system_multitasking_full_screen, KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT to - "Switch to app on left or above while using split screen", + R.string.system_multitasking_splitscreen_focus_lhs, KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT to - "Switch to app on right or below while using split screen", + R.string.system_multitasking_splitscreen_focus_rhs, // App Category - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR to "Calculator", - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR to "Calendar", - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER to "Chrome", - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS to "Contacts", - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL to "Gmail", - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS to "Maps", - KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING to "Messages", + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR to + R.string.keyboard_shortcut_group_applications_calculator, + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR to + R.string.keyboard_shortcut_group_applications_calendar, + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER to + R.string.keyboard_shortcut_group_applications_browser, + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS to + R.string.keyboard_shortcut_group_applications_contacts, + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL to + R.string.keyboard_shortcut_group_applications_email, + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS to + R.string.keyboard_shortcut_group_applications_maps, + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING to + R.string.keyboard_shortcut_group_applications_sms, ) } diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt index 5f8570cba7a6..bf7df7ef8561 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt @@ -20,7 +20,9 @@ data class Shortcut( val label: String, val commands: List<ShortcutCommand>, val icon: ShortcutIcon? = null, -) +) { + val containsCustomShortcutCommands: Boolean = commands.any { it.isCustom } +} class ShortcutBuilder(private val label: String) { val commands = mutableListOf<ShortcutCommand>() diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCustomizationRequestInfo.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCustomizationRequestInfo.kt new file mode 100644 index 000000000000..203228b4a32b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCustomizationRequestInfo.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyboard.shortcut.shared.model + +sealed interface ShortcutCustomizationRequestInfo { + data class Add( + val label: String, + val categoryType: ShortcutCategoryType, + val subCategoryLabel: String, + ) : ShortcutCustomizationRequestInfo +} diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt index 02e206e09bc7..e44bfe30a8bb 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt @@ -24,7 +24,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.systemui.keyboard.shortcut.shared.model.ShortcutInfo +import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo import com.android.systemui.keyboard.shortcut.ui.composable.AssignNewShortcutDialog import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState import com.android.systemui.keyboard.shortcut.ui.viewmodel.ShortcutCustomizationViewModel @@ -59,8 +59,8 @@ constructor( } } - fun onAddShortcutDialogRequested(shortcutBeingCustomized: ShortcutInfo) { - viewModel.onAddShortcutDialogRequested(shortcutBeingCustomized) + fun onShortcutCustomizationRequested(requestInfo: ShortcutCustomizationRequestInfo) { + viewModel.onShortcutCustomizationRequested(requestInfo) } private fun createAddShortcutDialog(): Dialog { diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarter.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarter.kt index 10a201e976c1..fa03883e2a35 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarter.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarter.kt @@ -84,7 +84,7 @@ constructor( onKeyboardSettingsClicked = { onKeyboardSettingsClicked(dialog) }, onSearchQueryChanged = { shortcutHelperViewModel.onSearchQueryChanged(it) }, onCustomizationRequested = { - shortcutCustomizationDialogStarter.onAddShortcutDialogRequested(it) + shortcutCustomizationDialogStarter.onShortcutCustomizationRequested(it) }, ) dialog.setOnDismissListener { shortcutHelperViewModel.onViewClosed() } diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt index 13934ea38233..41e69297f7c6 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt @@ -43,6 +43,7 @@ import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState @@ -53,6 +54,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.OpenInNew import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.DeleteOutline import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.Tune @@ -71,7 +73,6 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -109,14 +110,15 @@ import com.android.compose.ui.graphics.painter.rememberDrawablePainter import com.android.systemui.keyboard.shortcut.shared.model.Shortcut as ShortcutModel import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand +import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo import com.android.systemui.keyboard.shortcut.shared.model.ShortcutIcon -import com.android.systemui.keyboard.shortcut.shared.model.ShortcutInfo import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory import com.android.systemui.keyboard.shortcut.ui.model.IconSource import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCategoryUi import com.android.systemui.keyboard.shortcut.ui.model.ShortcutsUiState import com.android.systemui.res.R +import kotlinx.coroutines.delay @Composable fun ShortcutHelper( @@ -125,7 +127,7 @@ fun ShortcutHelper( modifier: Modifier = Modifier, shortcutsUiState: ShortcutsUiState, useSinglePane: @Composable () -> Boolean = { shouldUseSinglePane() }, - onCustomizationRequested: (ShortcutInfo) -> Unit = {}, + onCustomizationRequested: (ShortcutCustomizationRequestInfo) -> Unit = {}, ) { when (shortcutsUiState) { is ShortcutsUiState.Active -> { @@ -138,6 +140,7 @@ fun ShortcutHelper( onCustomizationRequested, ) } + else -> { // No-op for now. } @@ -151,7 +154,7 @@ private fun ActiveShortcutHelper( onSearchQueryChanged: (String) -> Unit, modifier: Modifier, onKeyboardSettingsClicked: () -> Unit, - onCustomizationRequested: (ShortcutInfo) -> Unit = {}, + onCustomizationRequested: (ShortcutCustomizationRequestInfo) -> Unit = {}, ) { var selectedCategoryType by remember(shortcutsUiState.defaultSelectedCategory) { @@ -367,14 +370,10 @@ private fun ShortcutHelperTwoPane( onCategorySelected: (ShortcutCategoryType?) -> Unit, onKeyboardSettingsClicked: () -> Unit, isShortcutCustomizerFlagEnabled: Boolean, - onCustomizationRequested: (ShortcutInfo) -> Unit = {}, + onCustomizationRequested: (ShortcutCustomizationRequestInfo) -> Unit = {}, ) { val selectedCategory = categories.fastFirstOrNull { it.type == selectedCategoryType } - var isCustomizeModeEntered by remember { mutableStateOf(false) } - val isCustomizing by - remember(isCustomizeModeEntered, isShortcutCustomizerFlagEnabled) { - derivedStateOf { isCustomizeModeEntered && isCustomizeModeEntered } - } + var isCustomizing by remember { mutableStateOf(false) } Column(modifier = modifier.fillMaxSize().padding(horizontal = 24.dp)) { Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { @@ -383,10 +382,10 @@ private fun ShortcutHelperTwoPane( } Spacer(modifier = Modifier.weight(1f)) if (isShortcutCustomizerFlagEnabled) { - if (isCustomizeModeEntered) { - DoneButton(onClick = { isCustomizeModeEntered = false }) + if (isCustomizing) { + DoneButton(onClick = { isCustomizing = false }) } else { - CustomizeButton(onClick = { isCustomizeModeEntered = true }) + CustomizeButton(onClick = { isCustomizing = true }) } } } @@ -441,7 +440,7 @@ private fun EndSidePanel( modifier: Modifier, category: ShortcutCategoryUi?, isCustomizing: Boolean, - onCustomizationRequested: (ShortcutInfo) -> Unit = {}, + onCustomizationRequested: (ShortcutCustomizationRequestInfo) -> Unit = {}, ) { val listState = rememberLazyListState() LaunchedEffect(key1 = category) { if (category != null) listState.animateScrollToItem(0) } @@ -457,7 +456,7 @@ private fun EndSidePanel( isCustomizing = isCustomizing, onCustomizationRequested = { label, subCategoryLabel -> onCustomizationRequested( - ShortcutInfo( + ShortcutCustomizationRequestInfo.Add( label = label, subCategoryLabel = subCategoryLabel, categoryType = category.type, @@ -565,7 +564,7 @@ private fun Shortcut( modifier = Modifier.weight(1f), shortcut = shortcut, isCustomizing = isCustomizing, - onAddShortcutClicked = { onCustomizationRequested(shortcut.label) }, + onAddShortcutRequested = { onCustomizationRequested(shortcut.label) }, ) } } @@ -594,38 +593,88 @@ private fun ShortcutKeyCombinations( modifier: Modifier = Modifier, shortcut: ShortcutModel, isCustomizing: Boolean = false, - onAddShortcutClicked: () -> Unit = {}, + onAddShortcutRequested: () -> Unit = {}, + onDeleteShortcutRequested: () -> Unit = {}, ) { FlowRow( modifier = modifier, verticalArrangement = Arrangement.spacedBy(8.dp), + itemVerticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.End, ) { shortcut.commands.forEachIndexed { index, command -> if (index > 0) { ShortcutOrSeparator(spacing = 16.dp) } - ShortcutCommand(command) + ShortcutCommandContainer(showBackground = command.isCustom) { ShortcutCommand(command) } } if (isCustomizing) { Spacer(modifier = Modifier.width(16.dp)) - ShortcutHelperButton( - modifier = - Modifier.border( - width = 1.dp, - color = MaterialTheme.colorScheme.outline, - shape = CircleShape, - ), - onClick = { onAddShortcutClicked() }, - color = Color.Transparent, - width = 32.dp, - height = 32.dp, - iconSource = IconSource(imageVector = Icons.Default.Add), - contentColor = MaterialTheme.colorScheme.primary, - contentPaddingVertical = 0.dp, - contentPaddingHorizontal = 0.dp, - ) + if (shortcut.containsCustomShortcutCommands) { + DeleteShortcutButton(onDeleteShortcutRequested) + } else { + AddShortcutButton(onAddShortcutRequested) + } + } + } +} + +@Composable +private fun AddShortcutButton(onClick: () -> Unit) { + ShortcutHelperButton( + modifier = + Modifier.border( + width = 1.dp, + color = MaterialTheme.colorScheme.outline, + shape = CircleShape, + ), + onClick = onClick, + color = Color.Transparent, + width = 32.dp, + height = 32.dp, + iconSource = IconSource(imageVector = Icons.Default.Add), + contentColor = MaterialTheme.colorScheme.primary, + contentPaddingVertical = 0.dp, + contentPaddingHorizontal = 0.dp, + ) +} + +@Composable +private fun DeleteShortcutButton(onClick: () -> Unit) { + ShortcutHelperButton( + modifier = + Modifier.border( + width = 1.dp, + color = MaterialTheme.colorScheme.outline, + shape = CircleShape, + ), + onClick = onClick, + color = Color.Transparent, + width = 32.dp, + height = 32.dp, + iconSource = IconSource(imageVector = Icons.Default.DeleteOutline), + contentColor = MaterialTheme.colorScheme.primary, + contentPaddingVertical = 0.dp, + contentPaddingHorizontal = 0.dp, + ) +} + +@Composable +private fun ShortcutCommandContainer(showBackground: Boolean, content: @Composable () -> Unit) { + if (showBackground) { + Box( + modifier = + Modifier.wrapContentSize() + .background( + color = MaterialTheme.colorScheme.outlineVariant, + shape = RoundedCornerShape(16.dp), + ) + .padding(4.dp) + ) { + content() } + } else { + content() } } @@ -853,7 +902,12 @@ private fun ShortcutsSearchBar(onQueryChange: (String) -> Unit) { var queryInternal by remember { mutableStateOf("") } val focusRequester = remember { FocusRequester() } val focusManager = LocalFocusManager.current - LaunchedEffect(Unit) { focusRequester.requestFocus() } + LaunchedEffect(Unit) { + // TODO(b/272065229): Added minor delay so TalkBack can take focus of search box by default, + // remove when default a11y focus is fixed. + delay(50) + focusRequester.requestFocus() + } SearchBar( modifier = Modifier.fillMaxWidth().focusRequester(focusRequester).onKeyEvent { diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt index e761c7313ff3..58ce194694df 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt @@ -18,6 +18,7 @@ package com.android.systemui.keyboard.shortcut.ui.composable import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.IndicationNodeFactory +import androidx.compose.foundation.LocalIndication import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable @@ -126,8 +127,7 @@ fun SelectableShortcutSurface( .selectable( selected = selected, interactionSource = interactionSource, - indication = - ShortcutHelperIndication(interactionSource, interactionsConfig), + indication = ShortcutHelperIndication(interactionsConfig), enabled = enabled, onClick = onClick, ) @@ -181,8 +181,7 @@ fun ClickableShortcutSurface( ) .clickable( interactionSource = interactionSource, - indication = - ShortcutHelperIndication(interactionSource, interactionsConfig), + indication = ShortcutHelperIndication(interactionsConfig), enabled = enabled, onClick = onClick, ), @@ -507,10 +506,8 @@ private class ShortcutHelperInteractionsNode( } } -data class ShortcutHelperIndication( - private val interactionSource: InteractionSource, - private val interactionsConfig: InteractionsConfig, -) : IndicationNodeFactory { +data class ShortcutHelperIndication(private val interactionsConfig: InteractionsConfig) : + IndicationNodeFactory { override fun create(interactionSource: InteractionSource): DelegatableNode { return ShortcutHelperInteractionsNode(interactionSource, interactionsConfig) } @@ -529,3 +526,15 @@ data class InteractionsConfig( val hoverPadding: Dp = 0.dp, val pressedPadding: Dp = hoverPadding, ) + +@Composable +fun ProvideShortcutHelperIndication( + interactionsConfig: InteractionsConfig, + content: @Composable () -> Unit, +) { + CompositionLocalProvider( + LocalIndication provides ShortcutHelperIndication(interactionsConfig) + ) { + content() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt index b9253878ba0d..e86da5d25b22 100644 --- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt @@ -19,7 +19,7 @@ package com.android.systemui.keyboard.shortcut.ui.viewmodel import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.input.key.KeyEvent import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutCustomizationInteractor -import com.android.systemui.keyboard.shortcut.shared.model.ShortcutInfo +import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -30,32 +30,35 @@ import kotlinx.coroutines.flow.update class ShortcutCustomizationViewModel @AssistedInject constructor(private val shortcutCustomizationInteractor: ShortcutCustomizationInteractor) { - private val _shortcutBeingCustomized = mutableStateOf<ShortcutInfo?>(null) + private val _shortcutBeingCustomized = mutableStateOf<ShortcutCustomizationRequestInfo?>(null) private val _shortcutCustomizationUiState = MutableStateFlow<ShortcutCustomizationUiState>(ShortcutCustomizationUiState.Inactive) val shortcutCustomizationUiState = _shortcutCustomizationUiState.asStateFlow() - fun onAddShortcutDialogRequested(shortcutBeingCustomized: ShortcutInfo) { - _shortcutCustomizationUiState.value = - ShortcutCustomizationUiState.AddShortcutDialog( - shortcutLabel = shortcutBeingCustomized.label, - shouldShowErrorMessage = false, - isValidKeyCombination = false, - defaultCustomShortcutModifierKey = - shortcutCustomizationInteractor.getDefaultCustomShortcutModifierKey(), - isDialogShowing = false, - ) - - _shortcutBeingCustomized.value = shortcutBeingCustomized + fun onShortcutCustomizationRequested(requestInfo: ShortcutCustomizationRequestInfo) { + when (requestInfo) { + is ShortcutCustomizationRequestInfo.Add -> { + _shortcutCustomizationUiState.value = + ShortcutCustomizationUiState.AddShortcutDialog( + shortcutLabel = requestInfo.label, + shouldShowErrorMessage = false, + isValidKeyCombination = false, + defaultCustomShortcutModifierKey = + shortcutCustomizationInteractor.getDefaultCustomShortcutModifierKey(), + isDialogShowing = false, + ) + _shortcutBeingCustomized.value = requestInfo + } + } } fun onAddShortcutDialogShown() { _shortcutCustomizationUiState.update { uiState -> - (uiState as? ShortcutCustomizationUiState.AddShortcutDialog) - ?.let { it.copy(isDialogShowing = true) } - ?: uiState + (uiState as? ShortcutCustomizationUiState.AddShortcutDialog)?.copy( + isDialogShowing = true + ) ?: uiState } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt index 2d056001b669..5ec6d37207b5 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt @@ -95,7 +95,7 @@ constructor( private val keyguardBlueprintViewModel: KeyguardBlueprintViewModel, private val keyguardStatusViewComponentFactory: KeyguardStatusViewComponent.Factory, @ShadeDisplayAware private val configuration: ConfigurationState, - private val context: Context, + @ShadeDisplayAware private val context: Context, private val keyguardIndicationController: KeyguardIndicationController, private val shadeInteractor: ShadeInteractor, private val interactionJankMonitor: InteractionJankMonitor, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java index 39144b56adc7..c0ffda6640b2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java @@ -34,6 +34,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dump.DumpManager; import com.android.systemui.power.domain.interactor.PowerInteractor; import com.android.systemui.res.R; +import com.android.systemui.shade.ShadeDisplayAware; import com.android.systemui.util.time.SystemClock; import java.io.PrintWriter; @@ -91,7 +92,7 @@ public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observe @Inject public WakefulnessLifecycle( - Context context, + @ShadeDisplayAware Context context, @Nullable IWallpaperManager wallpaperManagerService, SystemClock systemClock, DumpManager dumpManager) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerOcclusionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerOcclusionManager.kt index 585bd6adf11f..4bac8f7a1b47 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerOcclusionManager.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerOcclusionManager.kt @@ -46,6 +46,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.res.R +import com.android.systemui.shade.ShadeDisplayAware import java.util.concurrent.Executor import javax.inject.Inject @@ -83,7 +84,7 @@ constructor( val activityTransitionAnimator: ActivityTransitionAnimator, val keyguardViewController: dagger.Lazy<KeyguardViewController>, val powerInteractor: PowerInteractor, - val context: Context, + @ShadeDisplayAware val context: Context, val interactionJankMonitor: InteractionJankMonitor, @Main executor: Executor, val dreamingToLockscreenTransitionViewModel: DreamingToLockscreenTransitionViewModel, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java index 7638079d7475..0101e099084e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java @@ -68,6 +68,7 @@ import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.process.ProcessWrapper; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.ShadeController; +import com.android.systemui.shade.ShadeDisplayAware; import com.android.systemui.statusbar.NotificationShadeDepthController; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.SysuiStatusBarStateController; @@ -126,7 +127,7 @@ public interface KeyguardModule { @Provides @SysUISingleton static KeyguardViewMediator newKeyguardViewMediator( - Context context, + @ShadeDisplayAware Context context, UiEventLogger uiEventLogger, SessionTracker sessionTracker, UserTracker userTracker, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt index 77e8179195a1..74ee052f12b9 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt @@ -27,9 +27,9 @@ import com.android.systemui.camera.CameraGestureHelper import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.settings.UserTracker +import com.android.systemui.shade.ShadeDisplayAware import dagger.Lazy import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher @@ -41,7 +41,7 @@ import kotlinx.coroutines.withContext class CameraQuickAffordanceConfig @Inject constructor( - @Application private val context: Context, + @ShadeDisplayAware private val context: Context, private val packageManager: PackageManager, private val cameraGestureHelper: Lazy<CameraGestureHelper>, private val userTracker: UserTracker, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt index be873344b719..d1f9fa259c6b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt @@ -40,6 +40,7 @@ import com.android.systemui.keyguard.shared.quickaffordance.ActivationState import com.android.systemui.modes.shared.ModesUi import com.android.systemui.res.R import com.android.systemui.settings.UserTracker +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.policy.ZenModeController import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor import com.android.systemui.util.settings.SecureSettings @@ -75,7 +76,7 @@ constructor( @Inject constructor( - context: Context, + @ShadeDisplayAware context: Context, controller: ZenModeController, interactor: ZenModeInteractor, secureSettings: SecureSettings, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt index a7999c192643..480ef5e19d8e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt @@ -27,6 +27,7 @@ import com.android.systemui.common.shared.model.Icon import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.shared.quickaffordance.ActivationState +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.policy.FlashlightController import javax.inject.Inject import kotlinx.coroutines.channels.awaitClose @@ -36,7 +37,7 @@ import kotlinx.coroutines.flow.Flow class FlashlightQuickAffordanceConfig @Inject constructor( - @Application private val context: Context, + @ShadeDisplayAware private val context: Context, private val flashlightController: FlashlightController, ) : KeyguardQuickAffordanceConfig { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt index cc36961ff973..3555f06ce96f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt @@ -36,6 +36,7 @@ import com.android.systemui.controls.ui.ControlsUiController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.Companion.appStoreIntent +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.util.kotlin.getOrNull import javax.inject.Inject import kotlinx.coroutines.channels.awaitClose @@ -48,7 +49,7 @@ import kotlinx.coroutines.flow.flowOf class HomeControlsKeyguardQuickAffordanceConfig @Inject constructor( - @Application private val context: Context, + @ShadeDisplayAware private val context: Context, private val component: ControlsComponent, ) : KeyguardQuickAffordanceConfig { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt index 796374aadc1a..f08576abc44f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt @@ -29,6 +29,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.res.R import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserTracker +import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.awaitClose @@ -47,7 +48,7 @@ import kotlinx.coroutines.flow.onStart class KeyguardQuickAffordanceLocalUserSelectionManager @Inject constructor( - @Application private val context: Context, + @ShadeDisplayAware private val context: Context, private val userFileManager: UserFileManager, private val userTracker: UserTracker, broadcastDispatcher: BroadcastDispatcher, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt index 6c1bdad98251..1358634a55f8 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt @@ -33,6 +33,7 @@ import com.android.systemui.keyguard.shared.quickaffordance.ActivationState import com.android.systemui.res.R import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserTracker +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.util.RingerModeTracker import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher @@ -51,7 +52,7 @@ import kotlinx.coroutines.withContext class MuteQuickAffordanceConfig @Inject constructor( - private val context: Context, + @ShadeDisplayAware private val context: Context, private val userTracker: UserTracker, private val userFileManager: UserFileManager, private val ringerModeTracker: RingerModeTracker, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt index a503541dcf59..d12c42a754f0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt @@ -27,6 +27,7 @@ import com.android.systemui.common.shared.model.Icon import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.qrcodescanner.controller.QRCodeScannerController +import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow @@ -36,7 +37,7 @@ import kotlinx.coroutines.flow.Flow class QrCodeScannerKeyguardQuickAffordanceConfig @Inject constructor( - @Application private val context: Context, + @ShadeDisplayAware private val context: Context, private val controller: QRCodeScannerController, ) : KeyguardQuickAffordanceConfig { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt index 56b520ed6206..eafa1cea59f3 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt @@ -34,6 +34,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.plugins.ActivityStarter import com.android.systemui.res.R +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.wallet.controller.QuickAccessWalletController import com.android.systemui.wallet.util.getPaymentCards import javax.inject.Inject @@ -51,7 +52,7 @@ import kotlinx.coroutines.withContext class QuickAccessWalletKeyguardQuickAffordanceConfig @Inject constructor( - @Application private val context: Context, + @ShadeDisplayAware private val context: Context, @Background private val backgroundDispatcher: CoroutineDispatcher, private val walletController: QuickAccessWalletController, private val activityStarter: ActivityStarter, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt index 3e6e3b79a820..ceaeeca4ea2a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt @@ -32,6 +32,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.settings.UserTracker +import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow @@ -42,7 +43,7 @@ import kotlinx.coroutines.withContext class VideoCameraQuickAffordanceConfig @Inject constructor( - @Application private val context: Context, + @ShadeDisplayAware private val context: Context, private val cameraIntents: CameraIntentsWrapper, private val activityIntentHelper: ActivityIntentHelper, private val userTracker: UserTracker, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt index dd3e6190ceaf..ab8cc7125d6e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt @@ -40,6 +40,7 @@ import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.shared.model.AuthenticationFlags import com.android.systemui.keyguard.shared.model.DevicePosture import com.android.systemui.res.R +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository import com.android.systemui.user.data.repository.UserRepository import java.io.PrintWriter @@ -123,7 +124,7 @@ private const val TAG = "BiometricsRepositoryImpl" class BiometricSettingsRepositoryImpl @Inject constructor( - context: Context, + @ShadeDisplayAware context: Context, lockPatternUtils: LockPatternUtils, broadcastDispatcher: BroadcastDispatcher, authController: AuthController, @@ -354,7 +355,10 @@ constructor( } @OptIn(ExperimentalCoroutinesApi::class) -private class StrongAuthTracker(private val userRepository: UserRepository, context: Context?) : +private class StrongAuthTracker( + private val userRepository: UserRepository, + @ShadeDisplayAware context: Context? +) : LockPatternUtils.StrongAuthTracker(context) { private val selectedUserId = diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBypassRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBypassRepository.kt index be4ab4b2c486..c9be2072e506 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBypassRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBypassRepository.kt @@ -19,7 +19,6 @@ package com.android.systemui.keyguard.data.repository import android.annotation.IntDef import android.content.res.Resources import android.provider.Settings -import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main @@ -27,13 +26,11 @@ import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.shared.model.DevicePosture import com.android.systemui.keyguard.shared.model.DevicePosture.UNKNOWN import com.android.systemui.res.R -import com.android.systemui.tuner.TunerService import com.android.systemui.util.kotlin.FlowDumperImpl +import com.android.systemui.util.settings.repository.UserAwareSecureSettingsRepository import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOf @@ -48,7 +45,7 @@ constructor( biometricSettingsRepository: BiometricSettingsRepository, devicePostureRepository: DevicePostureRepository, dumpManager: DumpManager, - private val tunerService: TunerService, + secureSettingsRepository: UserAwareSecureSettingsRepository, @Background backgroundDispatcher: CoroutineDispatcher, ) : FlowDumperImpl(dumpManager) { @@ -61,40 +58,26 @@ constructor( DevicePosture.toPosture(resources.getInteger(R.integer.config_face_auth_supported_posture)) } - private val dismissByDefault: Int by lazy { - if (resources.getBoolean(com.android.internal.R.bool.config_faceAuthDismissesKeyguard)) { - 1 - } else { - 0 - } - } - private var bypassEnabledSetting: Flow<Boolean> = - callbackFlow { - val updateBypassSetting = { state: Boolean -> - trySendWithFailureLogging(state, TAG, "Error sending bypassSetting $state") - } - - val tunable = - TunerService.Tunable { key, _ -> - updateBypassSetting(tunerService.getValue(key, dismissByDefault) != 0) - } - - updateBypassSetting(false) - tunerService.addTunable(tunable, Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD) - awaitClose { tunerService.removeTunable(tunable) } - } + secureSettingsRepository + .boolSetting( + name = Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, + defaultValue = + resources.getBoolean( + com.android.internal.R.bool.config_faceAuthDismissesKeyguard + ), + ) .flowOn(backgroundDispatcher) .dumpWhileCollecting("bypassEnabledSetting") - val overrideFaceBypassSetting: Flow<Boolean> = + private val overrideFaceBypassSetting: Flow<Boolean> = when (bypassOverride) { FACE_UNLOCK_BYPASS_ALWAYS -> flowOf(true) FACE_UNLOCK_BYPASS_NEVER -> flowOf(false) else -> bypassEnabledSetting } - val isPostureAllowedForFaceAuth: Flow<Boolean> = + private val isPostureAllowedForFaceAuth: Flow<Boolean> = when (configFaceAuthSupportedPosture) { UNKNOWN -> flowOf(true) else -> diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt index 95d1b5d7fcac..283651dd9db7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt @@ -31,6 +31,7 @@ import com.android.systemui.plugins.clocks.ClockController import com.android.systemui.plugins.clocks.ClockId import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.SceneContainerFlag +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.shared.clocks.ClockRegistry import com.android.systemui.util.settings.SecureSettings import com.android.systemui.util.settings.SettingsProxyExt.observerFlow @@ -89,7 +90,7 @@ constructor( override val clockEventController: ClockEventController, @Background private val backgroundDispatcher: CoroutineDispatcher, @Application private val applicationScope: CoroutineScope, - @Application private val applicationContext: Context, + @ShadeDisplayAware private val context: Context, private val featureFlags: FeatureFlagsClassic, ) : KeyguardClockRepository { @@ -166,7 +167,7 @@ constructor( get() = featureFlags.isEnabled(Flags.LOCKSCREEN_ENABLE_LANDSCAPE) && // True on small landscape screens - applicationContext.resources.getBoolean(R.bool.force_small_clock_on_lockscreen) + context.resources.getBoolean(R.bool.force_small_clock_on_lockscreen) private fun getClockSize(): ClockSizeSetting { return ClockSizeSetting.fromSettingValue( diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt index d0de21b45be0..c1ec88bb44f1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt @@ -36,6 +36,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardQuickAffordancePickerR import com.android.systemui.keyguard.shared.model.KeyguardSlotPickerRepresentation import com.android.systemui.res.R import com.android.systemui.settings.UserTracker +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.util.kotlin.FlowDumperImpl import java.io.PrintWriter import javax.inject.Inject @@ -57,7 +58,7 @@ import kotlinx.coroutines.flow.stateIn class KeyguardQuickAffordanceRepository @Inject constructor( - @Application private val appContext: Context, + @ShadeDisplayAware private val appContext: Context, @Application private val scope: CoroutineScope, private val localUserSelectionManager: KeyguardQuickAffordanceLocalUserSelectionManager, private val remoteUserSelectionManager: KeyguardQuickAffordanceRemoteUserSelectionManager, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepository.kt index b67fd4bf0ea7..549a5081cc43 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardSmartspaceRepository.kt @@ -16,7 +16,6 @@ package com.android.systemui.keyguard.data.repository -import android.content.Context import android.os.UserHandle import android.provider.Settings import android.view.View @@ -46,7 +45,6 @@ interface KeyguardSmartspaceRepository { class KeyguardSmartspaceRepositoryImpl @Inject constructor( - context: Context, private val secureSettings: SecureSettings, private val userTracker: UserTracker, @Application private val applicationScope: CoroutineScope, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt index eaf8fa9585f6..354fc3d82342 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt @@ -305,12 +305,12 @@ constructor(@Main val mainDispatcher: CoroutineDispatcher) : KeyguardTransitionR } override suspend fun forceFinishCurrentTransition() { - withContextMutex.lock() - if (lastAnimator?.isRunning != true) { return } + withContextMutex.lock() + return withContext("$TAG#forceFinishCurrentTransition", mainDispatcher) { withContextMutex.unlock() diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepository.kt index 4c9c282514cd..4f6319af24f1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepository.kt @@ -30,6 +30,7 @@ import com.android.systemui.power.data.repository.PowerRepository import com.android.systemui.power.shared.model.WakeSleepReason import com.android.systemui.power.shared.model.WakeSleepReason.TAP import com.android.systemui.res.R +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.CircleReveal import com.android.systemui.statusbar.LiftReveal import com.android.systemui.statusbar.LightRevealEffect @@ -77,7 +78,7 @@ class LightRevealScrimRepositoryImpl @Inject constructor( keyguardRepository: KeyguardRepository, - val context: Context, + @ShadeDisplayAware val context: Context, powerRepository: PowerRepository, private val scrimLogger: ScrimLogger, ) : LightRevealScrimRepository { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt index 73a4cc3ad9df..68ec4f3e86ce 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt @@ -45,7 +45,7 @@ import kotlinx.coroutines.flow.stateIn class BurnInInteractor @Inject constructor( - private val context: Context, + @ShadeDisplayAware private val context: Context, private val burnInHelperWrapper: BurnInHelperWrapper, @Application private val scope: CoroutineScope, @ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt index 03cf1a4b3e9a..6367b5c2df8e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt @@ -28,6 +28,7 @@ import com.android.systemui.res.R import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine @@ -47,7 +48,7 @@ import kotlinx.coroutines.flow.onEach class DeviceEntrySideFpsOverlayInteractor @Inject constructor( - @Application private val context: Context, + @ShadeDisplayAware private val context: Context, deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository, private val sceneInteractor: SceneInteractor, private val primaryBouncerInteractor: PrimaryBouncerInteractor, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt index d4d7e75a8b41..2d81be6fb0dc 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardKeyEventInteractor.kt @@ -28,6 +28,7 @@ import com.android.systemui.plugins.ActivityStarter.OnDismissAction import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.shade.ShadeController +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager import javax.inject.Inject @@ -39,7 +40,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi class KeyguardKeyEventInteractor @Inject constructor( - private val context: Context, + @ShadeDisplayAware private val context: Context, private val statusBarStateController: StatusBarStateController, private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager, private val shadeController: ShadeController, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt index 8c9473f4284b..ae55825c9842 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt @@ -51,6 +51,7 @@ import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.settings.UserTracker +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEYGUARD_QUICK_AFFORDANCE_ID_NONE @@ -90,7 +91,7 @@ constructor( private val dockManager: DockManager, private val biometricSettingsRepository: BiometricSettingsRepository, @Background private val backgroundDispatcher: CoroutineDispatcher, - @Application private val appContext: Context, + @ShadeDisplayAware private val appContext: Context, private val sceneInteractor: Lazy<SceneInteractor>, ) { /** diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt index 377a03edf88d..b9784f14fa1c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt @@ -23,6 +23,7 @@ import com.android.systemui.keyguard.shared.model.Edge import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor import com.android.systemui.util.kotlin.sample import com.android.systemui.util.kotlin.toPx @@ -45,7 +46,7 @@ class KeyguardSurfaceBehindInteractor @Inject constructor( private val repository: KeyguardSurfaceBehindRepository, - context: Context, + @ShadeDisplayAware context: Context, transitionInteractor: KeyguardTransitionInteractor, inWindowLauncherUnlockAnimationInteractor: Lazy<InWindowLauncherUnlockAnimationInteractor>, swipeToDismissInteractor: SwipeToDismissInteractor, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt index b2031d300a82..274a1ddbd392 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt @@ -34,6 +34,7 @@ import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.res.R import com.android.systemui.shade.PulsingGestureListener +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -58,7 +59,7 @@ import com.android.app.tracing.coroutines.launchTraced as launch class KeyguardTouchHandlingInteractor @Inject constructor( - @Application private val appContext: Context, + @ShadeDisplayAware private val context: Context, @Application private val scope: CoroutineScope, transitionInteractor: KeyguardTransitionInteractor, repository: KeyguardRepository, @@ -188,7 +189,7 @@ constructor( private fun isFeatureEnabled(): Boolean { return featureFlags.isEnabled(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED) && - appContext.resources.getBoolean(R.bool.long_press_keyguard_customize_lockscreen_enabled) + context.resources.getBoolean(R.bool.long_press_keyguard_customize_lockscreen_enabled) } /** Updates application state to ask to show the menu. */ diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt index 9c98a96ea908..fbc7e2aecbdf 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt @@ -38,6 +38,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.Companion.device import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.power.shared.model.WakeSleepReason import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.kotlin.sample import com.android.systemui.util.settings.SecureSettings @@ -75,7 +76,7 @@ class KeyguardWakeDirectlyToGoneInteractor @Inject constructor( @Application private val scope: CoroutineScope, - private val context: Context, + @ShadeDisplayAware private val context: Context, private val repository: KeyguardRepository, private val systemClock: SystemClock, private val alarmManager: AlarmManager, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NaturalScrollingSettingObserver.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NaturalScrollingSettingObserver.kt index 508fb597ef65..7e7742354a9c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NaturalScrollingSettingObserver.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NaturalScrollingSettingObserver.kt @@ -24,6 +24,7 @@ import android.provider.Settings import android.provider.Settings.SettingNotFoundException import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject @SysUISingleton @@ -31,7 +32,7 @@ class NaturalScrollingSettingObserver @Inject constructor( @Main private val handler: Handler, - private val context: Context, + @ShadeDisplayAware private val context: Context, ) { var isNaturalScrollingEnabled = true get() { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt index 73e80ff1d02b..d6a110a8fd55 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StatusBarDisableFlagsInteractor.kt @@ -40,6 +40,7 @@ import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.power.shared.model.WakeSleepReason import com.android.systemui.power.shared.model.WakefulnessModel import com.android.systemui.scene.shared.flag.SceneContainerFlag +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.user.domain.interactor.SelectedUserInteractor import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher @@ -62,7 +63,7 @@ class StatusBarDisableFlagsInteractor @Inject constructor( @Application private val scope: CoroutineScope, - @Application private val applicationContext: Context, + @ShadeDisplayAware private val context: Context, @Background private val backgroundDispatcher: CoroutineDispatcher, private val deviceEntryFaceAuthInteractor: DeviceEntryFaceAuthInteractor, private val statusBarService: IStatusBarService, @@ -142,7 +143,7 @@ constructor( scope.launch { disableFlagsForUserId.collect { (selectedUserId, flags) -> - if (applicationContext.getSystemService(Context.STATUS_BAR_SERVICE) == null) { + if (context.getSystemService(Context.STATUS_BAR_SERVICE) == null) { return@collect } @@ -151,7 +152,7 @@ constructor( statusBarService.disableForUser( flags, disableToken, - applicationContext.packageName, + context.packageName, selectedUserId, ) } catch (e: RemoteException) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/SwipeUpAnywhereGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/SwipeUpAnywhereGestureHandler.kt index 3540a0c6f016..b6aa209fad3f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/SwipeUpAnywhereGestureHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/SwipeUpAnywhereGestureHandler.kt @@ -20,6 +20,7 @@ import android.content.Context import android.view.MotionEvent import com.android.systemui.dagger.SysUISingleton import com.android.systemui.settings.DisplayTracker +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.gesture.SwipeUpGestureHandler import com.android.systemui.statusbar.gesture.SwipeUpGestureLogger import javax.inject.Inject @@ -29,7 +30,7 @@ import javax.inject.Inject class SwipeUpAnywhereGestureHandler @Inject constructor( - context: Context, + @ShadeDisplayAware context: Context, displayTracker: DisplayTracker, logger: SwipeUpGestureLogger, ) : diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt index 7292ddaf43a7..b30e1e9b1103 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt @@ -26,6 +26,7 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.keyguard.MigrateClocksToBlueprint import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor @@ -44,7 +45,6 @@ import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map -import com.android.app.tracing.coroutines.launchTraced as launch object KeyguardClockViewBinder { private val TAG = KeyguardClockViewBinder::class.simpleName!! @@ -133,15 +133,26 @@ object KeyguardClockViewBinder { launch { if (!MigrateClocksToBlueprint.isEnabled) return@launch aodBurnInViewModel.movement.collect { burnInModel -> - viewModel.currentClock.value?.let { - it.largeClock.layout.applyAodBurnIn( + viewModel.currentClock.value + ?.largeClock + ?.layout + ?.applyAodBurnIn( AodClockBurnInModel( translationX = burnInModel.translationX.toFloat(), translationY = burnInModel.translationY.toFloat(), scale = burnInModel.scale, ) ) - } + } + } + + launch { + if (!MigrateClocksToBlueprint.isEnabled) return@launch + viewModel.largeClockTextSize.collect { fontSizePx -> + viewModel.currentClock.value + ?.largeClock + ?.events + ?.onFontSettingChanged(fontSizePx = fontSizePx.toFloat()) } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AccessibilityActionsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AccessibilityActionsSection.kt index 717a89801ba4..587a8fe5a5c3 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AccessibilityActionsSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AccessibilityActionsSection.kt @@ -26,6 +26,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.keyguard.ui.binder.AccessibilityActionsViewBinder import com.android.systemui.keyguard.ui.viewmodel.AccessibilityActionsViewModel import com.android.systemui.res.R +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.util.Utils import javax.inject.Inject import kotlinx.coroutines.DisposableHandle @@ -37,7 +38,7 @@ import kotlinx.coroutines.DisposableHandle class AccessibilityActionsSection @Inject constructor( - private val context: Context, + @ShadeDisplayAware private val context: Context, private val communalSettingsInteractor: CommunalSettingsInteractor, private val accessibilityActionsViewModel: AccessibilityActionsViewModel, ) : KeyguardSection() { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt index d639978764f8..8622ffc04601 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt @@ -28,13 +28,14 @@ import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.keyguard.ui.view.KeyguardRootView import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.res.R +import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject /** Adds a layer to group elements for translation for burn-in preventation */ class AodBurnInSection @Inject constructor( - private val context: Context, + @ShadeDisplayAware private val context: Context, private val rootView: KeyguardRootView, private val clockViewModel: KeyguardClockViewModel, ) : KeyguardSection() { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt index faa497833e7b..08c3f153bc4e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt @@ -47,7 +47,7 @@ import kotlinx.coroutines.DisposableHandle class AodNotificationIconsSection @Inject constructor( - private val context: Context, + @ShadeDisplayAware private val context: Context, @ShadeDisplayAware private val configurationState: ConfigurationState, private val iconBindingFailureTracker: StatusBarIconViewBindingFailureTracker, private val nicAodViewModel: NotificationIconContainerAlwaysOnDisplayViewModel, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt index 6096cf74a772..c009720feaeb 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt @@ -45,6 +45,7 @@ import com.android.systemui.plugins.clocks.ClockController import com.android.systemui.plugins.clocks.ClockFaceLayout import com.android.systemui.res.R import com.android.systemui.shade.LargeScreenHeaderHelper +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.shared.R as sharedR import com.android.systemui.util.ui.value import dagger.Lazy @@ -69,7 +70,7 @@ class ClockSection constructor( private val clockInteractor: KeyguardClockInteractor, protected val keyguardClockViewModel: KeyguardClockViewModel, - private val context: Context, + @ShadeDisplayAware private val context: Context, val smartspaceViewModel: KeyguardSmartspaceViewModel, val blueprintInteractor: Lazy<KeyguardBlueprintInteractor>, private val rootViewModel: KeyguardRootViewModel, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt index 8d2bfb5bdf40..b51bb7b229ee 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt @@ -45,6 +45,7 @@ import com.android.systemui.log.dagger.LongPressTouchLog import com.android.systemui.plugins.FalsingManager import com.android.systemui.res.R import com.android.systemui.shade.NotificationPanelView +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.VibratorHelper import dagger.Lazy import javax.inject.Inject @@ -60,7 +61,7 @@ constructor( @Application private val applicationScope: CoroutineScope, private val authController: AuthController, private val windowManager: WindowManager, - private val context: Context, + @ShadeDisplayAware private val context: Context, private val notificationPanelView: NotificationPanelView, private val featureFlags: FeatureFlags, private val deviceEntryIconViewModel: Lazy<DeviceEntryIconViewModel>, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt index af0528a4c354..2d9dac41ba6e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultIndicationAreaSection.kt @@ -27,6 +27,7 @@ import com.android.systemui.keyguard.ui.binder.KeyguardIndicationAreaBinder import com.android.systemui.keyguard.ui.view.KeyguardIndicationArea import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel import com.android.systemui.res.R +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.KeyguardIndicationController import javax.inject.Inject import kotlinx.coroutines.DisposableHandle @@ -34,7 +35,7 @@ import kotlinx.coroutines.DisposableHandle class DefaultIndicationAreaSection @Inject constructor( - private val context: Context, + @ShadeDisplayAware private val context: Context, private val keyguardIndicationAreaViewModel: KeyguardIndicationAreaViewModel, private val indicationController: KeyguardIndicationController, ) : KeyguardSection() { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt index 6ac33af26605..3a791fd45528 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt @@ -28,6 +28,7 @@ import com.android.systemui.keyguard.MigrateClocksToBlueprint import com.android.systemui.res.R import com.android.systemui.shade.LargeScreenHeaderHelper import com.android.systemui.shade.NotificationPanelView +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer import com.android.systemui.statusbar.notification.stack.ui.viewbinder.SharedNotificationContainerBinder import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel @@ -38,7 +39,7 @@ import javax.inject.Inject class DefaultNotificationStackScrollLayoutSection @Inject constructor( - context: Context, + @ShadeDisplayAware context: Context, notificationPanelView: NotificationPanelView, sharedNotificationContainer: SharedNotificationContainer, sharedNotificationContainerViewModel: SharedNotificationContainerViewModel, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusBarSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusBarSection.kt index 9b5fae38059e..9d9be44f3153 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusBarSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusBarSection.kt @@ -31,6 +31,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.shade.NotificationPanelView +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.shade.ShadeViewStateProvider import com.android.systemui.statusbar.phone.KeyguardStatusBarView import com.android.systemui.util.Utils @@ -40,7 +41,7 @@ import javax.inject.Inject class DefaultStatusBarSection @Inject constructor( - private val context: Context, + @ShadeDisplayAware private val context: Context, private val notificationPanelView: NotificationPanelView, private val keyguardStatusBarViewComponentFactory: KeyguardStatusBarViewComponent.Factory, ) : KeyguardSection() { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt index 45641dbfc517..57ea1ad5575d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt @@ -38,6 +38,7 @@ import com.android.systemui.media.controls.ui.controller.KeyguardMediaController import com.android.systemui.res.R import com.android.systemui.shade.NotificationPanelView import com.android.systemui.shade.NotificationPanelViewController +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.policy.SplitShadeStateController import com.android.systemui.util.Utils import dagger.Lazy @@ -47,7 +48,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi class DefaultStatusViewSection @Inject constructor( - private val context: Context, + @ShadeDisplayAware private val context: Context, private val notificationPanelView: NotificationPanelView, private val keyguardStatusViewComponentFactory: KeyguardStatusViewComponent.Factory, private val keyguardViewConfigurator: Lazy<KeyguardViewConfigurator>, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultUdfpsAccessibilityOverlaySection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultUdfpsAccessibilityOverlaySection.kt index 2abb7ba37340..0ae1400b1906 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultUdfpsAccessibilityOverlaySection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultUdfpsAccessibilityOverlaySection.kt @@ -26,6 +26,7 @@ import com.android.systemui.deviceentry.ui.viewmodel.DeviceEntryUdfpsAccessibili import com.android.systemui.keyguard.KeyguardBottomAreaRefactor import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.res.R +import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -34,7 +35,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi class DefaultUdfpsAccessibilityOverlaySection @Inject constructor( - private val context: Context, + @ShadeDisplayAware private val context: Context, private val viewModel: DeviceEntryUdfpsAccessibilityOverlayViewModel, ) : KeyguardSection() { private val viewId = R.id.udfps_accessibility_overlay diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt index 6ddcae38ce92..7ad2ec5e3bf8 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt @@ -33,6 +33,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.keyguard.ui.binder.KeyguardSmartspaceViewBinder import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.res.R as R import com.android.systemui.shared.R as sharedR import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController @@ -44,7 +45,7 @@ import kotlinx.coroutines.DisposableHandle open class SmartspaceSection @Inject constructor( - val context: Context, + @ShadeDisplayAware val context: Context, val keyguardClockViewModel: KeyguardClockViewModel, val keyguardSmartspaceViewModel: KeyguardSmartspaceViewModel, private val keyguardSmartspaceInteractor: KeyguardSmartspaceInteractor, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeMediaSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeMediaSection.kt index 5dbba75411a5..0782846f52ae 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeMediaSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeMediaSection.kt @@ -33,13 +33,14 @@ import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.media.controls.ui.controller.KeyguardMediaController import com.android.systemui.res.R import com.android.systemui.shade.NotificationPanelView +import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject /** Aligns media on left side for split shade, below smartspace, date, and weather. */ class SplitShadeMediaSection @Inject constructor( - private val context: Context, + @ShadeDisplayAware private val context: Context, private val notificationPanelView: NotificationPanelView, private val keyguardMediaController: KeyguardMediaController ) : KeyguardSection() { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeNotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeNotificationStackScrollLayoutSection.kt index 1a7386678e14..729759a9ad00 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeNotificationStackScrollLayoutSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeNotificationStackScrollLayoutSection.kt @@ -26,6 +26,7 @@ import androidx.constraintlayout.widget.ConstraintSet.TOP import com.android.systemui.keyguard.MigrateClocksToBlueprint import com.android.systemui.res.R import com.android.systemui.shade.NotificationPanelView +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer import com.android.systemui.statusbar.notification.stack.ui.viewbinder.SharedNotificationContainerBinder import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel @@ -35,7 +36,7 @@ import javax.inject.Inject class SplitShadeNotificationStackScrollLayoutSection @Inject constructor( - context: Context, + @ShadeDisplayAware context: Context, notificationPanelView: NotificationPanelView, sharedNotificationContainer: SharedNotificationContainer, sharedNotificationContainerViewModel: SharedNotificationContainerViewModel, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt index 56e3125f7078..3a5263f3df77 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt @@ -41,7 +41,7 @@ import kotlinx.coroutines.flow.onStart class AlternateBouncerUdfpsIconViewModel @Inject constructor( - val context: Context, + @ShadeDisplayAware val context: Context, @ShadeDisplayAware configurationInteractor: ConfigurationInteractor, deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor, deviceEntryBackgroundViewModel: DeviceEntryBackgroundViewModel, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt index 12f9467c0f96..29ae4b94be6a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt @@ -40,7 +40,7 @@ import kotlinx.coroutines.flow.onStart class DeviceEntryBackgroundViewModel @Inject constructor( - val context: Context, + @ShadeDisplayAware val context: Context, val deviceEntryIconViewModel: DeviceEntryIconViewModel, keyguardTransitionInteractor: KeyguardTransitionInteractor, @ShadeDisplayAware configurationInteractor: ConfigurationInteractor, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt index 749f19315409..5065fcbbac93 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt @@ -45,7 +45,7 @@ import kotlinx.coroutines.flow.onStart class DeviceEntryForegroundViewModel @Inject constructor( - val context: Context, + @ShadeDisplayAware val context: Context, @ShadeDisplayAware configurationInteractor: ConfigurationInteractor, deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor, transitionInteractor: KeyguardTransitionInteractor, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt index 82adced1e1be..3a7a640be85f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt @@ -187,6 +187,9 @@ constructor( val largeClockTopMargin: Flow<Int> = configurationInteractor.onAnyConfigurationChange.map { getLargeClockTopMargin() } + val largeClockTextSize: Flow<Int> = + configurationInteractor.dimensionPixelSize(customR.dimen.large_clock_text_size) + enum class ClockLayout { LARGE_CLOCK, SMALL_CLOCK, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt index da96f3fd1f9c..3de1f1e6258e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/SideFpsProgressBarViewModel.kt @@ -40,6 +40,7 @@ import com.android.systemui.keyguard.shared.model.FingerprintAuthenticationStatu import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.res.R +import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.statusbar.phone.DozeServiceHost import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher @@ -66,7 +67,7 @@ import com.android.app.tracing.coroutines.launchTraced as launch class SideFpsProgressBarViewModel @Inject constructor( - private val context: Context, + @ShadeDisplayAware private val context: Context, biometricStatusInteractor: BiometricStatusInteractor, deviceEntryFingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor, private val sfpsSensorInteractor: SideFpsSensorInteractor, diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt index 51ff598c580b..21c45c550e08 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt @@ -51,6 +51,7 @@ import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect @@ -70,6 +71,7 @@ import androidx.compose.ui.layout.approachLayout import androidx.compose.ui.layout.onPlaced import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.layout.positionInRoot +import androidx.compose.ui.layout.positionOnScreen import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource @@ -77,6 +79,7 @@ import androidx.compose.ui.semantics.CustomAccessibilityAction import androidx.compose.ui.semantics.customActions import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.round import androidx.compose.ui.util.fastRoundToInt import androidx.compose.ui.viewinterop.AndroidView @@ -101,6 +104,8 @@ import com.android.systemui.Dumpable import com.android.systemui.brightness.ui.compose.BrightnessSliderContainer import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.dump.DumpManager +import com.android.systemui.keyboard.shortcut.ui.composable.InteractionsConfig +import com.android.systemui.keyboard.shortcut.ui.composable.ProvideShortcutHelperIndication import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.lifecycle.setSnapshotBinding import com.android.systemui.media.controls.ui.view.MediaHost @@ -124,6 +129,7 @@ import com.android.systemui.qs.ui.composable.QuickSettingsShade import com.android.systemui.qs.ui.composable.QuickSettingsTheme import com.android.systemui.res.R import com.android.systemui.util.LifecycleFragment +import com.android.systemui.util.animation.UniqueObjectHostView import com.android.systemui.util.asIndenting import com.android.systemui.util.printSection import com.android.systemui.util.println @@ -238,51 +244,54 @@ constructor( @Composable private fun Content() { - PlatformTheme { - AnimatedVisibility( - visible = viewModel.isQsVisible, - modifier = - Modifier.graphicsLayer { alpha = viewModel.viewAlpha } - // Clipping before translation to match QSContainerImpl.onDraw - .offset { - IntOffset(x = 0, y = viewModel.viewTranslationY.fastRoundToInt()) - } - .thenIf(notificationScrimClippingParams.isEnabled) { - Modifier.notificationScrimClip { - notificationScrimClippingParams.params + PlatformTheme(isDarkTheme = true) { + ProvideShortcutHelperIndication(interactionsConfig = interactionsConfig()) { + AnimatedVisibility( + visible = viewModel.isQsVisible, + modifier = + Modifier.graphicsLayer { alpha = viewModel.viewAlpha } + // Clipping before translation to match QSContainerImpl.onDraw + .offset { + IntOffset(x = 0, y = viewModel.viewTranslationY.fastRoundToInt()) + } + .thenIf(notificationScrimClippingParams.isEnabled) { + Modifier.notificationScrimClip { + notificationScrimClippingParams.params + } } + // Disable touches in the whole composable while the mirror is showing. + // While the mirror is showing, an ancestor of the ComposeView is made + // alpha 0, but touches are still being captured by the composables. + .gesturesDisabled(viewModel.showingMirror), + ) { + val isEditing by + viewModel.containerViewModel.editModeViewModel.isEditing + .collectAsStateWithLifecycle() + val animationSpecEditMode = tween<Float>(EDIT_MODE_TIME_MILLIS) + AnimatedContent( + targetState = isEditing, + transitionSpec = { + fadeIn(animationSpecEditMode) togetherWith + fadeOut(animationSpecEditMode) + }, + label = "EditModeAnimatedContent", + ) { editing -> + if (editing) { + val qqsPadding = viewModel.qqsHeaderHeight + EditMode( + viewModel = viewModel.containerViewModel.editModeViewModel, + modifier = + Modifier.fillMaxWidth() + .padding(top = { qqsPadding }) + .padding( + horizontal = { + QuickSettingsShade.Dimensions.Padding.roundToPx() + } + ), + ) + } else { + CollapsableQuickSettingsSTL() } - // Disable touches in the whole composable while the mirror is showing. - // While the mirror is showing, an ancestor of the ComposeView is made - // alpha 0, but touches are still being captured by the composables. - .gesturesDisabled(viewModel.showingMirror), - ) { - val isEditing by - viewModel.containerViewModel.editModeViewModel.isEditing - .collectAsStateWithLifecycle() - val animationSpecEditMode = tween<Float>(EDIT_MODE_TIME_MILLIS) - AnimatedContent( - targetState = isEditing, - transitionSpec = { - fadeIn(animationSpecEditMode) togetherWith fadeOut(animationSpecEditMode) - }, - label = "EditModeAnimatedContent", - ) { editing -> - if (editing) { - val qqsPadding = viewModel.qqsHeaderHeight - EditMode( - viewModel = viewModel.containerViewModel.editModeViewModel, - modifier = - Modifier.fillMaxWidth() - .padding(top = { qqsPadding }) - .padding( - horizontal = { - QuickSettingsShade.Dimensions.Padding.roundToPx() - } - ), - ) - } else { - CollapsableQuickSettingsSTL() } } } @@ -447,8 +456,7 @@ constructor( } override fun setShouldUpdateSquishinessOnMedia(shouldUpdate: Boolean) { - super.setShouldUpdateSquishinessOnMedia(shouldUpdate) - // TODO (b/353253280) + viewModel.shouldUpdateSquishinessOnMedia = shouldUpdate } override fun setInSplitShade(isInSplitShade: Boolean) { @@ -660,7 +668,20 @@ constructor( Column( modifier = - Modifier.offset { + Modifier.onPlaced { coordinates -> + val positionOnScreen = coordinates.positionOnScreen() + val left = positionOnScreen.x + val right = left + coordinates.size.width + val top = positionOnScreen.y + val bottom = top + coordinates.size.height + viewModel.applyNewQsScrollerBounds( + left = left, + top = top, + right = right, + bottom = bottom, + ) + } + .offset { IntOffset( x = 0, y = viewModel.qsScrollTranslationY.fastRoundToInt(), @@ -704,7 +725,10 @@ constructor( val Media = @Composable { if (viewModel.qsMediaVisible) { - MediaObject(mediaHost = viewModel.qsMediaHost) + MediaObject( + mediaHost = viewModel.qsMediaHost, + update = { translationY = viewModel.qsMediaTranslationY }, + ) } } Box( @@ -987,7 +1011,11 @@ private fun Modifier.gesturesDisabled(disabled: Boolean) = } @Composable -private fun MediaObject(mediaHost: MediaHost, modifier: Modifier = Modifier) { +private fun MediaObject( + mediaHost: MediaHost, + modifier: Modifier = Modifier, + update: UniqueObjectHostView.() -> Unit = {}, +) { Box { AndroidView( modifier = modifier, @@ -1000,6 +1028,7 @@ private fun MediaObject(mediaHost: MediaHost, modifier: Modifier = Modifier) { ) } }, + update = { view -> view.update() }, onReset = {}, ) } @@ -1068,3 +1097,14 @@ private object ResIdTags { const val qsScroll = "expanded_qs_scroll_view" const val qsFooterActions = "qs_footer_actions" } + +@Composable +private fun interactionsConfig() = + InteractionsConfig( + hoverOverlayColor = MaterialTheme.colorScheme.onSurface, + hoverOverlayAlpha = 0.11f, + pressedOverlayColor = MaterialTheme.colorScheme.onSurface, + pressedOverlayAlpha = 0.15f, + // we are OK using this as our content is clipped and all corner radius are larger than this + surfaceCornerRadius = 28.dp, + ) diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt index e912a0c7faa6..9029563b6321 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt @@ -26,6 +26,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import androidx.lifecycle.LifecycleCoroutineScope +import com.android.app.animation.Interpolators import com.android.app.tracing.coroutines.launchTraced as launch import com.android.keyguard.BouncerPanelExpansionCalculator import com.android.systemui.Dumpable @@ -270,6 +271,23 @@ constructor( val qsMediaInRow: Boolean get() = qsMediaInRowViewModel.shouldMediaShowInRow + var shouldUpdateSquishinessOnMedia by mutableStateOf(false) + + val qsMediaTranslationY by derivedStateOf { + if ( + qsExpansion > 0f && + !isKeyguardState && + !qqsMediaVisible && + !qsMediaInRow && + !isInSplitShade + ) { + val interpolation = Interpolators.ACCELERATE.getInterpolation(1f - qsExpansion) + -qsMediaHost.hostView.height * 1.3f * interpolation + } else { + 0f + } + } + val animateTilesExpansion: Boolean get() = inFirstPage && !mediaSuddenlyAppearingInLandscape @@ -297,6 +315,18 @@ constructor( MediaHostState.EXPANDED } + private val shouldApplySquishinessToMedia by derivedStateOf { + shouldUpdateSquishinessOnMedia || (isInSplitShade && statusBarState == StatusBarState.SHADE) + } + + private val mediaSquishiness by derivedStateOf { + if (shouldApplySquishinessToMedia) { + squishinessFraction + } else { + 1f + } + } + private var qsBounds by mutableStateOf(Rect()) private val constrainedSquishinessFraction: Float @@ -355,8 +385,6 @@ constructor( private val isOverscrolling: Boolean get() = overScrollAmount != 0 - private var shouldUpdateMediaSquishiness by mutableStateOf(false) - private val forceQs by derivedStateOf { (isQsExpanded || isStackScrollerOverscrolling) && (isKeyguardState && !showCollapsedOnKeyguard) @@ -394,11 +422,26 @@ constructor( ), ) + fun applyNewQsScrollerBounds(left: Float, top: Float, right: Float, bottom: Float) { + if (usingMedia) { + qsMediaHost.currentClipping.set( + left.toInt(), + top.toInt(), + right.toInt(), + bottom.toInt(), + ) + } + } + override suspend fun onActivated(): Nothing { initMediaHosts() // init regardless of using media (same as current QS). coroutineScope { launch { hydrateSquishinessInteractor() } - launch { hydrateQqsMediaExpansion() } + if (usingMedia) { + launch { hydrateQqsMediaExpansion() } + launch { hydrateMediaSquishiness() } + launch { hydrateMediaDisappearParameters() } + } launch { hydrator.activate() } launch { containerViewModel.activate() } launch { qqsMediaInRowViewModel.activate() } @@ -429,6 +472,21 @@ constructor( snapshotFlow { qqsMediaExpansion }.collect { qqsMediaHost.expansion = it } } + private suspend fun hydrateMediaSquishiness() { + snapshotFlow { mediaSquishiness }.collect { qsMediaHost.squishFraction = it } + } + + private suspend fun hydrateMediaDisappearParameters() { + coroutineScope { + launch { + snapshotFlow { qqsMediaInRow }.collect { qqsMediaHost.applyDisappearParameters(it) } + } + launch { + snapshotFlow { qsMediaInRow }.collect { qsMediaHost.applyDisappearParameters(it) } + } + } + } + override fun dump(pw: PrintWriter, args: Array<out String>) { pw.asIndenting().run { printSection("Quick Settings state") { @@ -474,6 +532,9 @@ constructor( println("qsMediaInRow", qsMediaInRow) println("collapsedLandscapeMedia", collapsedLandscapeMedia) println("qqsMediaExpansion", qqsMediaExpansion) + println("shouldUpdateSquishinessOnMedia", shouldUpdateSquishinessOnMedia) + println("mediaSquishiness", mediaSquishiness) + println("qsMediaTranslationY", qsMediaTranslationY) } } } @@ -510,3 +571,22 @@ private fun mediaHostVisible(mediaHost: MediaHost): Flow<Boolean> { // lazily. .onStart { emit(mediaHost.visible) } } + +// Taken from QSPanelControllerBase +private fun MediaHost.applyDisappearParameters(inRow: Boolean) { + disappearParameters.apply { + fadeStartPosition = 0.95f + disappearStart = 0f + if (inRow) { + disappearSize.set(0f, 0.4f) + gonePivot.set(1f, 0f) + contentTranslationFraction.set(0.25f, 1f) + disappearEnd = 0.6f + } else { + disappearSize.set(1f, 0f) + gonePivot.set(0f, 0f) + contentTranslationFraction.set(0f, 1f) + disappearEnd = 0.95f + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt index 2efe500912cd..4e094cc77eae 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt @@ -18,10 +18,13 @@ package com.android.systemui.qs.panels.ui.compose import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.foundation.shape.CornerSize +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Edit import androidx.compose.material3.Icon @@ -32,7 +35,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment @@ -41,6 +43,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.SceneScope +import com.android.compose.modifiers.padding import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.lifecycle.rememberViewModel import com.android.systemui.qs.panels.dagger.PaginatedBaseLayoutType @@ -48,6 +51,7 @@ import com.android.systemui.qs.panels.ui.compose.PaginatedGridLayout.Dimensions. import com.android.systemui.qs.panels.ui.compose.PaginatedGridLayout.Dimensions.InterPageSpacing import com.android.systemui.qs.panels.ui.viewmodel.PaginatedGridViewModel import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel +import com.android.systemui.qs.ui.compose.borderOnFocus import com.android.systemui.res.R import javax.inject.Inject @@ -89,9 +93,24 @@ constructor( } Column { + val contentPaddingValue = + if (pages.size > 1) { + InterPageSpacing + } else { + 0.dp + } + val contentPadding = PaddingValues(horizontal = contentPaddingValue) + + /* Use negative padding equal with value equal to content padding. That way, each page + * layout extends to the sides, but the content is as if there was no padding. That + * way, the clipping bounds of the HorizontalPager extend beyond the tiles in each page. + */ HorizontalPager( state = pagerState, - modifier = Modifier.sysuiResTag("qs_pager"), + modifier = + Modifier.sysuiResTag("qs_pager") + .padding(horizontal = { -contentPaddingValue.roundToPx() }), + contentPadding = contentPadding, pageSpacing = if (pages.size > 1) InterPageSpacing else 0.dp, beyondViewportPageCount = 1, verticalAlignment = Alignment.Top, @@ -114,7 +133,13 @@ constructor( CompositionLocalProvider(value = LocalContentColor provides Color.White) { IconButton( onClick = editModeStart, - modifier = Modifier.align(Alignment.CenterEnd), + shape = RoundedCornerShape(CornerSize(28.dp)), + modifier = + Modifier.align(Alignment.CenterEnd) + .borderOnFocus( + color = MaterialTheme.colorScheme.secondary, + cornerSize = CornerSize(FooterHeight / 2), + ), ) { Icon( imageVector = Icons.Default.Edit, diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt index 4a51bf06d4af..0e09ad29f4fd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt @@ -17,6 +17,7 @@ package com.android.systemui.qs.panels.ui.compose.infinitegrid import android.graphics.drawable.Animatable +import android.graphics.drawable.Drawable import android.text.TextUtils import androidx.compose.animation.animateColorAsState import androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi @@ -30,7 +31,9 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicText import androidx.compose.material3.MaterialTheme @@ -47,7 +50,6 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.graphics.Shape import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role @@ -68,8 +70,11 @@ import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.ui.compose.Icon import com.android.systemui.common.ui.compose.load import com.android.systemui.compose.modifiers.sysuiResTag +import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.SideIconHeight +import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.SideIconWidth import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.longPressLabel import com.android.systemui.qs.panels.ui.viewmodel.AccessibilityUiState +import com.android.systemui.qs.ui.compose.borderOnFocus import com.android.systemui.res.R private const val TEST_TAG_TOGGLE = "qs_tile_toggle_target" @@ -79,10 +84,11 @@ fun LargeTileContent( label: String, secondaryLabel: String?, icon: Icon, + sideDrawable: Drawable?, colors: TileColors, squishiness: () -> Float, accessibilityUiState: AccessibilityUiState? = null, - iconShape: Shape = RoundedCornerShape(CommonTileDefaults.InactiveCornerRadius), + iconShape: RoundedCornerShape = RoundedCornerShape(CommonTileDefaults.InactiveCornerRadius), toggleClick: (() -> Unit)? = null, onLongClick: (() -> Unit)? = null, ) { @@ -94,10 +100,12 @@ fun LargeTileContent( val longPressLabel = longPressLabel().takeIf { onLongClick != null } val animatedBackgroundColor by animateColorAsState(colors.iconBackground, label = "QSTileDualTargetBackgroundColor") + val focusBorderColor = MaterialTheme.colorScheme.secondary Box( modifier = Modifier.size(CommonTileDefaults.ToggleTargetSize).thenIf(toggleClick != null) { - Modifier.clip(iconShape) + Modifier.borderOnFocus(color = focusBorderColor, iconShape.topEnd) + .clip(iconShape) .verticalSquish(squishiness) .drawBehind { drawRect(animatedBackgroundColor) } .combinedClickable( @@ -135,6 +143,14 @@ fun LargeTileContent( colors = colors, accessibilityUiState = accessibilityUiState, ) + + if (sideDrawable != null) { + Image( + painter = rememberDrawablePainter(sideDrawable), + contentDescription = null, + modifier = Modifier.width(SideIconWidth).height(SideIconHeight), + ) + } } } @@ -229,6 +245,8 @@ fun SmallTileContent( object CommonTileDefaults { val IconSize = 32.dp val LargeTileIconSize = 28.dp + val SideIconWidth = 32.dp + val SideIconHeight = 20.dp val ToggleTargetSize = 56.dp val TileHeight = 72.dp val TilePadding = 8.dp diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt index 9bbf290a53f0..cb57c6710553 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt @@ -39,6 +39,7 @@ import androidx.compose.foundation.lazy.grid.LazyGridScope import androidx.compose.foundation.lazy.grid.LazyGridState import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.rememberLazyGridState +import androidx.compose.foundation.shape.CornerSize import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable @@ -49,6 +50,7 @@ import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape import androidx.compose.ui.platform.LocalConfiguration @@ -59,6 +61,7 @@ import androidx.compose.ui.semantics.role import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.semantics.toggleableState +import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -82,6 +85,7 @@ import com.android.systemui.qs.panels.ui.viewmodel.TileUiState import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel import com.android.systemui.qs.panels.ui.viewmodel.toUiState import com.android.systemui.qs.tileimpl.QSTileImpl +import com.android.systemui.qs.ui.compose.borderOnFocus import com.android.systemui.res.R import java.util.function.Supplier import kotlinx.coroutines.CoroutineScope @@ -130,15 +134,7 @@ fun Tile( // TODO(b/361789146): Draw the shapes instead of clipping val tileShape = TileDefaults.animateTileShape(uiState.state) - val animatedColor by - animateColorAsState( - if (iconOnly || !uiState.handlesSecondaryClick) { - colors.iconBackground - } else { - colors.background - }, - label = "QSTileBackgroundColor", - ) + val animatedColor by animateColorAsState(colors.background, label = "QSTileBackgroundColor") TileExpandable( color = { animatedColor }, @@ -147,6 +143,7 @@ fun Tile( hapticsViewModel = hapticsViewModel, modifier = modifier + .borderOnFocus(color = MaterialTheme.colorScheme.secondary, tileShape.topEnd) .fillMaxWidth() .bounceable( bounceable = currentBounceableInfo.bounceable, @@ -199,6 +196,7 @@ fun Tile( label = uiState.label, secondaryLabel = uiState.secondaryLabel, icon = icon, + sideDrawable = uiState.sideDrawable, colors = colors, iconShape = iconShape, toggleClick = secondaryClick, @@ -388,7 +386,7 @@ private object TileDefaults { } @Composable - fun animateIconShape(state: Int): Shape { + fun animateIconShape(state: Int): RoundedCornerShape { return animateShape( state = state, activeCornerRadius = ActiveIconCornerRadius, @@ -397,7 +395,7 @@ private object TileDefaults { } @Composable - fun animateTileShape(state: Int): Shape { + fun animateTileShape(state: Int): RoundedCornerShape { return animateShape( state = state, activeCornerRadius = ActiveTileCornerRadius, @@ -406,7 +404,7 @@ private object TileDefaults { } @Composable - fun animateShape(state: Int, activeCornerRadius: Dp, label: String): Shape { + fun animateShape(state: Int, activeCornerRadius: Dp, label: String): RoundedCornerShape { val animatedCornerRadius by animateDpAsState( targetValue = @@ -417,7 +415,15 @@ private object TileDefaults { }, label = label, ) - return RoundedCornerShape(animatedCornerRadius) + + val corner = remember { + object : CornerSize { + override fun toPx(shapeSize: Size, density: Density): Float { + return with(density) { animatedCornerRadius.toPx() } + } + } + } + return RoundedCornerShape(corner) } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt index 56675e49d4e6..2fc7f0f9d67b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt @@ -17,6 +17,7 @@ package com.android.systemui.qs.panels.ui.viewmodel import android.content.res.Resources +import android.graphics.drawable.Drawable import android.service.quicksettings.Tile import android.text.TextUtils import android.widget.Switch @@ -36,6 +37,7 @@ data class TileUiState( val handlesLongClick: Boolean, val handlesSecondaryClick: Boolean, val icon: Supplier<QSTile.Icon?>, + val sideDrawable: Drawable?, val accessibilityUiState: AccessibilityUiState, ) @@ -90,6 +92,7 @@ fun QSTile.State.toUiState(resources: Resources): TileUiState { handlesLongClick = handlesLongClick, handlesSecondaryClick = handlesSecondaryClick, icon = icon?.let { Supplier { icon } } ?: iconSupplier ?: Supplier { null }, + sideDrawable = sideViewCustomDrawable, AccessibilityUiState( contentDescription?.toString() ?: "", stateDescription.toString(), diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt index 736e1a5cb9b6..57a60c179581 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt @@ -75,10 +75,10 @@ constructor( override fun availability(user: UserHandle): Flow<Boolean> = flowOf(true) private fun hasSufficientPermission(): Boolean { - val rotationPackage: String = packageManager.rotationResolverPackageName - return rotationPackage != null && - packageManager.checkPermission(Manifest.permission.CAMERA, rotationPackage) == + return packageManager.rotationResolverPackageName?.let { + packageManager.checkPermission(Manifest.permission.CAMERA, it) == PackageManager.PERMISSION_GRANTED + } ?: false } private fun isCameraRotationEnabled( diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/compose/BorderOnFocus.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/compose/BorderOnFocus.kt new file mode 100644 index 000000000000..e6caa0d7520d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/ui/compose/BorderOnFocus.kt @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.qs.ui.compose + +import androidx.compose.foundation.shape.CornerSize +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusEventModifierNode +import androidx.compose.ui.focus.FocusState +import androidx.compose.ui.geometry.CornerRadius +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Rect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.drawscope.ContentDrawScope +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.node.DrawModifierNode +import androidx.compose.ui.node.ModifierNodeElement +import androidx.compose.ui.platform.InspectorInfo +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +/** + * Provides a rounded rect border when the element is focused. + * + * This should be used for elements that are themselves rounded rects. + */ +fun Modifier.borderOnFocus( + color: Color, + cornerSize: CornerSize, + strokeWidth: Dp = 3.dp, + padding: Dp = 2.dp, +) = this then BorderOnFocusElement(color, cornerSize, strokeWidth, padding) + +private class BorderOnFocusNode( + var color: Color, + var cornerSize: CornerSize, + var strokeWidth: Dp, + var padding: Dp, +) : FocusEventModifierNode, DrawModifierNode, Modifier.Node() { + + private var focused by mutableStateOf(false) + + override fun onFocusEvent(focusState: FocusState) { + focused = focusState.isFocused + } + + override fun ContentDrawScope.draw() { + drawContent() + val focusOutline = Rect(Offset.Zero, size).inflate(padding.toPx()) + if (focused) { + drawRoundRect( + color = color, + topLeft = focusOutline.topLeft, + size = focusOutline.size, + cornerRadius = CornerRadius(cornerSize.toPx(focusOutline.size, this)), + style = Stroke(strokeWidth.toPx()), + ) + } + } +} + +private data class BorderOnFocusElement( + val color: Color, + val cornerSize: CornerSize, + val strokeWidth: Dp, + val padding: Dp, +) : ModifierNodeElement<BorderOnFocusNode>() { + override fun create(): BorderOnFocusNode { + return BorderOnFocusNode(color, cornerSize, strokeWidth, padding) + } + + override fun update(node: BorderOnFocusNode) { + node.color = color + node.cornerSize = cornerSize + node.strokeWidth = strokeWidth + node.padding = padding + } + + override fun InspectorInfo.inspectableProperties() { + name = "borderOnFocus" + properties["color"] = color + properties["cornerSize"] = cornerSize + properties["strokeWidth"] = strokeWidth + properties["padding"] = padding + } +} diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt index 580a51a3dc0a..daeaaa52fd94 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt @@ -373,6 +373,7 @@ constructor( "device was unlocked with alternate bouncer showing" + " and shade didn't need to be left open" } else { + replaceLockscreenSceneOnBackStack() null } } @@ -391,16 +392,7 @@ constructor( val prevScene = previousScene.value val targetScene = prevScene ?: Scenes.Gone if (targetScene != Scenes.Gone) { - sceneBackInteractor.updateBackStack { stack -> - val list = stack.asIterable().toMutableList() - check(list.last() == Scenes.Lockscreen) { - "The bottommost/last SceneKey of the back stack isn't" + - " the Lockscreen scene like expected. The back" + - " stack is $stack." - } - list[list.size - 1] = Scenes.Gone - sceneStackOf(*list.toTypedArray()) - } + replaceLockscreenSceneOnBackStack() } targetScene to "device was unlocked with primary bouncer showing," + @@ -435,6 +427,20 @@ constructor( } } + /** If the [Scenes.Lockscreen] is on the backstack, replaces it with [Scenes.Gone]. */ + private fun replaceLockscreenSceneOnBackStack() { + sceneBackInteractor.updateBackStack { stack -> + val list = stack.asIterable().toMutableList() + check(list.last() == Scenes.Lockscreen) { + "The bottommost/last SceneKey of the back stack isn't" + + " the Lockscreen scene like expected. The back" + + " stack is $stack." + } + list[list.size - 1] = Scenes.Gone + sceneStackOf(*list.toTypedArray()) + } + } + private fun handlePowerState() { applicationScope.launch { powerInteractor.detailedWakefulness.collect { wakefulness -> diff --git a/packages/SystemUI/src/com/android/systemui/shade/StatusBarLongPressGestureDetector.kt b/packages/SystemUI/src/com/android/systemui/shade/LongPressGestureDetector.kt index ae36e81c7b1f..6fb3ca5f86d2 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/StatusBarLongPressGestureDetector.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/LongPressGestureDetector.kt @@ -25,7 +25,7 @@ import javax.inject.Inject /** Accepts touch events, detects long press, and calls ShadeViewController#onStatusBarLongPress. */ @SysUISingleton -class StatusBarLongPressGestureDetector +class LongPressGestureDetector @Inject constructor(context: Context, val shadeViewController: ShadeViewController) { val gestureDetector = diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index c15c8f946855..0e82bf82fdf9 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -2053,9 +2053,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } if (mQsController.getExpanded()) { mQsController.flingQs(0, FLING_COLLAPSE); - } else if (mBarState == KEYGUARD) { - mLockscreenShadeTransitionController.goToLockedShade( - /* expandedView= */null, /* needsQSAnimation= */false); } else { expand(true /* animate */); } @@ -3112,7 +3109,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump if (isTracking()) { onTrackingStopped(true); } - if (isExpanded() && mBarState != KEYGUARD && !mQsController.getExpanded()) { + if (isExpanded() && !mQsController.getExpanded()) { mShadeLog.d("Status Bar was long pressed. Expanding to QS."); expandToQs(); } else { @@ -5094,13 +5091,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } boolean handled = mHeadsUpTouchHelper.onTouchEvent(event); - // This touch session has already resulted in shade expansion. Ignore everything else. - if (ShadeExpandsOnStatusBarLongPress.isEnabled() - && event.getActionMasked() != MotionEvent.ACTION_DOWN - && event.getDownTime() == mStatusBarLongPressDowntime) { - mShadeLog.d("Touch has same down time as Status Bar long press. Ignoring."); - return false; - } if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && mQsController.handleTouch( event, isFullyCollapsed(), isShadeOrQsHeightAnimationRunning())) { if (event.getActionMasked() != MotionEvent.ACTION_MOVE) { @@ -5108,6 +5098,13 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } return true; } + // This touch session has already resulted in shade expansion. Ignore everything else. + if (ShadeExpandsOnStatusBarLongPress.isEnabled() + && event.getActionMasked() != MotionEvent.ACTION_DOWN + && event.getDownTime() == mStatusBarLongPressDowntime) { + mShadeLog.d("Touch has same down time as Status Bar long press. Ignoring."); + return false; + } if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()) { mMetricsLogger.count(COUNTER_PANEL_OPEN, 1); handled = true; diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java index 24dba59a1d54..4d77e3ecea7b 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java @@ -17,8 +17,6 @@ package com.android.systemui.shade; import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; -import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; -import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_OPTIMIZE_MEASURE; import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT; import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; @@ -27,16 +25,13 @@ import android.app.IActivityManager; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.Configuration; -import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Region; -import android.os.Binder; import android.os.Build; import android.os.RemoteException; import android.os.Trace; import android.util.Log; import android.view.Display; -import android.view.Gravity; import android.view.IWindow; import android.view.IWindowSession; import android.view.View; @@ -271,33 +266,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW // Now that the notification shade encompasses the sliding panel and its // translucent backdrop, the entire thing is made TRANSLUCENT and is // hardware-accelerated. - mLp = new LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT, - LayoutParams.TYPE_NOTIFICATION_SHADE, - LayoutParams.FLAG_NOT_FOCUSABLE - | LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING - | LayoutParams.FLAG_SPLIT_TOUCH - | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH - | LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, - PixelFormat.TRANSLUCENT); - mLp.token = new Binder(); - mLp.gravity = Gravity.TOP; - mLp.setFitInsetsTypes(0 /* types */); - mLp.setTitle("NotificationShade"); - mLp.packageName = mContext.getPackageName(); - mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; - mLp.privateFlags |= PRIVATE_FLAG_OPTIMIZE_MEASURE; - - if (SceneContainerFlag.isEnabled()) { - // This prevents the appearance and disappearance of the software keyboard (also known - // as the "IME") from scrolling/panning the window to make room for the keyboard. - // - // The scene container logic does its own adjustment and animation when the IME appears - // or disappears. - mLp.softInputMode = LayoutParams.SOFT_INPUT_ADJUST_NOTHING; - } - + mLp = ShadeWindowLayoutParams.INSTANCE.create(mContext); mWindowManager.addView(mWindowRootView, mLp); // We use BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE here, however, there is special logic in diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt index 63510b873951..e15830eb22eb 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt @@ -157,7 +157,6 @@ object ShadeDisplayAwareModule { @SysUISingleton @Provides - @ShadeDisplayAware fun provideShadePositionRepository(impl: ShadePositionRepositoryImpl): ShadePositionRepository { ShadeWindowGoesAround.isUnexpectedlyInLegacyMode() return impl diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLayoutParams.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLayoutParams.kt new file mode 100644 index 000000000000..6bb50f99b5e7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeWindowLayoutParams.kt @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.shade + +import android.content.Context +import android.graphics.PixelFormat +import android.os.Binder +import android.view.Gravity +import android.view.ViewGroup +import android.view.WindowManager.LayoutParams +import com.android.systemui.scene.shared.flag.SceneContainerFlag + +object ShadeWindowLayoutParams { + /** + * Creates [LayoutParams] for the shade window. + * + * This is extracted to a single place as those layout params will be used by several places: + * - When sysui starts, and the shade is added the first time + * - When the shade moves to a different window (e.g. while an external display is connected) + */ + fun create(context: Context): LayoutParams { + return LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT, + LayoutParams.TYPE_NOTIFICATION_SHADE, + LayoutParams.FLAG_NOT_FOCUSABLE or + LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING or + LayoutParams.FLAG_SPLIT_TOUCH or + LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or + LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, + // Now that the notification shade encompasses the sliding panel and its + // translucent backdrop, the entire thing is made TRANSLUCENT and is + // hardware-accelerated. + PixelFormat.TRANSLUCENT, + ) + .apply { + token = Binder() + gravity = Gravity.TOP + fitInsetsTypes = 0 + title = "NotificationShade" + packageName = context.packageName + layoutInDisplayCutoutMode = LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS + privateFlags = privateFlags or LayoutParams.PRIVATE_FLAG_OPTIMIZE_MEASURE + if (SceneContainerFlag.isEnabled) { + // This prevents the appearance and disappearance of the software keyboard (also + // known as the "IME") from scrolling/panning the window to make room for the + // keyboard. + // + // The scene container logic does its own adjustment and animation when the IME + // appears or disappears. + softInputMode = LayoutParams.SOFT_INPUT_ADJUST_NOTHING + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/FakeShadePositionRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/FakeShadePositionRepository.kt new file mode 100644 index 000000000000..37210b90ee78 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/FakeShadePositionRepository.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.shade.data.repository + +import android.view.Display +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow + +class FakeShadePositionRepository : ShadePositionRepository { + private val _displayId = MutableStateFlow(Display.DEFAULT_DISPLAY) + + override fun setDisplayId(displayId: Int) { + _displayId.value = displayId + } + + override val displayId: StateFlow<Int> + get() = _displayId + + override fun resetDisplayId() { + _displayId.value = Display.DEFAULT_DISPLAY + } +} diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt new file mode 100644 index 000000000000..4e7898d2fd2d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.shade.domain.interactor + +import android.content.Context +import android.util.Log +import android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE +import com.android.app.tracing.coroutines.launchTraced +import com.android.app.tracing.traceSection +import com.android.systemui.CoreStartable +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository +import com.android.systemui.display.shared.model.DisplayWindowProperties +import com.android.systemui.scene.ui.view.WindowRootView +import com.android.systemui.shade.ShadeDisplayAware +import com.android.systemui.shade.ShadeWindowLayoutParams +import com.android.systemui.shade.data.repository.ShadePositionRepository +import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround +import com.android.systemui.statusbar.phone.ConfigurationForwarder +import javax.inject.Inject +import kotlin.coroutines.CoroutineContext +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.withContext + +/** Handles Shade window display change when [ShadePositionRepository.displayId] changes. */ +@SysUISingleton +class ShadeDisplaysInteractor +@Inject +constructor( + private val shadeRootView: WindowRootView, + private val shadePositionRepository: ShadePositionRepository, + @ShadeDisplayAware private val shadeContext: Context, + private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository, + @Background private val bgScope: CoroutineScope, + @ShadeDisplayAware private val configurationForwarder: ConfigurationForwarder, + @Main private val mainContext: CoroutineContext, +) : CoreStartable { + + override fun start() { + ShadeWindowGoesAround.isUnexpectedlyInLegacyMode() + bgScope.launchTraced(TAG) { + shadePositionRepository.displayId.collect { displayId -> moveShadeWindowTo(displayId) } + } + } + + /** Tries to move the shade. If anything wrong happens, fails gracefully without crashing. */ + private suspend fun moveShadeWindowTo(destinationDisplayId: Int) { + val currentId = shadeRootView.display.displayId + if (currentId == destinationDisplayId) { + Log.w(TAG, "Trying to move the shade to a display it was already in") + return + } + try { + moveShadeWindow(fromId = currentId, toId = destinationDisplayId) + } catch (e: IllegalStateException) { + Log.e( + TAG, + "Unable to move the shade window from display $currentId to $destinationDisplayId", + e, + ) + } + } + + private suspend fun moveShadeWindow(fromId: Int, toId: Int) { + val sourceProperties = getDisplayWindowProperties(fromId) + val destinationProperties = getDisplayWindowProperties(toId) + traceSection({ "MovingShadeWindow from $fromId to $toId" }) { + withContext(mainContext) { + traceSection("removeView") { + sourceProperties.windowManager.removeView(shadeRootView) + } + traceSection("addView") { + destinationProperties.windowManager.addView( + shadeRootView, + ShadeWindowLayoutParams.create(shadeContext), + ) + } + } + } + traceSection("SecondaryShadeInteractor#onConfigurationChanged") { + configurationForwarder.onConfigurationChanged( + destinationProperties.context.resources.configuration + ) + } + } + + private fun getDisplayWindowProperties(displayId: Int): DisplayWindowProperties { + return displayWindowPropertiesRepository.get(displayId, TYPE_NOTIFICATION_SHADE) + } + + private companion object { + const val TAG = "SecondaryShadeInteractor" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt b/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt index 6f492cfaa6c3..c23ff5302b3c 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/shared/flag/ShadeWindowGoesAround.kt @@ -32,7 +32,7 @@ object ShadeWindowGoesAround { /** Is the refactor enabled */ @JvmStatic - inline val isEnabled + inline val isEnabled: Boolean get() = Flags.shadeWindowGoesAround() /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipLogTags.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipLogTags.kt new file mode 100644 index 000000000000..6c1d6c52088f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipLogTags.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.chips + +/** Helper class to ensure all tags used in [StatusBarChipsLog] are exactly the same length. */ +object StatusBarChipLogTags { + private const val TAG_LENGTH = 20 + + fun String.pad(): String { + return this.padEnd(TAG_LENGTH) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt index eaefc111ae3d..bb0467f10e16 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt @@ -20,6 +20,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.LogLevel +import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad import com.android.systemui.statusbar.chips.StatusBarChipsLog import com.android.systemui.statusbar.phone.ongoingcall.data.repository.OngoingCallRepository import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel @@ -47,6 +48,6 @@ constructor( .stateIn(scope, SharingStarted.Lazily, OngoingCallModel.NoCall) companion object { - private const val TAG = "OngoingCall" + private val TAG = "OngoingCall".pad() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt index e82525810c64..b8cdd2587774 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt @@ -28,6 +28,7 @@ import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.LogLevel import com.android.systemui.plugins.ActivityStarter import com.android.systemui.res.R +import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad import com.android.systemui.statusbar.chips.StatusBarChipsLog import com.android.systemui.statusbar.chips.call.domain.interactor.CallChipInteractor import com.android.systemui.statusbar.chips.ui.model.ColorsModel @@ -112,7 +113,7 @@ constructor( ActivityTransitionAnimator.Controller.fromView( backgroundView, InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP, - ) + ), ) } } @@ -121,10 +122,8 @@ constructor( private val phoneIcon = Icon.Resource( com.android.internal.R.drawable.ic_phone, - ContentDescription.Resource( - R.string.ongoing_phone_call_content_description, - ), + ContentDescription.Resource(R.string.ongoing_phone_call_content_description), ) - private const val TAG = "CallVM" + private val TAG = "CallVM".pad() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt index 7c95f1e42080..b3dbf299e7cc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt @@ -21,6 +21,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.LogLevel import com.android.systemui.mediarouter.data.repository.MediaRouterRepository +import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad import com.android.systemui.statusbar.chips.StatusBarChipsLog import com.android.systemui.statusbar.chips.casttootherdevice.domain.model.MediaRouterCastModel import com.android.systemui.statusbar.policy.CastDevice @@ -68,6 +69,6 @@ constructor( } companion object { - private const val TAG = "MediaRouter" + private val TAG = "MediaRouter".pad() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt index 11072068bef9..3422337523f9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt @@ -28,6 +28,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.LogLevel import com.android.systemui.res.R +import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad import com.android.systemui.statusbar.chips.StatusBarChipsLog import com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor.MediaRouterChipInteractor import com.android.systemui.statusbar.chips.casttootherdevice.domain.model.MediaRouterCastModel @@ -255,6 +256,6 @@ constructor( companion object { @DrawableRes val CAST_TO_OTHER_DEVICE_ICON = R.drawable.ic_cast_connected - private const val TAG = "CastToOtherVM" + private val TAG = "CastToOtherVM".pad() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt index 27b2465d52b3..af238f697a18 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.chips.mediaprojection.domain.interactor import android.content.pm.PackageManager +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.Flags import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application @@ -25,6 +26,7 @@ import com.android.systemui.log.core.LogLevel import com.android.systemui.mediaprojection.MediaProjectionUtils.packageHasCastingCapabilities import com.android.systemui.mediaprojection.data.model.MediaProjectionState import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepository +import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad import com.android.systemui.statusbar.chips.StatusBarChipsLog import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel import javax.inject.Inject @@ -33,7 +35,6 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn -import com.android.app.tracing.coroutines.launchTraced as launch /** * Interactor for media projection events, used to show chips in the status bar for share-to-app and @@ -108,6 +109,6 @@ constructor( } companion object { - private const val TAG = "MediaProjection" + private val TAG = "MediaProjection".pad() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt index e3dc70af5fe6..f5952f4804fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt @@ -25,6 +25,7 @@ import com.android.systemui.mediaprojection.data.model.MediaProjectionState import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepository import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository +import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad import com.android.systemui.statusbar.chips.StatusBarChipsLog import com.android.systemui.statusbar.chips.screenrecord.domain.model.ScreenRecordChipModel import javax.inject.Inject @@ -143,6 +144,6 @@ constructor( } companion object { - private const val TAG = "ScreenRecord" + private val TAG = "ScreenRecord".pad() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt index eb735211a970..0065593c7b73 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt @@ -30,6 +30,7 @@ import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.LogLevel import com.android.systemui.res.R import com.android.systemui.screenrecord.data.model.ScreenRecordModel.Starting.Companion.toCountdownSeconds +import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad import com.android.systemui.statusbar.chips.StatusBarChipsLog import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.ScreenRecordChipInteractor @@ -84,7 +85,7 @@ constructor( Icon.Resource( ICON, ContentDescription.Resource( - R.string.screenrecord_ongoing_screen_only, + R.string.screenrecord_ongoing_screen_only ), ) ), @@ -153,6 +154,6 @@ constructor( companion object { @DrawableRes val ICON = R.drawable.ic_screenrecord - private const val TAG = "ScreenRecordVM" + private val TAG = "ScreenRecordVM".pad() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt index 11d077fc09f1..2af86a51cf70 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt @@ -28,6 +28,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.LogLevel import com.android.systemui.res.R +import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad import com.android.systemui.statusbar.chips.StatusBarChipsLog import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractor import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel @@ -179,6 +180,6 @@ constructor( companion object { @DrawableRes val SHARE_TO_APP_ICON = R.drawable.ic_present_to_all - private const val TAG = "ShareToAppVM" + private val TAG = "ShareToAppVM".pad() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt index ed325970ebb2..45efc57685f7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt @@ -20,6 +20,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.LogLevel +import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad import com.android.systemui.statusbar.chips.StatusBarChipsLog import com.android.systemui.statusbar.chips.call.ui.viewmodel.CallChipViewModel import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.CastToOtherDeviceChipViewModel @@ -347,7 +348,7 @@ constructor( } companion object { - private const val TAG = "ChipsViewModel" + private val TAG = "ChipsViewModel".pad() private val DEFAULT_INTERNAL_HIDDEN_MODEL = InternalChipModel.Hidden( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt index 564d52a62cde..1cb4c44d10e9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt @@ -27,7 +27,10 @@ import kotlinx.coroutines.flow.StateFlow interface SystemStatusAnimationScheduler : CallbackController<SystemStatusAnimationCallback>, Dumpable { - /** StateFlow holding the current [SystemEventAnimationState] at any time. */ + /** + * The current state of the animation. This can be used from compose functions to coordinate + * their animations with the chip + */ val animationState: StateFlow<SystemEventAnimationState> fun onStatusEvent(event: StatusEvent) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepository.kt new file mode 100644 index 000000000000..971f5d1b04f2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepository.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.events.data.repository + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState +import javax.inject.Inject +import kotlinx.coroutines.flow.StateFlow + +/** Repository to expose the [SystemStatusAnimationScheduler] state via flows */ +interface SystemStatusEventAnimationRepository { + val animationState: StateFlow<SystemEventAnimationState> +} + +@SysUISingleton +class SystemStatusEventAnimationRepositoryImpl +@Inject +constructor(scheduler: SystemStatusAnimationScheduler) : SystemStatusEventAnimationRepository { + override val animationState = scheduler.animationState +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractor.kt new file mode 100644 index 000000000000..3e3064223595 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractor.kt @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.events.domain.interactor + +import android.view.View +import androidx.core.animation.Animator +import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.res.R +import com.android.systemui.statusbar.events.data.repository.SystemStatusEventAnimationRepository +import com.android.systemui.statusbar.phone.fragment.StatusBarSystemEventDefaultAnimator +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.stateIn + +/** + * Interactor for dealing with system status event animations. This class can be used to monitor the + * current [animationState], and defines some common animation functions that an handle hiding + * system chrome in order to make space for the event chips + */ +@SysUISingleton +class SystemStatusEventAnimationInteractor +@Inject +constructor( + repo: SystemStatusEventAnimationRepository, + configurationInteractor: ConfigurationInteractor, + @Application scope: CoroutineScope, +) { + private val chipAnimateInTranslationX = + configurationInteractor + .dimensionPixelSize(R.dimen.ongoing_appops_chip_animation_in_status_bar_translation_x) + .stateIn(scope, SharingStarted.Eagerly, 0) + + private val chipAnimateOutTranslationX = + configurationInteractor + .dimensionPixelSize(R.dimen.ongoing_appops_chip_animation_out_status_bar_translation_x) + .stateIn(scope, SharingStarted.Eagerly, 0) + + val animationState = repo.animationState + + private fun getDefaultStatusBarAnimationForChipEnter( + setX: (Float) -> Unit, + setAlpha: (Float) -> Unit, + ): Animator { + return StatusBarSystemEventDefaultAnimator.getDefaultStatusBarAnimationForChipEnter( + chipAnimateInTranslationX.value, + setX, + setAlpha, + ) + } + + private fun getDefaultStatusBarAnimationForChipExit( + setX: (Float) -> Unit, + setAlpha: (Float) -> Unit, + ): Animator { + return StatusBarSystemEventDefaultAnimator.getDefaultStatusBarAnimationForChipExit( + chipAnimateOutTranslationX.value, + setX, + setAlpha, + ) + } + + fun animateStatusBarContentForChipEnter(v: View) { + getDefaultStatusBarAnimationForChipEnter(setX = v::setTranslationX, setAlpha = v::setAlpha) + .start() + } + + fun animateStatusBarContentForChipExit(v: View) { + v.translationX = chipAnimateOutTranslationX.value.toFloat() + getDefaultStatusBarAnimationForChipExit(setX = v::setTranslationX, setAlpha = v::setAlpha) + .start() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeadsUpManagerPhone.java deleted file mode 100644 index 0299ebcdf043..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeadsUpManagerPhone.java +++ /dev/null @@ -1,772 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.notification; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Region; -import android.os.Handler; -import android.util.ArrayMap; -import android.util.Pools; - -import androidx.collection.ArraySet; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.logging.UiEventLogger; -import com.android.internal.policy.SystemBarUtils; -import com.android.systemui.dagger.SysUISingleton; -import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; -import com.android.systemui.res.R; -import com.android.systemui.scene.shared.flag.SceneContainerFlag; -import com.android.systemui.shade.domain.interactor.ShadeInteractor; -import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener; -import com.android.systemui.statusbar.notification.collection.provider.OnReorderingBannedListener; -import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; -import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; -import com.android.systemui.statusbar.notification.data.repository.HeadsUpRepository; -import com.android.systemui.statusbar.notification.data.repository.HeadsUpRowRepository; -import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; -import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun; -import com.android.systemui.statusbar.phone.ExpandHeadsUpOnInlineReply; -import com.android.systemui.statusbar.phone.KeyguardBypassController; -import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; -import com.android.systemui.statusbar.policy.AnimationStateHandler; -import com.android.systemui.statusbar.policy.AvalancheController; -import com.android.systemui.statusbar.policy.BaseHeadsUpManager; -import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.HeadsUpManagerLogger; -import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; -import com.android.systemui.statusbar.policy.OnHeadsUpPhoneListenerChange; -import com.android.systemui.util.concurrency.DelayableExecutor; -import com.android.systemui.util.kotlin.JavaAdapter; -import com.android.systemui.util.settings.GlobalSettings; -import com.android.systemui.util.time.SystemClock; - -import kotlinx.coroutines.flow.Flow; -import kotlinx.coroutines.flow.MutableStateFlow; -import kotlinx.coroutines.flow.StateFlow; -import kotlinx.coroutines.flow.StateFlowKt; - -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.Stack; - -import javax.inject.Inject; - -/** A implementation of HeadsUpManager for phone. */ -@SysUISingleton -public class HeadsUpManagerPhone extends BaseHeadsUpManager implements - HeadsUpRepository, OnHeadsUpChangedListener { - private static final String TAG = "HeadsUpManagerPhone"; - - @VisibleForTesting - public final int mExtensionTime; - private final KeyguardBypassController mBypassController; - private final GroupMembershipManager mGroupMembershipManager; - private final List<OnHeadsUpPhoneListenerChange> mHeadsUpPhoneListeners = new ArrayList<>(); - private final VisualStabilityProvider mVisualStabilityProvider; - - private AvalancheController mAvalancheController; - - // TODO(b/328393698) move the topHeadsUpRow logic to an interactor - private final MutableStateFlow<HeadsUpRowRepository> mTopHeadsUpRow = - StateFlowKt.MutableStateFlow(null); - private final MutableStateFlow<Set<HeadsUpRowRepository>> mHeadsUpNotificationRows = - StateFlowKt.MutableStateFlow(new HashSet<>()); - private final MutableStateFlow<Boolean> mHeadsUpAnimatingAway = - StateFlowKt.MutableStateFlow(false); - private boolean mReleaseOnExpandFinish; - private boolean mTrackingHeadsUp; - private final HashSet<String> mSwipedOutKeys = new HashSet<>(); - private final HashSet<NotificationEntry> mEntriesToRemoveAfterExpand = new HashSet<>(); - @VisibleForTesting - public final ArraySet<NotificationEntry> mEntriesToRemoveWhenReorderingAllowed - = new ArraySet<>(); - private boolean mIsShadeOrQsExpanded; - private boolean mIsQsExpanded; - private int mStatusBarState; - private AnimationStateHandler mAnimationStateHandler; - - private int mHeadsUpInset; - - // Used for determining the region for touch interaction - private final Region mTouchableRegion = new Region(); - - private final Pools.Pool<HeadsUpEntryPhone> mEntryPool = new Pools.Pool<HeadsUpEntryPhone>() { - private Stack<HeadsUpEntryPhone> mPoolObjects = new Stack<>(); - - @Override - public HeadsUpEntryPhone acquire() { - NotificationThrottleHun.assertInLegacyMode(); - if (!mPoolObjects.isEmpty()) { - return mPoolObjects.pop(); - } - return new HeadsUpEntryPhone(); - } - - @Override - public boolean release(@NonNull HeadsUpEntryPhone instance) { - NotificationThrottleHun.assertInLegacyMode(); - mPoolObjects.push(instance); - return true; - } - }; - - /////////////////////////////////////////////////////////////////////////////////////////////// - // Constructor: - @Inject - public HeadsUpManagerPhone( - @NonNull final Context context, - HeadsUpManagerLogger logger, - StatusBarStateController statusBarStateController, - KeyguardBypassController bypassController, - GroupMembershipManager groupMembershipManager, - VisualStabilityProvider visualStabilityProvider, - ConfigurationController configurationController, - @Main Handler handler, - GlobalSettings globalSettings, - SystemClock systemClock, - @Main DelayableExecutor executor, - AccessibilityManagerWrapper accessibilityManagerWrapper, - UiEventLogger uiEventLogger, - JavaAdapter javaAdapter, - ShadeInteractor shadeInteractor, - AvalancheController avalancheController) { - super(context, logger, handler, globalSettings, systemClock, executor, - accessibilityManagerWrapper, uiEventLogger, avalancheController); - Resources resources = mContext.getResources(); - mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time); - statusBarStateController.addCallback(mStatusBarStateListener); - mBypassController = bypassController; - mGroupMembershipManager = groupMembershipManager; - mVisualStabilityProvider = visualStabilityProvider; - mAvalancheController = avalancheController; - updateResources(); - configurationController.addCallback(new ConfigurationController.ConfigurationListener() { - @Override - public void onDensityOrFontScaleChanged() { - updateResources(); - } - - @Override - public void onThemeChanged() { - updateResources(); - } - }); - javaAdapter.alwaysCollectFlow(shadeInteractor.isAnyExpanded(), - this::onShadeOrQsExpanded); - if (SceneContainerFlag.isEnabled()) { - javaAdapter.alwaysCollectFlow(shadeInteractor.isQsExpanded(), - this::onQsExpanded); - } - if (NotificationThrottleHun.isEnabled()) { - mVisualStabilityProvider.addPersistentReorderingBannedListener( - mOnReorderingBannedListener); - mVisualStabilityProvider.addPersistentReorderingAllowedListener( - mOnReorderingAllowedListener); - } - } - - public void setAnimationStateHandler(AnimationStateHandler handler) { - mAnimationStateHandler = handler; - } - - private void updateResources() { - Resources resources = mContext.getResources(); - mHeadsUpInset = SystemBarUtils.getStatusBarHeight(mContext) - + resources.getDimensionPixelSize(R.dimen.heads_up_status_bar_padding); - } - - /////////////////////////////////////////////////////////////////////////////////////////////// - // Public methods: - - /** - * Add a listener to receive callbacks {@link #setHeadsUpAnimatingAway(boolean)} - */ - @Override - public void addHeadsUpPhoneListener(OnHeadsUpPhoneListenerChange listener) { - mHeadsUpPhoneListeners.add(listener); - } - - /** - * Gets the touchable region needed for heads up notifications. Returns null if no touchable - * region is required (ie: no heads up notification currently exists). - */ - // TODO(b/347007367): With scene container enabled this method may report outdated regions - @Override - public @Nullable Region getTouchableRegion() { - NotificationEntry topEntry = getTopEntry(); - - // This call could be made in an inconsistent state while the pinnedMode hasn't been - // updated yet, but callbacks leading out of the headsUp manager, querying it. Let's - // therefore also check if the topEntry is null. - if (!hasPinnedHeadsUp() || topEntry == null) { - return null; - } else { - if (topEntry.rowIsChildInGroup()) { - final NotificationEntry groupSummary = - mGroupMembershipManager.getGroupSummary(topEntry); - if (groupSummary != null) { - topEntry = groupSummary; - } - } - ExpandableNotificationRow topRow = topEntry.getRow(); - int[] tmpArray = new int[2]; - topRow.getLocationOnScreen(tmpArray); - int minX = tmpArray[0]; - int maxX = tmpArray[0] + topRow.getWidth(); - int height = topRow.getIntrinsicHeight(); - final boolean stretchToTop = tmpArray[1] <= mHeadsUpInset; - mTouchableRegion.set(minX, stretchToTop ? 0 : tmpArray[1], maxX, tmpArray[1] + height); - return mTouchableRegion; - } - } - - /** - * Decides whether a click is invalid for a notification, i.e it has not been shown long enough - * that a user might have consciously clicked on it. - * - * @param key the key of the touched notification - * @return whether the touch is invalid and should be discarded - */ - @Override - public boolean shouldSwallowClick(@NonNull String key) { - BaseHeadsUpManager.HeadsUpEntry entry = getHeadsUpEntry(key); - return entry != null && mSystemClock.elapsedRealtime() < entry.mPostTime; - } - - @Override - public void releaseAfterExpansion() { - if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return; - onExpandingFinished(); - } - - public void onExpandingFinished() { - if (mReleaseOnExpandFinish) { - releaseAllImmediately(); - mReleaseOnExpandFinish = false; - } else { - for (NotificationEntry entry: getAllEntries().toList()) { - entry.setSeenInShade(true); - } - for (NotificationEntry entry : mEntriesToRemoveAfterExpand) { - if (isHeadsUpEntry(entry.getKey())) { - // Maybe the heads-up was removed already - removeEntry(entry.getKey(), "onExpandingFinished"); - } - } - } - mEntriesToRemoveAfterExpand.clear(); - } - - /** - * Sets the tracking-heads-up flag. If the flag is true, HeadsUpManager doesn't remove the entry - * from the list even after a Heads Up Notification is gone. - */ - public void setTrackingHeadsUp(boolean trackingHeadsUp) { - mTrackingHeadsUp = trackingHeadsUp; - } - - private void onShadeOrQsExpanded(Boolean isExpanded) { - if (isExpanded != mIsShadeOrQsExpanded) { - mIsShadeOrQsExpanded = isExpanded; - if (!SceneContainerFlag.isEnabled() && isExpanded) { - mHeadsUpAnimatingAway.setValue(false); - } - } - } - - private void onQsExpanded(Boolean isQsExpanded) { - if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return; - if (isQsExpanded != mIsQsExpanded) mIsQsExpanded = isQsExpanded; - } - - /** - * Set that we are exiting the headsUp pinned mode, but some notifications might still be - * animating out. This is used to keep the touchable regions in a reasonable state. - */ - @Override - public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) { - if (headsUpAnimatingAway != mHeadsUpAnimatingAway.getValue()) { - for (OnHeadsUpPhoneListenerChange listener : mHeadsUpPhoneListeners) { - listener.onHeadsUpAnimatingAwayStateChanged(headsUpAnimatingAway); - } - mHeadsUpAnimatingAway.setValue(headsUpAnimatingAway); - } - } - - @Override - public void unpinAll(boolean userUnPinned) { - super.unpinAll(userUnPinned); - } - - /** - * Notifies that a remote input textbox in notification gets active or inactive. - * - * @param entry The entry of the target notification. - * @param remoteInputActive True to notify active, False to notify inactive. - */ - public void setRemoteInputActive( - @NonNull NotificationEntry entry, boolean remoteInputActive) { - HeadsUpEntryPhone headsUpEntry = getHeadsUpEntryPhone(entry.getKey()); - if (headsUpEntry != null && headsUpEntry.mRemoteInputActive != remoteInputActive) { - headsUpEntry.mRemoteInputActive = remoteInputActive; - if (ExpandHeadsUpOnInlineReply.isEnabled() && remoteInputActive) { - headsUpEntry.mRemoteInputActivatedAtLeastOnce = true; - } - if (remoteInputActive) { - headsUpEntry.cancelAutoRemovalCallbacks("setRemoteInputActive(true)"); - } else { - headsUpEntry.updateEntry(false /* updatePostTime */, "setRemoteInputActive(false)"); - } - onEntryUpdated(headsUpEntry); - } - } - - /** - * Sets whether an entry's guts are exposed and therefore it should stick in the heads up - * area if it's pinned until it's hidden again. - */ - public void setGutsShown(@NonNull NotificationEntry entry, boolean gutsShown) { - HeadsUpEntry headsUpEntry = getHeadsUpEntry(entry.getKey()); - if (!(headsUpEntry instanceof HeadsUpEntryPhone)) return; - HeadsUpEntryPhone headsUpEntryPhone = (HeadsUpEntryPhone)headsUpEntry; - if (entry.isRowPinned() || !gutsShown) { - headsUpEntryPhone.setGutsShownPinned(gutsShown); - } - } - - /** - * Extends the lifetime of the currently showing pulsing notification so that the pulse lasts - * longer. - */ - public void extendHeadsUp() { - HeadsUpEntryPhone topEntry = getTopHeadsUpEntryPhone(); - if (topEntry == null) { - return; - } - topEntry.extendPulse(); - } - - /////////////////////////////////////////////////////////////////////////////////////////////// - // HeadsUpManager public methods overrides and overloads: - - @Override - public boolean isTrackingHeadsUp() { - return mTrackingHeadsUp; - } - - @Override - public void snooze() { - super.snooze(); - mReleaseOnExpandFinish = true; - } - - public void addSwipedOutNotification(@NonNull String key) { - mSwipedOutKeys.add(key); - } - - @Override - public boolean removeNotification(@NonNull String key, boolean releaseImmediately, - boolean animate, @NonNull String reason) { - if (animate) { - return removeNotification(key, releaseImmediately, - "removeNotification(animate: true), reason: " + reason); - } else { - mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(false); - final boolean removed = removeNotification(key, releaseImmediately, - "removeNotification(animate: false), reason: " + reason); - mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(true); - return removed; - } - } - - /////////////////////////////////////////////////////////////////////////////////////////////// - // Dumpable overrides: - - @Override - public void dump(PrintWriter pw, String[] args) { - pw.println("HeadsUpManagerPhone state:"); - dumpInternal(pw, args); - } - - /////////////////////////////////////////////////////////////////////////////////////////////// - // OnReorderingAllowedListener: - - private final OnReorderingAllowedListener mOnReorderingAllowedListener = () -> { - if (NotificationThrottleHun.isEnabled()) { - mAvalancheController.setEnableAtRuntime(true); - if (mEntriesToRemoveWhenReorderingAllowed.isEmpty()) { - return; - } - } - mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(false); - for (NotificationEntry entry : mEntriesToRemoveWhenReorderingAllowed) { - if (entry != null && isHeadsUpEntry(entry.getKey())) { - // Maybe the heads-up was removed already - removeEntry(entry.getKey(), "mOnReorderingAllowedListener"); - } - } - mEntriesToRemoveWhenReorderingAllowed.clear(); - mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(true); - }; - - private final OnReorderingBannedListener mOnReorderingBannedListener = () -> { - if (mAvalancheController != null) { - // In open shade the first HUN is pinned, and visual stability logic prevents us from - // unpinning this first HUN as long as the shade remains open. AvalancheController only - // shows the next HUN when the currently showing HUN is unpinned, so we must disable - // throttling here so that the incoming HUN stream is not forever paused. This is reset - // when reorder becomes allowed. - mAvalancheController.setEnableAtRuntime(false); - - // Note that we cannot do the above when - // 1) The remove runnable runs because its delay means it may not run before shade close - // 2) Reordering is allowed again (when shade closes) because the HUN appear animation - // will have started by then - } - }; - - /////////////////////////////////////////////////////////////////////////////////////////////// - // HeadsUpManager utility (protected) methods overrides: - - @NonNull - @Override - protected HeadsUpEntry createHeadsUpEntry(NotificationEntry entry) { - if (NotificationThrottleHun.isEnabled()) { - return new HeadsUpEntryPhone(entry); - } else { - HeadsUpEntryPhone headsUpEntry = mEntryPool.acquire(); - headsUpEntry.setEntry(entry); - return headsUpEntry; - } - } - - @Override - protected void onEntryAdded(HeadsUpEntry headsUpEntry) { - super.onEntryAdded(headsUpEntry); - updateTopHeadsUpFlow(); - updateHeadsUpFlow(); - } - - @Override - protected void onEntryUpdated(HeadsUpEntry headsUpEntry) { - super.onEntryUpdated(headsUpEntry); - // no need to update the list here - updateTopHeadsUpFlow(); - } - - @Override - protected void onEntryRemoved(HeadsUpEntry headsUpEntry) { - super.onEntryRemoved(headsUpEntry); - if (!NotificationThrottleHun.isEnabled()) { - mEntryPool.release((HeadsUpEntryPhone) headsUpEntry); - } - updateTopHeadsUpFlow(); - updateHeadsUpFlow(); - if (NotificationThrottleHun.isEnabled()) { - if (headsUpEntry.mEntry != null) { - if (mEntriesToRemoveWhenReorderingAllowed.contains(headsUpEntry.mEntry)) { - mEntriesToRemoveWhenReorderingAllowed.remove(headsUpEntry.mEntry); - } - } - } - } - - private void updateTopHeadsUpFlow() { - mTopHeadsUpRow.setValue((HeadsUpRowRepository) getTopHeadsUpEntry()); - } - - private void updateHeadsUpFlow() { - mHeadsUpNotificationRows.setValue(new HashSet<>(getHeadsUpEntryPhoneMap().values())); - } - - @Override - protected boolean shouldHeadsUpBecomePinned(NotificationEntry entry) { - boolean pin = mStatusBarState == StatusBarState.SHADE && !mIsShadeOrQsExpanded; - if (SceneContainerFlag.isEnabled()) { - pin |= mIsQsExpanded; - } - if (mBypassController.getBypassEnabled()) { - pin |= mStatusBarState == StatusBarState.KEYGUARD; - } - return pin || super.shouldHeadsUpBecomePinned(entry); - } - - @Override - protected void dumpInternal(PrintWriter pw, String[] args) { - super.dumpInternal(pw, args); - pw.print(" mBarState="); - pw.println(mStatusBarState); - pw.print(" mTouchableRegion="); - pw.println(mTouchableRegion); - } - - /////////////////////////////////////////////////////////////////////////////////////////////// - // Private utility methods: - - @NonNull - private ArrayMap<String, HeadsUpEntryPhone> getHeadsUpEntryPhoneMap() { - //noinspection unchecked - return (ArrayMap<String, HeadsUpEntryPhone>) ((ArrayMap) mHeadsUpEntryMap); - } - - @Nullable - private HeadsUpEntryPhone getHeadsUpEntryPhone(@NonNull String key) { - return (HeadsUpEntryPhone) mHeadsUpEntryMap.get(key); - } - - @Nullable - private HeadsUpEntryPhone getTopHeadsUpEntryPhone() { - if (SceneContainerFlag.isEnabled()) { - return (HeadsUpEntryPhone) mTopHeadsUpRow.getValue(); - } else { - return (HeadsUpEntryPhone) getTopHeadsUpEntry(); - } - } - - @Override - public boolean canRemoveImmediately(@NonNull String key) { - if (mSwipedOutKeys.contains(key)) { - // We always instantly dismiss views being manually swiped out. - mSwipedOutKeys.remove(key); - return true; - } - - HeadsUpEntryPhone headsUpEntry = getHeadsUpEntryPhone(key); - HeadsUpEntryPhone topEntry = getTopHeadsUpEntryPhone(); - - return headsUpEntry == null || headsUpEntry != topEntry || super.canRemoveImmediately(key); - } - - @Override - @NonNull - public Flow<HeadsUpRowRepository> getTopHeadsUpRow() { - return mTopHeadsUpRow; - } - - @Override - @NonNull - public Flow<Set<HeadsUpRowRepository>> getActiveHeadsUpRows() { - return mHeadsUpNotificationRows; - } - - @Override - @NonNull - public StateFlow<Boolean> isHeadsUpAnimatingAway() { - return mHeadsUpAnimatingAway; - } - - @Override - public boolean isHeadsUpAnimatingAwayValue() { - return mHeadsUpAnimatingAway.getValue(); - } - - /////////////////////////////////////////////////////////////////////////////////////////////// - // HeadsUpEntryPhone: - - protected class HeadsUpEntryPhone extends BaseHeadsUpManager.HeadsUpEntry implements - HeadsUpRowRepository { - - private boolean mGutsShownPinned; - private final MutableStateFlow<Boolean> mIsPinned = StateFlowKt.MutableStateFlow(false); - - /** - * If the time this entry has been on was extended - */ - private boolean extended; - - @Override - public boolean isSticky() { - return super.isSticky() || mGutsShownPinned; - } - - public HeadsUpEntryPhone() { - super(); - } - - public HeadsUpEntryPhone(NotificationEntry entry) { - super(entry); - } - - @Override - @NonNull - public String getKey() { - return requireEntry().getKey(); - } - - @Override - @NonNull - public StateFlow<Boolean> isPinned() { - return mIsPinned; - } - - @Override - protected void setRowPinned(boolean pinned) { - // TODO(b/327624082): replace this super call with a ViewBinder - super.setRowPinned(pinned); - mIsPinned.setValue(pinned); - } - - @Override - protected void setEntry(@androidx.annotation.NonNull NotificationEntry entry, - @androidx.annotation.Nullable Runnable removeRunnable) { - super.setEntry(entry, removeRunnable); - - if (NotificationThrottleHun.isEnabled()) { - mEntriesToRemoveWhenReorderingAllowed.add(entry); - if (!mVisualStabilityProvider.isReorderingAllowed()) { - entry.setSeenInShade(true); - } - } - } - - @Override - protected Runnable createRemoveRunnable(NotificationEntry entry) { - return () -> { - if (!NotificationThrottleHun.isEnabled() - && !mVisualStabilityProvider.isReorderingAllowed() - // We don't want to allow reordering while pulsing, but headsup need to - // time out anyway - && !entry.showingPulsing()) { - mEntriesToRemoveWhenReorderingAllowed.add(entry); - mVisualStabilityProvider.addTemporaryReorderingAllowedListener( - mOnReorderingAllowedListener); - } else if (mTrackingHeadsUp) { - mEntriesToRemoveAfterExpand.add(entry); - mLogger.logRemoveEntryAfterExpand(entry); - } else if (mVisualStabilityProvider.isReorderingAllowed() - || entry.showingPulsing()) { - removeEntry(entry.getKey(), "createRemoveRunnable"); - } - }; - } - - @Override - public void updateEntry(boolean updatePostTime, String reason) { - super.updateEntry(updatePostTime, reason); - - if (mEntriesToRemoveAfterExpand.contains(mEntry)) { - mEntriesToRemoveAfterExpand.remove(mEntry); - } - if (!NotificationThrottleHun.isEnabled()) { - if (mEntriesToRemoveWhenReorderingAllowed.contains(mEntry)) { - mEntriesToRemoveWhenReorderingAllowed.remove(mEntry); - } - } - } - - @Override - public void setExpanded(boolean expanded) { - if (this.mExpanded == expanded) { - return; - } - - this.mExpanded = expanded; - if (expanded) { - cancelAutoRemovalCallbacks("setExpanded(true)"); - } else { - updateEntry(false /* updatePostTime */, "setExpanded(false)"); - } - } - - public void setGutsShownPinned(boolean gutsShownPinned) { - if (mGutsShownPinned == gutsShownPinned) { - return; - } - - mGutsShownPinned = gutsShownPinned; - if (gutsShownPinned) { - cancelAutoRemovalCallbacks("setGutsShownPinned(true)"); - } else { - updateEntry(false /* updatePostTime */, "setGutsShownPinned(false)"); - } - } - - @Override - public void reset() { - super.reset(); - mGutsShownPinned = false; - extended = false; - } - - private void extendPulse() { - if (!extended) { - extended = true; - updateEntry(false, "extendPulse()"); - } - } - - @Override - protected long calculateFinishTime() { - return super.calculateFinishTime() + (extended ? mExtensionTime : 0); - } - - @Override - @NonNull - public Object getElementKey() { - return requireEntry().getRow(); - } - - private NotificationEntry requireEntry() { - /* check if */ SceneContainerFlag.isUnexpectedlyInLegacyMode(); - return Objects.requireNonNull(mEntry); - } - } - - private final StateListener mStatusBarStateListener = new StateListener() { - @Override - public void onStateChanged(int newState) { - boolean wasKeyguard = mStatusBarState == StatusBarState.KEYGUARD; - boolean isKeyguard = newState == StatusBarState.KEYGUARD; - mStatusBarState = newState; - - if (wasKeyguard && !isKeyguard && mBypassController.getBypassEnabled()) { - ArrayList<String> keysToRemove = new ArrayList<>(); - for (HeadsUpEntry entry : getHeadsUpEntryList()) { - if (entry.mEntry != null && entry.mEntry.isBubble() && !entry.isSticky()) { - keysToRemove.add(entry.mEntry.getKey()); - } - } - for (String key : keysToRemove) { - removeEntry(key, "mStatusBarStateListener"); - } - } - } - - @Override - public void onDozingChanged(boolean isDozing) { - if (!isDozing) { - // Let's make sure all huns we got while dozing time out within the normal timeout - // duration. Otherwise they could get stuck for a very long time - for (HeadsUpEntry entry : getHeadsUpEntryList()) { - entry.updateEntry(true /* updatePostTime */, "onDozingChanged(false)"); - } - } - } - }; -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java index e74ed8d27ec2..c487ff5d35bd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java @@ -49,6 +49,7 @@ import android.os.SystemClock; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.SnoozeCriterion; import android.service.notification.StatusBarNotification; +import android.util.Log; import android.view.ContentInfo; import androidx.annotation.NonNull; @@ -65,6 +66,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.No import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.notification.icon.IconPack; +import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController; import com.android.systemui.statusbar.notification.row.NotificationGuts; @@ -194,6 +196,10 @@ public final class NotificationEntry extends ListEntry { */ private boolean mIsDemoted = false; + // TODO(b/377565433): Move into NotificationContentModel during/after + // NotificationRowContentBinderRefactor. + private PromotedNotificationContentModel mPromotedNotificationContentModel; + /** * True if both * 1) app provided full screen intent but does not have the permission to send it @@ -1061,6 +1067,32 @@ public final class NotificationEntry extends ListEntry { this.mHeadsUpStatusBarTextPublic.setValue(headsUpStatusBarModel.getPublicText()); } + /** + * Gets the content needed to render this notification as a promoted notification on various + * surfaces (like status bar chips and AOD). + */ + public PromotedNotificationContentModel getPromotedNotificationContentModel() { + if (PromotedNotificationContentModel.featureFlagEnabled()) { + return mPromotedNotificationContentModel; + } else { + Log.wtf(TAG, "getting promoted content without feature flag enabled"); + return null; + } + } + + /** + * Sets the content needed to render this notification as a promoted notification on various + * surfaces (like status bar chips and AOD). + */ + public void setPromotedNotificationContentModel( + @Nullable PromotedNotificationContentModel promotedNotificationContentModel) { + if (PromotedNotificationContentModel.featureFlagEnabled()) { + this.mPromotedNotificationContentModel = promotedNotificationContentModel; + } else { + Log.wtf(TAG, "setting promoted content without feature flag enabled"); + } + } + /** Information about a suggestion that is being edited. */ public static class EditedSuggestionInfo { @@ -1101,4 +1133,6 @@ public final class NotificationEntry extends ListEntry { private static final long INITIALIZATION_DELAY = 400; private static final long NOT_LAUNCHED_YET = -LAUNCH_COOLDOWN; private static final int COLOR_INVALID = 1; + + private static final String TAG = "NotificationEntry"; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt index dc8ff63865a2..90212ed5b5f7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt @@ -27,13 +27,13 @@ import com.android.systemui.statusbar.notification.collection.render.requireSumm import javax.inject.Inject /** - * A small coordinator which updates the notif stack (the view layer which holds notifications) - * with high-level data after the stack is populated with the final entries. + * A small coordinator which updates the notif stack (the view layer which holds notifications) with + * high-level data after the stack is populated with the final entries. */ @CoordinatorScope -class DataStoreCoordinator @Inject internal constructor( - private val notifLiveDataStoreImpl: NotifLiveDataStoreImpl -) : CoreCoordinator { +class DataStoreCoordinator +@Inject +internal constructor(private val notifLiveDataStoreImpl: NotifLiveDataStoreImpl) : CoreCoordinator { override fun attach(pipeline: NotifPipeline) { pipeline.addOnAfterRenderListListener { entries, _ -> onAfterRenderList(entries) } @@ -61,4 +61,4 @@ class DataStoreCoordinator @Inject internal constructor( } } } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt index e9292f8c3cb8..32de65be5b5b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt @@ -43,8 +43,7 @@ internal constructor( private val groupExpansionManagerImpl: GroupExpansionManagerImpl, private val renderListInteractor: RenderNotificationListInteractor, private val activeNotificationsInteractor: ActiveNotificationsInteractor, - private val sensitiveNotificationProtectionController: - SensitiveNotificationProtectionController, + private val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController, ) : Coordinator { override fun attach(pipeline: NotifPipeline) { @@ -52,7 +51,7 @@ internal constructor( groupExpansionManagerImpl.attach(pipeline) } - fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) = + private fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) = traceSection("StackCoordinator.onAfterRenderList") { val notifStats = calculateNotifStats(entries) if (FooterViewRefactor.isEnabled) { @@ -78,13 +77,13 @@ internal constructor( val isSilent = section.bucket == BUCKET_SILENT // NOTE: NotificationEntry.isClearable will internally check group children to ensure // the group itself definitively clearable. - val isClearable = !isSensitiveContentProtectionActive && entry.isClearable - && !entry.isSensitive.value + val isClearable = + !isSensitiveContentProtectionActive && entry.isClearable && !entry.isSensitive.value when { isSilent && isClearable -> hasClearableSilentNotifs = true isSilent && !isClearable -> hasNonClearableSilentNotifs = true !isSilent && isClearable -> hasClearableAlertingNotifs = true - !isSilent && !isClearable -> hasNonClearableAlertingNotifs = true + else -> hasNonClearableAlertingNotifs = true } } return NotifStats( @@ -92,7 +91,7 @@ internal constructor( hasNonClearableAlertingNotifs = hasNonClearableAlertingNotifs, hasClearableAlertingNotifs = hasClearableAlertingNotifs, hasNonClearableSilentNotifs = hasNonClearableSilentNotifs, - hasClearableSilentNotifs = hasClearableSilentNotifs + hasClearableSilentNotifs = hasClearableSilentNotifs, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewRenderer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewRenderer.kt index 1ea574b2f386..410b78b9d3bf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewRenderer.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewRenderer.kt @@ -21,15 +21,15 @@ import com.android.systemui.statusbar.notification.collection.ListEntry import com.android.systemui.statusbar.notification.collection.NotificationEntry /** - * This interface and the interfaces it returns define the main API surface that must be - * implemented by the view implementation. The term "render" is used to indicate a handoff - * to the view system, whether that be to attach views to the hierarchy or to update independent - * view models, data stores, or adapters. + * This interface and the interfaces it returns define the main API surface that must be implemented + * by the view implementation. The term "render" is used to indicate a handoff to the view system, + * whether that be to attach views to the hierarchy or to update independent view models, data + * stores, or adapters. */ interface NotifViewRenderer { /** - * Hand off the list of notifications to the view implementation. This may attach views to the + * Hand off the list of notifications to the view implementation. This may attach views to the * hierarchy or simply update an independent datastore, but once called, the implementer myst * also ensure that future calls to [getStackController], [getGroupController], and * [getRowController] will provide valid results. @@ -37,21 +37,21 @@ interface NotifViewRenderer { fun onRenderList(notifList: List<ListEntry>) /** - * Provides an interface for the pipeline to update the overall shade. - * This will be called at most once for each time [onRenderList] is called. + * Provides an interface for the pipeline to update the overall shade. This will be called at + * most once for each time [onRenderList] is called. */ fun getStackController(): NotifStackController /** - * Provides an interface for the pipeline to update individual groups. - * This will be called at most once for each group in the most recent call to [onRenderList]. + * Provides an interface for the pipeline to update individual groups. This will be called at + * most once for each group in the most recent call to [onRenderList]. */ fun getGroupController(group: GroupEntry): NotifGroupController /** - * Provides an interface for the pipeline to update individual entries. - * This will be called at most once for each entry in the most recent call to [onRenderList]. - * This includes top level entries, group summaries, and group children. + * Provides an interface for the pipeline to update individual entries. This will be called at + * most once for each entry in the most recent call to [onRenderList]. This includes top level + * entries, group summaries, and group children. */ fun getRowController(entry: NotificationEntry): NotifRowController @@ -62,8 +62,8 @@ interface NotifViewRenderer { * logic now that all data from the pipeline is known to have been set for this execution. * * When this is called, the view system can expect that no more calls will be made to the - * getters on this interface until after the next call to [onRenderList]. Additionally, there + * getters on this interface until after the next call to [onRenderList]. Additionally, there * should be no further calls made on the objects previously returned by those getters. */ fun onDispatchComplete() {} -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManager.kt index 9b5521018f97..9d3b098fa966 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManager.kt @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.notification.collection.render +import com.android.app.tracing.traceSection import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.ListEntry @@ -26,7 +27,6 @@ import com.android.systemui.statusbar.notification.collection.ShadeListBuilder import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderGroupListener import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener -import com.android.app.tracing.traceSection import javax.inject.Inject /** @@ -77,16 +77,17 @@ class RenderStageManager @Inject constructor() : PipelineDumpable { onAfterRenderEntryListeners.add(listener) } - override fun dumpPipeline(d: PipelineDumper) = with(d) { - dump("viewRenderer", viewRenderer) - dump("onAfterRenderListListeners", onAfterRenderListListeners) - dump("onAfterRenderGroupListeners", onAfterRenderGroupListeners) - dump("onAfterRenderEntryListeners", onAfterRenderEntryListeners) - } + override fun dumpPipeline(d: PipelineDumper) = + with(d) { + dump("viewRenderer", viewRenderer) + dump("onAfterRenderListListeners", onAfterRenderListListeners) + dump("onAfterRenderGroupListeners", onAfterRenderGroupListeners) + dump("onAfterRenderEntryListeners", onAfterRenderEntryListeners) + } private fun dispatchOnAfterRenderList( viewRenderer: NotifViewRenderer, - entries: List<ListEntry> + entries: List<ListEntry>, ) { traceSection("RenderStageManager.dispatchOnAfterRenderList") { val stackController = viewRenderer.getStackController() @@ -98,7 +99,7 @@ class RenderStageManager @Inject constructor() : PipelineDumpable { private fun dispatchOnAfterRenderGroups( viewRenderer: NotifViewRenderer, - entries: List<ListEntry> + entries: List<ListEntry>, ) { traceSection("RenderStageManager.dispatchOnAfterRenderGroups") { if (onAfterRenderGroupListeners.isEmpty()) { @@ -115,7 +116,7 @@ class RenderStageManager @Inject constructor() : PipelineDumpable { private fun dispatchOnAfterRenderEntries( viewRenderer: NotifViewRenderer, - entries: List<ListEntry> + entries: List<ListEntry>, ) { traceSection("RenderStageManager.dispatchOnAfterRenderEntries") { if (onAfterRenderEntryListeners.isEmpty()) { @@ -131,8 +132,8 @@ class RenderStageManager @Inject constructor() : PipelineDumpable { } /** - * Performs a forward, depth-first traversal of the list where the group's summary - * immediately precedes the group's children. + * Performs a forward, depth-first traversal of the list where the group's summary immediately + * precedes the group's children. */ private inline fun List<ListEntry>.forEachNotificationEntry( action: (NotificationEntry) -> Unit diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt index 63c9e8be9ead..cf4fb25f638e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/NotificationDataLayerModule.kt @@ -16,16 +16,11 @@ package com.android.systemui.statusbar.notification.data import com.android.systemui.statusbar.notification.data.repository.HeadsUpRepository -import com.android.systemui.statusbar.notification.HeadsUpManagerPhone +import com.android.systemui.statusbar.policy.BaseHeadsUpManager import dagger.Binds import dagger.Module -@Module( - includes = - [ - NotificationSettingsRepositoryModule::class, - ] -) +@Module(includes = [NotificationSettingsRepositoryModule::class]) interface NotificationDataLayerModule { - @Binds fun bindHeadsUpNotificationRepository(impl: HeadsUpManagerPhone): HeadsUpRepository + @Binds fun bindHeadsUpNotificationRepository(impl: BaseHeadsUpManager): HeadsUpRepository } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/ActiveNotificationListRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/ActiveNotificationListRepository.kt index 45d1034f2cfb..2b9e49372a63 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/ActiveNotificationListRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/ActiveNotificationListRepository.kt @@ -66,7 +66,7 @@ data class ActiveNotificationsStore( * Map of notification key to rank, where rank is the 0-based index of the notification on the * system server, meaning that in the unfiltered flattened list of notification entries. */ - val rankingsMap: Map<String, Int> = emptyMap() + val rankingsMap: Map<String, Int> = emptyMap(), ) { operator fun get(key: Key): ActiveNotificationEntryModel? { return when (key) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt index 23da90d426c7..8edbc5e8e4bb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationListInteractor.kt @@ -34,6 +34,7 @@ import com.android.systemui.statusbar.notification.collection.provider.SectionSt import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore import com.android.systemui.statusbar.notification.promoted.PromotedNotificationsProvider +import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationEntryModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationGroupModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel @@ -173,6 +174,7 @@ private class ActiveNotificationsStoreBuilder( isGroupSummary = sbn.notification.isGroupSummary, bucket = bucket, callType = sbn.toCallType(), + promotedContent = promotedNotificationContentModel, ) } } @@ -199,6 +201,7 @@ private fun ActiveNotificationsStore.createOrReuse( isGroupSummary: Boolean, bucket: Int, callType: CallType, + promotedContent: PromotedNotificationContentModel?, ): ActiveNotificationModel { return individuals[key]?.takeIf { it.isCurrent( @@ -223,6 +226,7 @@ private fun ActiveNotificationsStore.createOrReuse( contentIntent = contentIntent, bucket = bucket, callType = callType, + promotedContent = promotedContent, ) } ?: ActiveNotificationModel( @@ -247,6 +251,7 @@ private fun ActiveNotificationsStore.createOrReuse( contentIntent = contentIntent, bucket = bucket, callType = callType, + promotedContent = promotedContent, ) } @@ -272,6 +277,7 @@ private fun ActiveNotificationModel.isCurrent( isGroupSummary: Boolean, bucket: Int, callType: CallType, + promotedContent: PromotedNotificationContentModel?, ): Boolean { return when { key != this.key -> false @@ -295,6 +301,9 @@ private fun ActiveNotificationModel.isCurrent( contentIntent != this.contentIntent -> false bucket != this.bucket -> false callType != this.callType -> false + // QQQ: Do we need to do the same `isCurrent` thing within the content model to avoid + // recreating the active notification model constantly? + promotedContent != this.promotedContent -> false else -> true } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt index 76e228bb54d2..2c5d9c2e449b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt @@ -38,6 +38,8 @@ interface NotificationsController { ) fun resetUserExpandedStates() + fun setNotificationSnoozed(sbn: StatusBarNotification, snoozeOption: SnoozeOption) + fun getActiveNotificationsCount(): Int } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt index 1677418c5c30..ea6a60bd7a1c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt @@ -129,7 +129,7 @@ constructor( } else { notificationListener.snoozeNotification( sbn.key, - snoozeOption.minutesToSnoozeFor * 60 * 1000.toLong() + snoozeOption.minutesToSnoozeFor * 60 * 1000.toLong(), ) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt index 65ba6de5b5cb..148b3f021643 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt @@ -28,9 +28,9 @@ import javax.inject.Inject /** * Implementation of [NotificationsController] that's used when notifications rendering is disabled. */ -class NotificationsControllerStub @Inject constructor( - private val notificationListener: NotificationListener -) : NotificationsController { +class NotificationsControllerStub +@Inject +constructor(private val notificationListener: NotificationListener) : NotificationsController { override fun initialize( presenter: NotificationPresenter, @@ -43,11 +43,9 @@ class NotificationsControllerStub @Inject constructor( notificationListener.registerAsSystemService() } - override fun resetUserExpandedStates() { - } + override fun resetUserExpandedStates() {} - override fun setNotificationSnoozed(sbn: StatusBarNotification, snoozeOption: SnoozeOption) { - } + override fun setNotificationSnoozed(sbn: StatusBarNotification, snoozeOption: SnoozeOption) {} override fun getActiveNotificationsCount(): Int { return 0 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt new file mode 100644 index 000000000000..41ee3b992c5a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.promoted.shared.model + +import android.annotation.DrawableRes +import android.graphics.drawable.Icon +import com.android.internal.widget.NotificationProgressModel +import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips +import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi + +/** + * The content needed to render a promoted notification to surfaces besides the notification stack, + * like the skeleton view on AOD or the status bar chip. + */ +data class PromotedNotificationContentModel( + val key: String, + + // for all styles: + val skeletonSmallIcon: Icon?, // TODO(b/377568176): Make into an IconModel. + val appName: CharSequence?, + val subText: CharSequence?, + val time: When?, + val lastAudiblyAlertedMs: Long, + @DrawableRes val profileBadgeResId: Int?, + val title: CharSequence?, + val text: CharSequence?, + val skeletonLargeIcon: Icon?, // TODO(b/377568176): Make into an IconModel. + val style: Style, + + // for CallStyle: + val personIcon: Icon?, // TODO(b/377568176): Make into an IconModel. + val personName: CharSequence?, + val verificationIcon: Icon?, // TODO(b/377568176): Make into an IconModel. + val verificationText: CharSequence?, + + // for ProgressStyle: + val progress: NotificationProgressModel?, +) { + class Builder(val key: String) { + var skeletonSmallIcon: Icon? = null + var appName: CharSequence? = null + var subText: CharSequence? = null + var time: When? = null + var lastAudiblyAlertedMs: Long = 0L + @DrawableRes var profileBadgeResId: Int? = null + var title: CharSequence? = null + var text: CharSequence? = null + var skeletonLargeIcon: Icon? = null + var style: Style = Style.Ineligible + + // for CallStyle: + var personIcon: Icon? = null + var personName: CharSequence? = null + var verificationIcon: Icon? = null + var verificationText: CharSequence? = null + + // for ProgressStyle: + var progress: NotificationProgressModel? = null + + fun build() = + PromotedNotificationContentModel( + key = key, + skeletonSmallIcon = skeletonSmallIcon, + appName = appName, + subText = subText, + time = time, + lastAudiblyAlertedMs = lastAudiblyAlertedMs, + profileBadgeResId = profileBadgeResId, + title = title, + text = text, + skeletonLargeIcon = skeletonLargeIcon, + style = style, + personIcon = personIcon, + personName = personName, + verificationIcon = verificationIcon, + verificationText = verificationText, + progress = progress, + ) + } + + /** The timestamp associated with a notification, along with the mode used to display it. */ + data class When(val time: Long, val mode: Mode) { + /** The mode used to display a notification's `when` value. */ + enum class Mode { + Absolute, + CountDown, + CountUp, + } + } + + /** The promotion-eligible style of a notification, or [Style.Ineligible] if not. */ + enum class Style { + BigPicture, + BigText, + Call, + Progress, + Ineligible, + } + + companion object { + @JvmStatic + fun featureFlagEnabled(): Boolean = + PromotedNotificationUi.isEnabled || StatusBarNotifChips.isEnabled + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt index 19a92a2230ba..a2b71551eca8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/ActiveNotificationModel.kt @@ -17,7 +17,9 @@ package com.android.systemui.statusbar.notification.shared import android.app.PendingIntent import android.graphics.drawable.Icon +import android.util.Log import com.android.systemui.statusbar.StatusBarIconView +import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.stack.PriorityBucket /** @@ -36,6 +38,7 @@ data class ActiveNotificationModel( val groupKey: String?, /** When this notification was posted. */ val whenTime: Long, + // TODO(b/377566661): Make isPromoted just check if promotedContent != null. /** True if this notification should be promoted and false otherwise. */ val isPromoted: Boolean, /** Is this entry in the ambient / minimized section (lowest priority)? */ @@ -78,7 +81,24 @@ data class ActiveNotificationModel( @PriorityBucket val bucket: Int, /** The call type set on the notification. */ val callType: CallType, -) : ActiveNotificationEntryModel() + /** + * The content needed to render this as a promoted notification on various surfaces, or null if + * this notification cannot be rendered as a promoted notification. + */ + val promotedContent: PromotedNotificationContentModel?, +) : ActiveNotificationEntryModel() { + init { + if (!PromotedNotificationContentModel.featureFlagEnabled()) { + if (promotedContent != null) { + Log.wtf(TAG, "passing non-null promoted content without feature flag enabled") + } + } + } + + companion object { + private const val TAG = "ActiveNotificationEntryModel" + } +} /** Model for a group of notifications. */ data class ActiveNotificationGroupModel( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 80c8e8b2a109..db294934c9ed 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -171,14 +171,12 @@ import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.shade.NotificationShadeWindowViewController; import com.android.systemui.shade.QuickSettingsController; import com.android.systemui.shade.ShadeController; -import com.android.systemui.shade.ShadeExpandsOnStatusBarLongPress; import com.android.systemui.shade.ShadeExpansionChangeEvent; import com.android.systemui.shade.ShadeExpansionListener; import com.android.systemui.shade.ShadeExpansionStateManager; import com.android.systemui.shade.ShadeLogger; import com.android.systemui.shade.ShadeSurface; import com.android.systemui.shade.ShadeViewController; -import com.android.systemui.shade.StatusBarLongPressGestureDetector; import com.android.systemui.shared.recents.utilities.Utilities; import com.android.systemui.shared.statusbar.phone.BarTransitions; import com.android.systemui.statusbar.AutoHideUiElement; @@ -368,7 +366,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private PhoneStatusBarViewController mPhoneStatusBarViewController; private PhoneStatusBarTransitions mStatusBarTransitions; - private final Provider<StatusBarLongPressGestureDetector> mStatusBarLongPressGestureDetector; private final AuthRippleController mAuthRippleController; @WindowVisibleState private int mStatusBarWindowState = WINDOW_STATE_SHOWING; private final NotificationShadeWindowController mNotificationShadeWindowController; @@ -674,7 +671,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { ShadeController shadeController, WindowRootViewVisibilityInteractor windowRootViewVisibilityInteractor, StatusBarKeyguardViewManager statusBarKeyguardViewManager, - Provider<StatusBarLongPressGestureDetector> statusBarLongPressGestureDetector, ViewMediatorCallback viewMediatorCallback, InitController initController, @Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler, @@ -782,7 +778,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mShadeController = shadeController; mWindowRootViewVisibilityInteractor = windowRootViewVisibilityInteractor; mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; - mStatusBarLongPressGestureDetector = statusBarLongPressGestureDetector; mKeyguardViewMediatorCallback = viewMediatorCallback; mInitController = initController; mPluginDependencyProvider = pluginDependencyProvider; @@ -1532,11 +1527,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { // to touch outside the customizer to close it, such as on the status or nav bar. mShadeController.onStatusBarTouch(event); } - if (ShadeExpandsOnStatusBarLongPress.isEnabled() - && mStatusBarStateController.getState() == StatusBarState.KEYGUARD) { - mStatusBarLongPressGestureDetector.get().handleTouch(event); - } - return getNotificationShadeWindowView().onTouchEvent(event); }; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt index 7919c84152b2..83551e9b8294 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt @@ -17,12 +17,12 @@ package com.android.systemui.statusbar.phone import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.statusbar.notification.HeadsUpManagerPhone +import com.android.systemui.statusbar.policy.BaseHeadsUpManager import com.android.systemui.statusbar.policy.HeadsUpManager import dagger.Binds import dagger.Module @Module interface HeadsUpModule { - @Binds @SysUISingleton fun bindsHeadsUpManager(hum: HeadsUpManagerPhone): HeadsUpManager + @Binds @SysUISingleton fun bindsHeadsUpManager(hum: BaseHeadsUpManager): HeadsUpManager } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 176dd8de6cd4..91c43ddf1ce4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -39,8 +39,8 @@ import com.android.systemui.Dependency; import com.android.systemui.Flags; import com.android.systemui.Gefingerpoken; import com.android.systemui.res.R; +import com.android.systemui.shade.LongPressGestureDetector; import com.android.systemui.shade.ShadeExpandsOnStatusBarLongPress; -import com.android.systemui.shade.StatusBarLongPressGestureDetector; import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer; import com.android.systemui.statusbar.window.StatusBarWindowControllerStore; import com.android.systemui.user.ui.binder.StatusBarUserChipViewBinder; @@ -69,7 +69,7 @@ public class PhoneStatusBarView extends FrameLayout { private InsetsFetcher mInsetsFetcher; private int mDensity; private float mFontScale; - private StatusBarLongPressGestureDetector mStatusBarLongPressGestureDetector; + private LongPressGestureDetector mLongPressGestureDetector; /** * Draw this many pixels into the left/right side of the cutout to optimally use the space @@ -81,10 +81,9 @@ public class PhoneStatusBarView extends FrameLayout { mStatusBarWindowControllerStore = Dependency.get(StatusBarWindowControllerStore.class); } - void setLongPressGestureDetector( - StatusBarLongPressGestureDetector statusBarLongPressGestureDetector) { + void setLongPressGestureDetector(LongPressGestureDetector longPressGestureDetector) { if (ShadeExpandsOnStatusBarLongPress.isEnabled()) { - mStatusBarLongPressGestureDetector = statusBarLongPressGestureDetector; + mLongPressGestureDetector = longPressGestureDetector; } } @@ -208,9 +207,8 @@ public class PhoneStatusBarView extends FrameLayout { @Override public boolean onTouchEvent(MotionEvent event) { - if (ShadeExpandsOnStatusBarLongPress.isEnabled() - && mStatusBarLongPressGestureDetector != null) { - mStatusBarLongPressGestureDetector.handleTouch(event); + if (ShadeExpandsOnStatusBarLongPress.isEnabled() && mLongPressGestureDetector != null) { + mLongPressGestureDetector.handleTouch(event); } if (mTouchEventHandler == null) { Log.w( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt index 16e023ce17fd..a94db490df0c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt @@ -34,11 +34,11 @@ import com.android.systemui.plugins.DarkIconDispatcher import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.ui.view.WindowRootView +import com.android.systemui.shade.LongPressGestureDetector import com.android.systemui.shade.ShadeController import com.android.systemui.shade.ShadeExpandsOnStatusBarLongPress import com.android.systemui.shade.ShadeLogger import com.android.systemui.shade.ShadeViewController -import com.android.systemui.shade.StatusBarLongPressGestureDetector import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator import com.android.systemui.statusbar.data.repository.StatusBarContentInsetsProviderStore @@ -69,7 +69,7 @@ private constructor( private val shadeController: ShadeController, private val shadeViewController: ShadeViewController, private val panelExpansionInteractor: PanelExpansionInteractor, - private val statusBarLongPressGestureDetector: Provider<StatusBarLongPressGestureDetector>, + private val longPressGestureDetector: Provider<LongPressGestureDetector>, private val windowRootView: Provider<WindowRootView>, private val shadeLogger: ShadeLogger, private val moveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?, @@ -119,7 +119,7 @@ private constructor( addCursorSupportToIconContainers() if (ShadeExpandsOnStatusBarLongPress.isEnabled) { - mView.setLongPressGestureDetector(statusBarLongPressGestureDetector.get()) + mView.setLongPressGestureDetector(longPressGestureDetector.get()) } progressProvider?.setReadyToHandleTransition(true) @@ -336,7 +336,7 @@ private constructor( private val shadeController: ShadeController, private val shadeViewController: ShadeViewController, private val panelExpansionInteractor: PanelExpansionInteractor, - private val statusBarLongPressGestureDetector: Provider<StatusBarLongPressGestureDetector>, + private val longPressGestureDetector: Provider<LongPressGestureDetector>, private val windowRootView: Provider<WindowRootView>, private val shadeLogger: ShadeLogger, private val viewUtil: ViewUtil, @@ -361,7 +361,7 @@ private constructor( shadeController, shadeViewController, panelExpansionInteractor, - statusBarLongPressGestureDetector, + longPressGestureDetector, windowRootView, shadeLogger, statusBarMoveFromCenterAnimationController, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 0c511aeae3e5..aef26dea3c0d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -520,6 +520,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mListenForCanShowAlternateBouncer.cancel(null); } mListenForCanShowAlternateBouncer = null; + // Collector that keeps the AlternateBouncerInteractor#canShowAlternateBouncer flow hot. mListenForCanShowAlternateBouncer = mJavaAdapter.alwaysCollectFlow( mAlternateBouncerInteractor.getCanShowAlternateBouncer(), @@ -568,6 +569,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } private void consumeCanShowAlternateBouncer(boolean canShow) { + if (SceneContainerFlag.isEnabled()) { + // When the scene framework is enabled, the alternative bouncer is hidden from the scene + // framework logic so there's no need for this logic here. + return; + } + // Hack: this is required to fix issues where // KeyguardBouncerRepository#alternateBouncerVisible state is incorrectly set and then never // reset. This is caused by usages of show()/forceShow() that only read this flow to set the diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java index c55a63c9edf5..23b4b65bb2ac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java @@ -376,7 +376,11 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue mCarrierConfigTracker.addDefaultDataSubscriptionChangedListener(mDefaultDataListener); mHomeStatusBarViewBinder.bind( - mStatusBar, mHomeStatusBarViewModel, mStatusBarVisibilityChangeListener); + mStatusBar, + mHomeStatusBarViewModel, + /* systemEventChipAnimateIn */ null, + /* systemEventChipAnimateOut */ null, + mStatusBarVisibilityChangeListener); } private String getDumpableName() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt index 1f9ea08e602f..fd7bce099d81 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt @@ -71,49 +71,87 @@ constructor( override fun onSystemEventAnimationBegin(): Animator { isAnimationRunning = true - val moveOut = - ValueAnimator.ofFloat(0f, 1f).apply { - duration = 23.frames - interpolator = STATUS_BAR_X_MOVE_OUT - addUpdateListener { - onTranslationXChanged(-(translationXIn * animatedValue as Float)) - } - } - val alphaOut = - ValueAnimator.ofFloat(1f, 0f).apply { - duration = 8.frames - interpolator = null - addUpdateListener { onAlphaChanged(animatedValue as Float) } - } - - val animSet = AnimatorSet() - animSet.playTogether(moveOut, alphaOut) - return animSet + return getDefaultStatusBarAnimationForChipEnter( + translationXIn, + onTranslationXChanged, + onAlphaChanged, + ) } override fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator { onTranslationXChanged(translationXOut.toFloat()) - val moveIn = - ValueAnimator.ofFloat(1f, 0f).apply { - duration = 23.frames - startDelay = 7.frames - interpolator = STATUS_BAR_X_MOVE_IN - addUpdateListener { - onTranslationXChanged(translationXOut * animatedValue as Float) + val anim = + getDefaultStatusBarAnimationForChipExit( + translationXOut, + onTranslationXChanged, + onAlphaChanged, + ) + anim.doOnEnd { isAnimationRunning = false } + anim.doOnCancel { isAnimationRunning = false } + + return anim + } + + /** Static definition of these animations so we can use them more easily from view binders */ + companion object { + /** + * Chip: coming in. Animated view: going out. + * + * Implements the exact spec for animating any status bar elements OUT to make space for the + * chip IN animation. + */ + fun getDefaultStatusBarAnimationForChipEnter( + targetTranslation: Int, + setX: (Float) -> Unit, + setAlpha: (Float) -> Unit, + ): Animator { + val moveOut = + ValueAnimator.ofFloat(0f, 1f).apply { + duration = 23.frames + interpolator = STATUS_BAR_X_MOVE_OUT + addUpdateListener { setX(-(targetTranslation * animatedValue as Float)) } + } + val alphaOut = + ValueAnimator.ofFloat(1f, 0f).apply { + duration = 8.frames + interpolator = null + addUpdateListener { setAlpha(animatedValue as Float) } + } + + val animSet = AnimatorSet() + animSet.playTogether(moveOut, alphaOut) + return animSet + } + + /** + * Chip: going out. Animated view: coming in. + * + * Implements the exact spec for animating any status bar elements IN as the chip is + * animating OUT + */ + fun getDefaultStatusBarAnimationForChipExit( + targetTranslation: Int, + setX: (Float) -> Unit, + setAlpha: (Float) -> Unit, + ): Animator { + val moveIn = + ValueAnimator.ofFloat(1f, 0f).apply { + duration = 23.frames + startDelay = 7.frames + interpolator = STATUS_BAR_X_MOVE_IN + addUpdateListener { setX(targetTranslation * animatedValue as Float) } + } + val alphaIn = + ValueAnimator.ofFloat(0f, 1f).apply { + duration = 5.frames + startDelay = 11.frames + interpolator = null + addUpdateListener { setAlpha(animatedValue as Float) } } - } - val alphaIn = - ValueAnimator.ofFloat(0f, 1f).apply { - duration = 5.frames - startDelay = 11.frames - interpolator = null - addUpdateListener { onAlphaChanged(animatedValue as Float) } - } - val animatorSet = AnimatorSet() - animatorSet.playTogether(moveIn, alphaIn) - animatorSet.doOnEnd { isAnimationRunning = false } - animatorSet.doOnCancel { isAnimationRunning = false } - return animatorSet + val animatorSet = AnimatorSet() + animatorSet.playTogether(moveIn, alphaIn) + return animatorSet + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt index 935b1012be31..bfdc8bd5e4c8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt @@ -23,6 +23,8 @@ import com.android.systemui.log.LogBuffer import com.android.systemui.log.LogBufferFactory import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBufferFactory +import com.android.systemui.statusbar.events.data.repository.SystemStatusEventAnimationRepository +import com.android.systemui.statusbar.events.data.repository.SystemStatusEventAnimationRepositoryImpl import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepository import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepositoryImpl import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel @@ -85,6 +87,11 @@ abstract class StatusBarPipelineModule { abstract fun connectivityRepository(impl: ConnectivityRepositoryImpl): ConnectivityRepository @Binds + abstract fun systemStatusEventAnimationRepository( + impl: SystemStatusEventAnimationRepositoryImpl + ): SystemStatusEventAnimationRepository + + @Binds abstract fun realDeviceBasedSatelliteRepository( impl: DeviceBasedSatelliteRepositoryImpl ): RealDeviceBasedSatelliteRepository diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt index 2177e025b976..72df02714d43 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt @@ -32,6 +32,10 @@ import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifCh import com.android.systemui.statusbar.chips.ui.binder.OngoingActivityChipBinder import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.core.StatusBarRootModernization +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingIn +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingOut +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.RunningChipAnim import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel @@ -46,10 +50,16 @@ interface HomeStatusBarViewBinder { /** * Binds the view to the view-model. [listener] will be notified whenever an event that may * change the status bar visibility occurs. + * + * Null chip animations are used when [StatusBarRootModernization] is off (i.e., when we are + * binding from the fragment). If non-null, they control the animation of the system icon area + * to support the chip animations. */ fun bind( view: View, viewModel: HomeStatusBarViewModel, + systemEventChipAnimateIn: ((View) -> Unit)?, + systemEventChipAnimateOut: ((View) -> Unit)?, listener: StatusBarVisibilityChangeListener, ) } @@ -59,6 +69,8 @@ class HomeStatusBarViewBinderImpl @Inject constructor() : HomeStatusBarViewBinde override fun bind( view: View, viewModel: HomeStatusBarViewModel, + systemEventChipAnimateIn: ((View) -> Unit)?, + systemEventChipAnimateOut: ((View) -> Unit)?, listener: StatusBarVisibilityChangeListener, ) { view.repeatWhenAttached { @@ -95,6 +107,7 @@ class HomeStatusBarViewBinderImpl @Inject constructor() : HomeStatusBarViewBinde when (primaryChipModel) { is OngoingActivityChipModel.Shown -> primaryChipView.show(shouldAnimateChange = true) + is OngoingActivityChipModel.Hidden -> primaryChipView.hide( state = View.GONE, @@ -109,6 +122,7 @@ class HomeStatusBarViewBinderImpl @Inject constructor() : HomeStatusBarViewBinde hasSecondaryOngoingActivity = false, shouldAnimate = true, ) + is OngoingActivityChipModel.Hidden -> listener.onOngoingActivityStatusChanged( hasPrimaryOngoingActivity = false, @@ -175,10 +189,30 @@ class HomeStatusBarViewBinderImpl @Inject constructor() : HomeStatusBarViewBinde view.requireViewById<View>(R.id.status_bar_end_side_content) // TODO(b/364360986): Also handle operator name view. launch { - viewModel.isSystemInfoVisible.collect { - systemInfoView.adjustVisibility(it) - // TODO(b/364360986): The system info view has a custom alpha controller - // in CollapsedStatusBarFragment. + viewModel.systemInfoCombinedVis.collect { (baseVis, animState) -> + // Broadly speaking, the baseVis controls the view.visibility, and + // the animation state uses only alpha to achieve its effect. This + // means that we can always modify the visibility, and if we're + // animating we can use the animState to handle it. If we are not + // animating, then we can use the baseVis default animation + if (animState.isAnimatingChip()) { + // Just apply the visibility of the view, but don't animate + systemInfoView.visibility = baseVis.visibility + // Now apply the animation state, with its animator + when (animState) { + AnimatingIn -> { + systemEventChipAnimateIn?.invoke(systemInfoView) + } + AnimatingOut -> { + systemEventChipAnimateOut?.invoke(systemInfoView) + } + else -> { + // Nothing to do here + } + } + } else { + systemInfoView.adjustVisibility(baseVis) + } } } } @@ -186,6 +220,14 @@ class HomeStatusBarViewBinderImpl @Inject constructor() : HomeStatusBarViewBinde } } + private fun SystemEventAnimationState.isAnimatingChip() = + when (this) { + AnimatingIn, + AnimatingOut, + RunningChipAnim -> true + else -> false + } + private fun OngoingActivityChipModel.toVisibilityModel(): VisibilityModel { return VisibilityModel( visibility = if (this is OngoingActivityChipModel.Shown) View.VISIBLE else View.GONE, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt index a9c2f72f7b18..1faa9f32af1f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt @@ -35,6 +35,7 @@ import com.android.app.tracing.coroutines.launchTraced as launch import com.android.systemui.plugins.DarkIconDispatcher import com.android.systemui.res.R import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore +import com.android.systemui.statusbar.events.domain.interactor.SystemStatusEventAnimationInteractor import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder import com.android.systemui.statusbar.phone.NotificationIconContainer import com.android.systemui.statusbar.phone.PhoneStatusBarView @@ -59,6 +60,7 @@ constructor( private val iconController: StatusBarIconController, private val ongoingCallController: OngoingCallController, private val darkIconDispatcherStore: DarkIconDispatcherStore, + private val eventAnimationInteractor: SystemStatusEventAnimationInteractor, ) { fun create(root: ViewGroup, andThen: (ViewGroup) -> Unit): ComposeView { val composeView = ComposeView(root.context) @@ -73,6 +75,7 @@ constructor( iconController = iconController, ongoingCallController = ongoingCallController, darkIconDispatcher = darkIconDispatcherStore.forDisplay(root.context.displayId), + eventAnimationInteractor = eventAnimationInteractor, onViewCreated = andThen, ) } @@ -102,6 +105,7 @@ fun StatusBarRoot( iconController: StatusBarIconController, ongoingCallController: OngoingCallController, darkIconDispatcher: DarkIconDispatcher, + eventAnimationInteractor: SystemStatusEventAnimationInteractor, onViewCreated: (ViewGroup) -> Unit, ) { // None of these methods are used when [StatusBarRootModernization] is on. @@ -181,6 +185,8 @@ fun StatusBarRoot( statusBarViewBinder.bind( phoneStatusBarView, statusBarViewModel, + eventAnimationInteractor::animateStatusBarContentForChipEnter, + eventAnimationInteractor::animateStatusBarContentForChipExit, nopVisibilityChangeListener, ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt index 4277a8be64d3..6a9b43c995e4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt @@ -35,6 +35,9 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModel +import com.android.systemui.statusbar.events.domain.interactor.SystemStatusEventAnimationInteractor +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor import com.android.systemui.statusbar.phone.domain.interactor.LightsOutInteractor @@ -95,7 +98,12 @@ interface HomeStatusBarViewModel { val isClockVisible: Flow<VisibilityModel> val isNotificationIconContainerVisible: Flow<VisibilityModel> - val isSystemInfoVisible: Flow<VisibilityModel> + /** + * Pair of (system info visibility, event animation state). The animation state can be used to + * respond to the system event chip animations. In all cases, system info visibility correctly + * models the View.visibility for the system info area + */ + val systemInfoCombinedVis: StateFlow<SystemInfoCombinedVisibilityModel> /** * Apps can request a low profile mode [android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE] where @@ -114,6 +122,12 @@ interface HomeStatusBarViewModel { /** True if a visibility change should be animated. */ val shouldAnimateChange: Boolean, ) + + /** The combined visibility + animation state for the system info status bar area */ + data class SystemInfoCombinedVisibilityModel( + val baseVisibility: VisibilityModel, + val animationState: SystemEventAnimationState, + ) } @SysUISingleton @@ -129,6 +143,7 @@ constructor( sceneContainerOcclusionInteractor: SceneContainerOcclusionInteractor, shadeInteractor: ShadeInteractor, ongoingActivityChipsViewModel: OngoingActivityChipsViewModel, + animations: SystemStatusEventAnimationInteractor, @Application coroutineScope: CoroutineScope, ) : HomeStatusBarViewModel { override val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean> = @@ -228,7 +243,7 @@ constructor( visibilityViaDisableFlags.animate, ) } - override val isSystemInfoVisible: Flow<VisibilityModel> = + private val isSystemInfoVisible = combine( shouldHomeStatusBarBeVisible, collapsedStatusBarInteractor.visibilityViaDisableFlags, @@ -238,6 +253,22 @@ constructor( VisibilityModel(showSystemInfo.toVisibilityInt(), visibilityViaDisableFlags.animate) } + override val systemInfoCombinedVis = + combine(isSystemInfoVisible, animations.animationState) { sysInfoVisible, animationState -> + HomeStatusBarViewModel.SystemInfoCombinedVisibilityModel( + sysInfoVisible, + animationState, + ) + } + .stateIn( + coroutineScope, + SharingStarted.WhileSubscribed(), + HomeStatusBarViewModel.SystemInfoCombinedVisibilityModel( + VisibilityModel(View.VISIBLE, false), + Idle, + ), + ) + @View.Visibility private fun Boolean.toVisibilityInt(): Int { return if (this) View.VISIBLE else View.GONE diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java index 4284c1911b33..f6f567f17077 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java @@ -16,33 +16,48 @@ package com.android.systemui.statusbar.policy; -import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP; - import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; import android.content.Context; import android.content.res.Resources; import android.database.ContentObserver; +import android.graphics.Region; import android.os.Handler; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; +import android.util.Pools; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; +import com.android.internal.policy.SystemBarUtils; import com.android.systemui.EventLogTags; +import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.res.R; +import com.android.systemui.scene.shared.flag.SceneContainerFlag; +import com.android.systemui.shade.domain.interactor.ShadeInteractor; +import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag; +import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener; +import com.android.systemui.statusbar.notification.collection.provider.OnReorderingBannedListener; +import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; +import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; +import com.android.systemui.statusbar.notification.data.repository.HeadsUpRepository; +import com.android.systemui.statusbar.notification.data.repository.HeadsUpRowRepository; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun; import com.android.systemui.statusbar.phone.ExpandHeadsUpOnInlineReply; +import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.util.ListenerSet; import com.android.systemui.util.concurrency.DelayableExecutor; +import com.android.systemui.util.kotlin.JavaAdapter; import com.android.systemui.util.settings.GlobalSettings; import com.android.systemui.util.time.SystemClock; @@ -50,14 +65,27 @@ import org.jetbrains.annotations.NotNull; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.Stack; import java.util.stream.Stream; +import javax.inject.Inject; + +import kotlinx.coroutines.flow.Flow; +import kotlinx.coroutines.flow.MutableStateFlow; +import kotlinx.coroutines.flow.StateFlow; +import kotlinx.coroutines.flow.StateFlowKt; + /** * A manager which handles heads up notifications which is a special mode where * they simply peek from the top of the screen. */ -public abstract class BaseHeadsUpManager implements HeadsUpManager { +@SysUISingleton +public class BaseHeadsUpManager + implements HeadsUpManager, HeadsUpRepository, OnHeadsUpChangedListener { private static final String TAG = "BaseHeadsUpManager"; private static final String SETTING_HEADS_UP_SNOOZE_LENGTH_MS = "heads_up_snooze_length_ms"; @@ -74,7 +102,11 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { private final AccessibilityManagerWrapper mAccessibilityMgr; private final UiEventLogger mUiEventLogger; - private final AvalancheController mAvalancheController; + private AvalancheController mAvalancheController; + private final KeyguardBypassController mBypassController; + private final GroupMembershipManager mGroupMembershipManager; + private final List<OnHeadsUpPhoneListenerChange> mHeadsUpPhoneListeners = new ArrayList<>(); + private final VisualStabilityProvider mVisualStabilityProvider; protected final SystemClock mSystemClock; protected final ArrayMap<String, HeadsUpEntry> mHeadsUpEntryMap = new ArrayMap<>(); @@ -84,6 +116,53 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { protected int mAutoDismissTime; protected DelayableExecutor mExecutor; + @VisibleForTesting + public final int mExtensionTime; + + // TODO(b/328393698) move the topHeadsUpRow logic to an interactor + private final MutableStateFlow<HeadsUpRowRepository> mTopHeadsUpRow = + StateFlowKt.MutableStateFlow(null); + private final MutableStateFlow<Set<HeadsUpRowRepository>> mHeadsUpNotificationRows = + StateFlowKt.MutableStateFlow(new HashSet<>()); + private final MutableStateFlow<Boolean> mHeadsUpAnimatingAway = + StateFlowKt.MutableStateFlow(false); + private final HashSet<String> mSwipedOutKeys = new HashSet<>(); + private final HashSet<NotificationEntry> mEntriesToRemoveAfterExpand = new HashSet<>(); + @VisibleForTesting + public final ArraySet<NotificationEntry> mEntriesToRemoveWhenReorderingAllowed + = new ArraySet<>(); + + private boolean mReleaseOnExpandFinish; + private boolean mTrackingHeadsUp; + private boolean mIsShadeOrQsExpanded; + private boolean mIsQsExpanded; + private int mStatusBarState; + private AnimationStateHandler mAnimationStateHandler; + private int mHeadsUpInset; + + // Used for determining the region for touch interaction + private final Region mTouchableRegion = new Region(); + + private final Pools.Pool<HeadsUpEntry> mEntryPool = new Pools.Pool<>() { + private final Stack<HeadsUpEntry> mPoolObjects = new Stack<>(); + + @Override + public HeadsUpEntry acquire() { + NotificationThrottleHun.assertInLegacyMode(); + if (!mPoolObjects.isEmpty()) { + return mPoolObjects.pop(); + } + return new HeadsUpEntry(); + } + + @Override + public boolean release(@NonNull HeadsUpEntry instance) { + NotificationThrottleHun.assertInLegacyMode(); + mPoolObjects.push(instance); + return true; + } + }; + /** * Enum entry for notification peek logged from this class. */ @@ -100,14 +179,23 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { } } - public BaseHeadsUpManager(@NonNull final Context context, + @Inject + public BaseHeadsUpManager( + @NonNull final Context context, HeadsUpManagerLogger logger, + StatusBarStateController statusBarStateController, + KeyguardBypassController bypassController, + GroupMembershipManager groupMembershipManager, + VisualStabilityProvider visualStabilityProvider, + ConfigurationController configurationController, @Main Handler handler, GlobalSettings globalSettings, SystemClock systemClock, @Main DelayableExecutor executor, AccessibilityManagerWrapper accessibilityManagerWrapper, UiEventLogger uiEventLogger, + JavaAdapter javaAdapter, + ShadeInteractor shadeInteractor, AvalancheController avalancheController) { mLogger = logger; mExecutor = executor; @@ -117,12 +205,16 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { mUiEventLogger = uiEventLogger; mAvalancheController = avalancheController; mAvalancheController.setBaseEntryMapStr(this::getEntryMapStr); + mBypassController = bypassController; + mGroupMembershipManager = groupMembershipManager; + mVisualStabilityProvider = visualStabilityProvider; Resources resources = context.getResources(); mMinimumDisplayTime = NotificationThrottleHun.isEnabled() ? 500 : resources.getInteger(R.integer.heads_up_notification_minimum_time); mStickyForSomeTimeAutoDismissTime = resources.getInteger( R.integer.sticky_heads_up_notification_time); mAutoDismissTime = resources.getInteger(R.integer.heads_up_notification_decay); + mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time); mTouchAcceptanceDelay = resources.getInteger(R.integer.touch_acceptance_delay); mSnoozedPackages = new ArrayMap<>(); int defaultSnoozeLengthMs = @@ -145,11 +237,38 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { globalSettings.getUriFor(SETTING_HEADS_UP_SNOOZE_LENGTH_MS), /* notifyForDescendants = */ false, settingsObserver); + + statusBarStateController.addCallback(mStatusBarStateListener); + updateResources(); + configurationController.addCallback(new ConfigurationController.ConfigurationListener() { + @Override + public void onDensityOrFontScaleChanged() { + updateResources(); + } + + @Override + public void onThemeChanged() { + updateResources(); + } + }); + javaAdapter.alwaysCollectFlow(shadeInteractor.isAnyExpanded(), + this::onShadeOrQsExpanded); + if (SceneContainerFlag.isEnabled()) { + javaAdapter.alwaysCollectFlow(shadeInteractor.isQsExpanded(), + this::onQsExpanded); + } + if (NotificationThrottleHun.isEnabled()) { + mVisualStabilityProvider.addPersistentReorderingBannedListener( + mOnReorderingBannedListener); + mVisualStabilityProvider.addPersistentReorderingAllowedListener( + mOnReorderingAllowedListener); + } } /** * Adds an OnHeadUpChangedListener to observe events. */ + @Override public void addListener(@NonNull OnHeadsUpChangedListener listener) { mListeners.addIfAbsent(listener); } @@ -157,11 +276,31 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { /** * Removes the OnHeadUpChangedListener from the observer list. */ + @Override public void removeListener(@NonNull OnHeadsUpChangedListener listener) { mListeners.remove(listener); } /** + * Add a listener to receive callbacks {@link #setHeadsUpAnimatingAway(boolean)} + */ + @Override + public void addHeadsUpPhoneListener(@NonNull OnHeadsUpPhoneListenerChange listener) { + mHeadsUpPhoneListeners.add(listener); + } + + @Override + public void setAnimationStateHandler(@NonNull AnimationStateHandler handler) { + mAnimationStateHandler = handler; + } + + private void updateResources() { + Resources resources = mContext.getResources(); + mHeadsUpInset = SystemBarUtils.getStatusBarHeight(mContext) + + resources.getDimensionPixelSize(R.dimen.heads_up_status_bar_padding); + } + + /** * Called when posting a new notification that should appear on screen. * Adds the notification to be managed. * @param entry entry to show @@ -188,14 +327,24 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { mAvalancheController.update(headsUpEntry, runnable, "showNotification"); } - /** - * Try to remove the notification. May not succeed if the notification has not been shown long - * enough and needs to be kept around. - * @param key the key of the notification to remove - * @param releaseImmediately force a remove regardless of earliest removal time - * @param reason reason for removing the notification - * @return true if notification is removed, false otherwise - */ + @Override + public boolean removeNotification( + @NonNull String key, + boolean releaseImmediately, + boolean animate, + @NonNull String reason) { + if (animate) { + return removeNotification(key, releaseImmediately, + "removeNotification(animate: true), reason: " + reason); + } else { + mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(false); + final boolean removed = removeNotification(key, releaseImmediately, + "removeNotification(animate: false), reason: " + reason); + mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(true); + return removed; + } + } + @Override public boolean removeNotification(@NotNull String key, boolean releaseImmediately, @NonNull String reason) { @@ -261,6 +410,42 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { } } + @Override + public void setTrackingHeadsUp(boolean trackingHeadsUp) { + mTrackingHeadsUp = trackingHeadsUp; + } + + @Override + public boolean shouldSwallowClick(@NonNull String key) { + BaseHeadsUpManager.HeadsUpEntry entry = getHeadsUpEntry(key); + return entry != null && mSystemClock.elapsedRealtime() < entry.mPostTime; + } + + @Override + public void releaseAfterExpansion() { + if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return; + onExpandingFinished(); + } + + @Override + public void onExpandingFinished() { + if (mReleaseOnExpandFinish) { + releaseAllImmediately(); + mReleaseOnExpandFinish = false; + } else { + for (NotificationEntry entry : getAllEntries().toList()) { + entry.setSeenInShade(true); + } + for (NotificationEntry entry : mEntriesToRemoveAfterExpand) { + if (isHeadsUpEntry(entry.getKey())) { + // Maybe the heads-up was removed already + removeEntry(entry.getKey(), "onExpandingFinished"); + } + } + } + mEntriesToRemoveAfterExpand.clear(); + } + /** * Clears all managed notifications. */ @@ -339,10 +524,19 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { return 0; } + @VisibleForTesting protected boolean shouldHeadsUpBecomePinned(@NonNull NotificationEntry entry) { - if (entry == null) { - return false; + boolean pin = mStatusBarState == StatusBarState.SHADE && !mIsShadeOrQsExpanded; + if (SceneContainerFlag.isEnabled()) { + pin |= mIsQsExpanded; + } + if (mBypassController.getBypassEnabled()) { + pin |= mStatusBarState == StatusBarState.KEYGUARD; + } + if (pin) { + return true; } + final HeadsUpEntry headsUpEntry = getHeadsUpEntry(entry.getKey()); if (headsUpEntry == null) { // This should not happen since shouldHeadsUpBecomePinned is always called after adding @@ -392,10 +586,6 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { } } - public @InflationFlag int getContentFlag() { - return FLAG_CONTENT_VIEW_HEADS_UP; - } - /** * Manager-specific logic that should occur when an entry is added. * @param headsUpEntry entry added @@ -410,6 +600,8 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { for (OnHeadsUpChangedListener listener : mListeners) { listener.onHeadsUpStateChanged(entry, true); } + updateTopHeadsUpFlow(); + updateHeadsUpFlow(); } /** @@ -466,11 +658,60 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { for (OnHeadsUpChangedListener listener : mListeners) { listener.onHeadsUpStateChanged(entry, false); } + if (!NotificationThrottleHun.isEnabled()) { + mEntryPool.release(headsUpEntry); + } + updateTopHeadsUpFlow(); + updateHeadsUpFlow(); + if (NotificationThrottleHun.isEnabled()) { + if (headsUpEntry.mEntry != null) { + if (mEntriesToRemoveWhenReorderingAllowed.contains(headsUpEntry.mEntry)) { + mEntriesToRemoveWhenReorderingAllowed.remove(headsUpEntry.mEntry); + } + } + } + } + + private void updateTopHeadsUpFlow() { + mTopHeadsUpRow.setValue((HeadsUpRowRepository) getTopHeadsUpEntry()); + } + + private void updateHeadsUpFlow() { + mHeadsUpNotificationRows.setValue(new HashSet<>(getHeadsUpEntryPhoneMap().values())); + } + + @Override + @NonNull + public Flow<HeadsUpRowRepository> getTopHeadsUpRow() { + return mTopHeadsUpRow; + } + + @Override + @NonNull + public Flow<Set<HeadsUpRowRepository>> getActiveHeadsUpRows() { + return mHeadsUpNotificationRows; + } + + @Override + @NonNull + public StateFlow<Boolean> isHeadsUpAnimatingAway() { + return mHeadsUpAnimatingAway; + } + + @Override + public boolean isHeadsUpAnimatingAwayValue() { + return mHeadsUpAnimatingAway.getValue(); + } + + @NonNull + private ArrayMap<String, HeadsUpEntry> getHeadsUpEntryPhoneMap() { + return mHeadsUpEntryMap; } /** * Called to notify the listeners that the HUN animating away animation has ended. */ + @Override public void onEntryAnimatingAwayEnded(@NonNull NotificationEntry entry) { for (OnHeadsUpChangedListener listener : mListeners) { listener.onHeadsUpAnimatingAwayEnded(entry); @@ -484,6 +725,8 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { * @param headsUpEntry entry updated */ protected void onEntryUpdated(HeadsUpEntry headsUpEntry) { + // no need to update the list here + updateTopHeadsUpFlow(); } protected void updatePinnedMode() { @@ -521,6 +764,7 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { /** * Snoozes all current Heads Up Notifications. */ + @Override public void snooze() { List<String> keySet = new ArrayList<>(mHeadsUpEntryMap.keySet()); keySet.addAll(mAvalancheController.getWaitingKeys()); @@ -534,6 +778,7 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { mLogger.logPackageSnoozed(snoozeKey); mSnoozedPackages.put(snoozeKey, mSystemClock.elapsedRealtime() + mSnoozeLengthMs); } + mReleaseOnExpandFinish = true; } @NonNull @@ -541,6 +786,11 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { return user + "," + packageName; } + @Override + public void addSwipedOutNotification(@NonNull String key) { + mSwipedOutKeys.add(key); + } + @Nullable protected HeadsUpEntry getHeadsUpEntry(@NonNull String key) { if (mHeadsUpEntryMap.containsKey(key)) { @@ -597,6 +847,59 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { } @Override + public @Nullable Region getTouchableRegion() { + NotificationEntry topEntry = getTopEntry(); + + // This call could be made in an inconsistent state while the pinnedMode hasn't been + // updated yet, but callbacks leading out of the headsUp manager, querying it. Let's + // therefore also check if the topEntry is null. + if (!hasPinnedHeadsUp() || topEntry == null) { + return null; + } else { + if (topEntry.rowIsChildInGroup()) { + final NotificationEntry groupSummary = + mGroupMembershipManager.getGroupSummary(topEntry); + if (groupSummary != null) { + topEntry = groupSummary; + } + } + ExpandableNotificationRow topRow = topEntry.getRow(); + int[] tmpArray = new int[2]; + topRow.getLocationOnScreen(tmpArray); + int minX = tmpArray[0]; + int maxX = tmpArray[0] + topRow.getWidth(); + int height = topRow.getIntrinsicHeight(); + final boolean stretchToTop = tmpArray[1] <= mHeadsUpInset; + mTouchableRegion.set(minX, stretchToTop ? 0 : tmpArray[1], maxX, tmpArray[1] + height); + return mTouchableRegion; + } + } + + @Override + public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) { + if (headsUpAnimatingAway != mHeadsUpAnimatingAway.getValue()) { + for (OnHeadsUpPhoneListenerChange listener : mHeadsUpPhoneListeners) { + listener.onHeadsUpAnimatingAwayStateChanged(headsUpAnimatingAway); + } + mHeadsUpAnimatingAway.setValue(headsUpAnimatingAway); + } + } + + private void onShadeOrQsExpanded(Boolean isExpanded) { + if (isExpanded != mIsShadeOrQsExpanded) { + mIsShadeOrQsExpanded = isExpanded; + if (!SceneContainerFlag.isEnabled() && isExpanded) { + mHeadsUpAnimatingAway.setValue(false); + } + } + } + + private void onQsExpanded(Boolean isQsExpanded) { + if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return; + if (isQsExpanded != mIsQsExpanded) mIsQsExpanded = isQsExpanded; + } + + @Override public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { pw.println("HeadsUpManager state:"); dumpInternal(pw, args); @@ -616,6 +919,10 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { pw.print(" "); pw.print(mSnoozedPackages.valueAt(i)); pw.print(", "); pw.println(mSnoozedPackages.keyAt(i)); } + pw.print(" mBarState="); + pw.println(mStatusBarState); + pw.print(" mTouchableRegion="); + pw.println(mTouchableRegion); } /** @@ -639,6 +946,7 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { * Unpins all pinned Heads Up Notifications. * @param userUnPinned The unpinned action is trigger by user real operation. */ + @Override public void unpinAll(boolean userUnPinned) { for (String key : mHeadsUpEntryMap.keySet()) { HeadsUpEntry headsUpEntry = getHeadsUpEntry(key); @@ -662,13 +970,59 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { } } - /** - * Returns the value of the tracking-heads-up flag. See the doc of {@code setTrackingHeadsUp} as - * well. - */ + @Override + public void setRemoteInputActive( + @NonNull NotificationEntry entry, boolean remoteInputActive) { + HeadsUpEntry headsUpEntry = getHeadsUpEntryPhone(entry.getKey()); + if (headsUpEntry != null && headsUpEntry.mRemoteInputActive != remoteInputActive) { + headsUpEntry.mRemoteInputActive = remoteInputActive; + if (ExpandHeadsUpOnInlineReply.isEnabled() && remoteInputActive) { + headsUpEntry.mRemoteInputActivatedAtLeastOnce = true; + } + if (remoteInputActive) { + headsUpEntry.cancelAutoRemovalCallbacks("setRemoteInputActive(true)"); + } else { + headsUpEntry.updateEntry(false /* updatePostTime */, "setRemoteInputActive(false)"); + } + onEntryUpdated(headsUpEntry); + } + } + + @Nullable + private HeadsUpEntry getHeadsUpEntryPhone(@NonNull String key) { + return mHeadsUpEntryMap.get(key); + } + + @Override + public void setGutsShown(@NonNull NotificationEntry entry, boolean gutsShown) { + HeadsUpEntry headsUpEntry = getHeadsUpEntry(entry.getKey()); + if (headsUpEntry == null) return; + if (entry.isRowPinned() || !gutsShown) { + headsUpEntry.setGutsShownPinned(gutsShown); + } + } + + @Override + public void extendHeadsUp() { + HeadsUpEntry topEntry = getTopHeadsUpEntryPhone(); + if (topEntry == null) { + return; + } + topEntry.extendPulse(); + } + + @Nullable + private HeadsUpEntry getTopHeadsUpEntryPhone() { + if (SceneContainerFlag.isEnabled()) { + return (HeadsUpEntry) mTopHeadsUpRow.getValue(); + } else { + return getTopHeadsUpEntry(); + } + } + + @Override public boolean isTrackingHeadsUp() { - // Might be implemented in subclass. - return false; + return mTrackingHeadsUp; } /** @@ -724,11 +1078,23 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { */ @Override public boolean canRemoveImmediately(@NonNull String key) { - HeadsUpEntry headsUpEntry = getHeadsUpEntry(key); - if (headsUpEntry != null && headsUpEntry.mUserActionMayIndirectlyRemove) { + if (mSwipedOutKeys.contains(key)) { + // We always instantly dismiss views being manually swiped out. + mSwipedOutKeys.remove(key); + return true; + } + + HeadsUpEntry headsUpEntry = getHeadsUpEntryPhone(key); + HeadsUpEntry topEntry = getTopHeadsUpEntryPhone(); + + if (headsUpEntry == null || headsUpEntry != topEntry) { return true; } - return headsUpEntry == null || headsUpEntry.wasShownLongEnough() + + if (headsUpEntry.mUserActionMayIndirectlyRemove) { + return true; + } + return headsUpEntry.wasShownLongEnough() || (headsUpEntry.mEntry != null && headsUpEntry.mEntry.isRowDismissed()); } @@ -747,7 +1113,13 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { @NonNull protected HeadsUpEntry createHeadsUpEntry(NotificationEntry entry) { - return new HeadsUpEntry(entry); + if (NotificationThrottleHun.isEnabled()) { + return new HeadsUpEntry(entry); + } else { + HeadsUpEntry headsUpEntry = mEntryPool.acquire(); + headsUpEntry.setEntry(entry); + return headsUpEntry; + } } /** @@ -763,12 +1135,79 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { && Notification.CATEGORY_CALL.equals(n.category)); } + private final OnReorderingAllowedListener mOnReorderingAllowedListener = () -> { + if (NotificationThrottleHun.isEnabled()) { + mAvalancheController.setEnableAtRuntime(true); + if (mEntriesToRemoveWhenReorderingAllowed.isEmpty()) { + return; + } + } + mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(false); + for (NotificationEntry entry : mEntriesToRemoveWhenReorderingAllowed) { + if (entry != null && isHeadsUpEntry(entry.getKey())) { + // Maybe the heads-up was removed already + removeEntry(entry.getKey(), "mOnReorderingAllowedListener"); + } + } + mEntriesToRemoveWhenReorderingAllowed.clear(); + mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(true); + }; + + private final OnReorderingBannedListener mOnReorderingBannedListener = () -> { + if (mAvalancheController != null) { + // In open shade the first HUN is pinned, and visual stability logic prevents us from + // unpinning this first HUN as long as the shade remains open. AvalancheController only + // shows the next HUN when the currently showing HUN is unpinned, so we must disable + // throttling here so that the incoming HUN stream is not forever paused. This is reset + // when reorder becomes allowed. + mAvalancheController.setEnableAtRuntime(false); + + // Note that we cannot do the above when + // 1) The remove runnable runs because its delay means it may not run before shade close + // 2) Reordering is allowed again (when shade closes) because the HUN appear animation + // will have started by then + } + }; + + private final StatusBarStateController.StateListener + mStatusBarStateListener = new StatusBarStateController.StateListener() { + @Override + public void onStateChanged(int newState) { + boolean wasKeyguard = mStatusBarState == StatusBarState.KEYGUARD; + boolean isKeyguard = newState == StatusBarState.KEYGUARD; + mStatusBarState = newState; + + if (wasKeyguard && !isKeyguard && mBypassController.getBypassEnabled()) { + ArrayList<String> keysToRemove = new ArrayList<>(); + for (HeadsUpEntry entry : getHeadsUpEntryList()) { + if (entry.mEntry != null && entry.mEntry.isBubble() && !entry.isSticky()) { + keysToRemove.add(entry.mEntry.getKey()); + } + } + for (String key : keysToRemove) { + removeEntry(key, "mStatusBarStateListener"); + } + } + } + + @Override + public void onDozingChanged(boolean isDozing) { + if (!isDozing) { + // Let's make sure all huns we got while dozing time out within the normal timeout + // duration. Otherwise they could get stuck for a very long time + for (HeadsUpEntry entry : getHeadsUpEntryList()) { + entry.updateEntry(true /* updatePostTime */, "onDozingChanged(false)"); + } + } + } + }; + /** * This represents a notification and how long it is in a heads up mode. It also manages its * lifecycle automatically when created. This class is public because it is exposed by methods * of AvalancheController that take it as param. */ - public class HeadsUpEntry implements Comparable<HeadsUpEntry> { + public class HeadsUpEntry implements Comparable<HeadsUpEntry>, HeadsUpRowRepository { public boolean mRemoteInputActivatedAtLeastOnce; public boolean mRemoteInputActive; public boolean mUserActionMayIndirectlyRemove; @@ -784,6 +1223,14 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { @Nullable private Runnable mCancelRemoveRunnable; + private boolean mGutsShownPinned; + private final MutableStateFlow<Boolean> mIsPinned = StateFlowKt.MutableStateFlow(false); + + /** + * If the time this entry has been on was extended + */ + private boolean extended; + public HeadsUpEntry() { NotificationThrottleHun.assertInLegacyMode(); } @@ -794,19 +1241,50 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { setEntry(entry, createRemoveRunnable(entry)); } + @Override + @NonNull + public String getKey() { + return requireEntry().getKey(); + } + + @Override + @NonNull + public Object getElementKey() { + return requireEntry().getRow(); + } + + private NotificationEntry requireEntry() { + /* check if */ SceneContainerFlag.isUnexpectedlyInLegacyMode(); + return Objects.requireNonNull(mEntry); + } + + @Override + @NonNull + public StateFlow<Boolean> isPinned() { + return mIsPinned; + } + /** Attach a NotificationEntry. */ public void setEntry(@NonNull final NotificationEntry entry) { NotificationThrottleHun.assertInLegacyMode(); setEntry(entry, createRemoveRunnable(entry)); } - protected void setEntry(@NonNull final NotificationEntry entry, + protected void setEntry( + @NonNull final NotificationEntry entry, @Nullable Runnable removeRunnable) { mEntry = entry; mRemoveRunnable = removeRunnable; mPostTime = calculatePostTime(); updateEntry(true /* updatePostTime */, "setEntry"); + + if (NotificationThrottleHun.isEnabled()) { + mEntriesToRemoveWhenReorderingAllowed.add(entry); + if (!mVisualStabilityProvider.isReorderingAllowed()) { + entry.setSeenInShade(true); + } + } } protected boolean isRowPinned() { @@ -815,6 +1293,7 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { protected void setRowPinned(boolean pinned) { if (mEntry != null) mEntry.setRowPinned(pinned); + mIsPinned.setValue(pinned); } /** @@ -870,6 +1349,22 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { // Notify the manager, that the posted time has changed. onEntryUpdated(this); + + if (mEntriesToRemoveAfterExpand.contains(mEntry)) { + mEntriesToRemoveAfterExpand.remove(mEntry); + } + if (!NotificationThrottleHun.isEnabled()) { + if (mEntriesToRemoveWhenReorderingAllowed.contains(mEntry)) { + mEntriesToRemoveWhenReorderingAllowed.remove(mEntry); + } + } + } + + private void extendPulse() { + if (!extended) { + extended = true; + updateEntry(false, "extendPulse()"); + } } /** @@ -878,6 +1373,8 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { * @return true if the notification is sticky */ public boolean isSticky() { + if (mGutsShownPinned) return true; + if (mEntry == null) return false; if (ExpandHeadsUpOnInlineReply.isEnabled()) { @@ -989,7 +1486,29 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { } public void setExpanded(boolean expanded) { + if (this.mExpanded == expanded) { + return; + } + this.mExpanded = expanded; + if (expanded) { + cancelAutoRemovalCallbacks("setExpanded(true)"); + } else { + updateEntry(false /* updatePostTime */, "setExpanded(false)"); + } + } + + public void setGutsShownPinned(boolean gutsShownPinned) { + if (mGutsShownPinned == gutsShownPinned) { + return; + } + + mGutsShownPinned = gutsShownPinned; + if (gutsShownPinned) { + cancelAutoRemovalCallbacks("setGutsShownPinned(true)"); + } else { + updateEntry(false /* updatePostTime */, "setGutsShownPinned(false)"); + } } public void reset() { @@ -999,6 +1518,8 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { mRemoveRunnable = null; mExpanded = false; mRemoteInputActive = false; + mGutsShownPinned = false; + extended = false; } /** @@ -1074,7 +1595,23 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { /** Creates a runnable to remove this notification from the alerting entries. */ protected Runnable createRemoveRunnable(NotificationEntry entry) { - return () -> removeEntry(entry.getKey(), "createRemoveRunnable"); + return () -> { + if (!NotificationThrottleHun.isEnabled() + && !mVisualStabilityProvider.isReorderingAllowed() + // We don't want to allow reordering while pulsing, but headsup need to + // time out anyway + && !entry.showingPulsing()) { + mEntriesToRemoveWhenReorderingAllowed.add(entry); + mVisualStabilityProvider.addTemporaryReorderingAllowedListener( + mOnReorderingAllowedListener); + } else if (mTrackingHeadsUp) { + mEntriesToRemoveAfterExpand.add(entry); + mLogger.logRemoveEntryAfterExpand(entry); + } else if (mVisualStabilityProvider.isReorderingAllowed() + || entry.showingPulsing()) { + removeEntry(entry.getKey(), "createRemoveRunnable"); + } + }; } /** @@ -1098,7 +1635,7 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { requestedTimeOutMs = mAvalancheController.getDurationMs(this, mAutoDismissTime); } final long duration = getRecommendedHeadsUpTimeoutMs(requestedTimeOutMs); - return mPostTime + duration; + return mPostTime + duration + (extended ? mExtensionTime : 0); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt index 04fe6b3e9eb7..b37194b8b7a0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt @@ -59,6 +59,7 @@ interface HeadsUpManager : Dumpable { * Gets the touchable region needed for heads up notifications. Returns null if no touchable * region is required (ie: no heads up notification currently exists). */ + // TODO(b/347007367): With scene container enabled this method may report outdated regions fun getTouchableRegion(): Region? /** @@ -83,6 +84,10 @@ interface HeadsUpManager : Dumpable { /** Returns whether the entry is (pinned and expanded) or (has an active remote input). */ fun isSticky(key: String?): Boolean + /** + * Returns the value of the tracking-heads-up flag. See the doc of {@code setTrackingHeadsUp} as + * well. + */ fun isTrackingHeadsUp(): Boolean fun onExpandingFinished() @@ -115,7 +120,7 @@ interface HeadsUpManager : Dumpable { key: String, releaseImmediately: Boolean, animate: Boolean, - reason: String + reason: String, ): Boolean /** Clears all managed notifications. */ @@ -149,6 +154,10 @@ interface HeadsUpManager : Dumpable { */ fun setRemoteInputActive(entry: NotificationEntry, remoteInputActive: Boolean) + /** + * Sets the tracking-heads-up flag. If the flag is true, HeadsUpManager doesn't remove the entry + * from the list even after a Heads Up Notification is gone. + */ fun setTrackingHeadsUp(tracking: Boolean) /** Sets the current user. */ @@ -260,7 +269,7 @@ class HeadsUpManagerEmptyImpl @Inject constructor() : HeadsUpManager { key: String, releaseImmediately: Boolean, animate: Boolean, - reason: String + reason: String, ) = false override fun setAnimationStateHandler(handler: AnimationStateHandler) {} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java deleted file mode 100644 index 0d36b48e9099..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.statusbar.policy; - -import android.app.ActivityManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.UserHandle; -import android.text.format.DateFormat; -import android.util.AttributeSet; -import android.widget.LinearLayout; -import android.widget.TextClock; - -import com.android.systemui.res.R; - -/** - * Container for a clock which has two separate views for the clock itself and AM/PM indicator. This - * is used to scale the clock independently of AM/PM. - */ -public class SplitClockView extends LinearLayout { - - private TextClock mTimeView; - private TextClock mAmPmView; - - private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - if (Intent.ACTION_TIME_CHANGED.equals(action) - || Intent.ACTION_TIMEZONE_CHANGED.equals(action) - || Intent.ACTION_LOCALE_CHANGED.equals(action) - || Intent.ACTION_CONFIGURATION_CHANGED.equals(action) - || Intent.ACTION_USER_SWITCHED.equals(action)) { - updatePatterns(); - } - } - }; - - public SplitClockView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - mTimeView = findViewById(R.id.time_view); - mAmPmView = findViewById(R.id.am_pm_view); - mTimeView.setShowCurrentUserTime(true); - mAmPmView.setShowCurrentUserTime(true); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_TIME_CHANGED); - filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); - filter.addAction(Intent.ACTION_LOCALE_CHANGED); - filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); - filter.addAction(Intent.ACTION_USER_SWITCHED); - getContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter, null, null); - - updatePatterns(); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - getContext().unregisterReceiver(mIntentReceiver); - } - - private void updatePatterns() { - String formatString = DateFormat.getTimeFormatString(getContext(), - ActivityManager.getCurrentUser()); - int index = getAmPmPartEndIndex(formatString); - String timeString; - String amPmString; - if (index == -1) { - timeString = formatString; - amPmString = ""; - } else { - timeString = formatString.substring(0, index); - amPmString = formatString.substring(index); - } - mTimeView.setFormat12Hour(timeString); - mTimeView.setFormat24Hour(timeString); - mTimeView.setContentDescriptionFormat12Hour(formatString); - mTimeView.setContentDescriptionFormat24Hour(formatString); - mAmPmView.setFormat12Hour(amPmString); - mAmPmView.setFormat24Hour(amPmString); - } - - /** - * @return the index where the AM/PM part starts at the end in {@code formatString} including - * leading white spaces or {@code -1} if no AM/PM part is found or {@code formatString} - * doesn't end with AM/PM part - */ - private static int getAmPmPartEndIndex(String formatString) { - boolean hasAmPm = false; - int length = formatString.length(); - for (int i = length - 1; i >= 0; i--) { - char c = formatString.charAt(i); - boolean isAmPm = c == 'a'; - boolean isWhitespace = Character.isWhitespace(c); - if (isAmPm) { - hasAmPm = true; - } - if (isAmPm || isWhitespace) { - continue; - } - if (i == length - 1) { - - // First character was not AM/PM and not whitespace, so it's not ending with AM/PM. - return -1; - } else { - - // If we have AM/PM at all, return last index, or -1 to indicate that it's not - // ending with AM/PM. - return hasAmPm ? i + 1 : -1; - } - } - - // Only AM/PM and whitespaces? The whole string is AM/PM. Else: Only whitespaces in the - // string. - return hasAmPm ? 0 : -1; - } - -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModeTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModeTileViewModel.kt index abd24533e1c4..238e56a1785f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModeTileViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModeTileViewModel.kt @@ -28,7 +28,7 @@ data class ModeTileViewModel( val icon: Icon, val text: String, val subtext: String, - val subtextDescription: String, // version of subtext without "on"/"off" for screen readers + val subtextDescription: String, // version of subtext (without "on"/"off") for screen readers val enabled: Boolean, val stateDescription: String, // "on"/"off" state of the tile, for screen readers val onClick: () -> Unit, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt index 4f595ed152e4..1c13a833ef30 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt @@ -23,6 +23,7 @@ import android.provider.Settings.ACTION_AUTOMATIC_ZEN_RULE_SETTINGS import android.provider.Settings.EXTRA_AUTOMATIC_ZEN_RULE_ID import com.android.settingslib.notification.modes.EnableZenModeDialog import com.android.settingslib.notification.modes.ZenMode +import com.android.settingslib.notification.modes.ZenModeDescriptions import com.android.systemui.common.shared.model.asIcon import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background @@ -54,6 +55,7 @@ constructor( private val dialogEventLogger: ModesDialogEventLogger, ) { private val zenDialogMetricsLogger = QSZenModeDialogMetricsLogger(context) + private val zenModeDescriptions = ZenModeDescriptions(context) // Modes that should be displayed in the dialog private val visibleModes: Flow<List<ZenMode>> = @@ -92,7 +94,8 @@ constructor( icon = zenModeInteractor.getModeIcon(mode).drawable().asIcon(), text = mode.name, subtext = getTileSubtext(mode), - subtextDescription = getModeDescription(mode) ?: "", + subtextDescription = + getModeDescription(mode, forAccessibility = true) ?: "", enabled = mode.isActive, stateDescription = context.getString( @@ -145,18 +148,21 @@ constructor( * This description is used directly for the content description of a mode tile for screen * readers, and for the tile subtext will be augmented with the current status of the mode. */ - private fun getModeDescription(mode: ZenMode): String? { + private fun getModeDescription(mode: ZenMode, forAccessibility: Boolean): String? { if (!mode.rule.isEnabled) { return context.resources.getString(R.string.zen_mode_set_up) } if (!mode.rule.isManualInvocationAllowed && !mode.isActive) { return context.resources.getString(R.string.zen_mode_no_manual_invocation) } - return mode.getDynamicDescription(context) + return if (forAccessibility) + zenModeDescriptions.getTriggerDescriptionForAccessibility(mode) + ?: zenModeDescriptions.getTriggerDescription(mode) + else zenModeDescriptions.getTriggerDescription(mode) } private fun getTileSubtext(mode: ZenMode): String { - val modeDescription = getModeDescription(mode) + val modeDescription = getModeDescription(mode, forAccessibility = false) return if (mode.isActive) { if (modeDescription != null) { context.getString(R.string.zen_mode_on_with_details, modeDescription) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowView.java index b79d39e65682..36d64a9b405e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowView.java @@ -39,7 +39,7 @@ import com.android.systemui.statusbar.core.StatusBarRootModernization; import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController; /** - * Status bar view. + * Status bar view * We now extend WindowRootView so that we can host Compose views */ public class StatusBarWindowView extends FrameLayout { diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt index 3c0682822564..2a9b1b97b48f 100644 --- a/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt +++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt @@ -22,6 +22,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Tracing import com.android.systemui.dagger.qualifiers.UiBackground +import com.android.systemui.util.settings.SettingsSingleThreadBackground import dagger.Module import dagger.Provides import kotlinx.coroutines.CoroutineDispatcher diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepository.kt index 49a0f14d6b3b..af03c529cb52 100644 --- a/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSettingsRepository.kt @@ -85,6 +85,12 @@ abstract class UserAwareSettingsRepository( } } + suspend fun setBoolean(name: String, value: Boolean) { + withContext(bgContext) { + userSettings.putBoolForUser(name, value, userRepository.getSelectedUserInfo().id) + } + } + suspend fun getString(name: String): String? { return withContext(bgContext) { userSettings.getStringForUser(name, userRepository.getSelectedUserInfo().id) diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt index 2ff8cbcf34ae..5bf15137b834 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt @@ -78,8 +78,7 @@ class DeviceItemFactoryTest : SysuiTestCase() { fun testAvailableMediaDeviceItemFactory_createFromCachedDevice() { `when`(cachedDevice.name).thenReturn(DEVICE_NAME) `when`(cachedDevice.connectionSummary).thenReturn(CONNECTION_SUMMARY) - `when`(BluetoothUtils.getBtClassDrawableWithDescription(any(), any())) - .thenReturn(Pair.create(drawable, "")) + `when`(cachedDevice.drawableWithDescription).thenReturn(Pair.create(drawable, "")) val deviceItem = availableMediaDeviceItemFactory.create(context, cachedDevice) assertDeviceItem(deviceItem, DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE) @@ -89,8 +88,7 @@ class DeviceItemFactoryTest : SysuiTestCase() { fun testConnectedDeviceItemFactory_createFromCachedDevice() { `when`(cachedDevice.name).thenReturn(DEVICE_NAME) `when`(cachedDevice.connectionSummary).thenReturn(CONNECTION_SUMMARY) - `when`(BluetoothUtils.getBtClassDrawableWithDescription(any(), any())) - .thenReturn(Pair.create(drawable, "")) + `when`(cachedDevice.drawableWithDescription).thenReturn(Pair.create(drawable, "")) val deviceItem = connectedDeviceItemFactory.create(context, cachedDevice) assertDeviceItem(deviceItem, DeviceItemType.CONNECTED_BLUETOOTH_DEVICE) @@ -100,8 +98,7 @@ class DeviceItemFactoryTest : SysuiTestCase() { fun testSavedDeviceItemFactory_createFromCachedDevice() { `when`(cachedDevice.name).thenReturn(DEVICE_NAME) `when`(cachedDevice.connectionSummary).thenReturn(CONNECTION_SUMMARY) - `when`(BluetoothUtils.getBtClassDrawableWithDescription(any(), any())) - .thenReturn(Pair.create(drawable, "")) + `when`(cachedDevice.drawableWithDescription).thenReturn(Pair.create(drawable, "")) val deviceItem = savedDeviceItemFactory.create(context, cachedDevice) assertDeviceItem(deviceItem, DeviceItemType.SAVED_BLUETOOTH_DEVICE) @@ -111,8 +108,7 @@ class DeviceItemFactoryTest : SysuiTestCase() { @Test fun testAvailableAudioSharingMediaDeviceItemFactory_createFromCachedDevice() { `when`(cachedDevice.name).thenReturn(DEVICE_NAME) - `when`(BluetoothUtils.getBtClassDrawableWithDescription(any(), any())) - .thenReturn(Pair.create(drawable, "")) + `when`(cachedDevice.drawableWithDescription).thenReturn(Pair.create(drawable, "")) val deviceItem = AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager) .create(context, cachedDevice) diff --git a/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderContentProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderContentProviderTest.kt new file mode 100644 index 000000000000..8d9fa6ad6e08 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/graphics/ImageLoaderContentProviderTest.kt @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.graphics + +import android.content.ContentProvider +import android.content.ContentValues +import android.content.Context +import android.database.Cursor +import android.net.Uri +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import androidx.test.rule.provider.ProviderTestRule +import com.android.systemui.SysuiTestCase +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +const val AUTHORITY = "exception.provider.authority" +val TEST_URI = Uri.Builder().scheme("content").authority(AUTHORITY).path("path").build() + +@SmallTest +@kotlinx.coroutines.ExperimentalCoroutinesApi +@RunWith(AndroidJUnit4::class) +class ImageLoaderContentProviderTest : SysuiTestCase() { + + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + private val mockContext = mock<Context>() + private lateinit var imageLoader: ImageLoader + + @Rule + @JvmField + @Suppress("DEPRECATION") + public val providerTestRule = + ProviderTestRule.Builder(ExceptionThrowingContentProvider::class.java, AUTHORITY).build() + + @Before + fun setUp() { + whenever(mockContext.contentResolver).thenReturn(providerTestRule.resolver) + imageLoader = ImageLoader(mockContext, kosmos.testDispatcher) + } + + @Test(expected = IllegalArgumentException::class) + fun loadFromTestContentProvider_throwsException() { + // This checks if the resolution actually throws the exception from test provider. + mockContext.contentResolver.query(TEST_URI, null, null, null) + } + + @Test + fun loadFromRuntimeExceptionThrowingProvider_returnsNull() = + testScope.runTest { assertThat(imageLoader.loadBitmap(ImageLoader.Uri(TEST_URI))).isNull() } +} + +class ExceptionThrowingContentProvider : ContentProvider() { + override fun query( + uri: Uri, + projection: Array<out String>?, + selection: String?, + selectionArgs: Array<out String>?, + sortOrder: String?, + ): Cursor? { + throw IllegalArgumentException("Test exception") + } + + override fun getType(uri: Uri): String? { + throw IllegalArgumentException("Test exception") + } + + override fun insert(uri: Uri, values: ContentValues?): Uri? { + throw IllegalArgumentException("Test exception") + } + + override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int { + throw IllegalArgumentException("Test exception") + } + + override fun update( + uri: Uri, + values: ContentValues?, + selection: String?, + selectionArgs: Array<out String>?, + ): Int { + throw IllegalArgumentException("Test exception") + } + + override fun onCreate(): Boolean = true +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt new file mode 100644 index 000000000000..f8d848139039 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyboard.shortcut.ui.viewmodel + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType +import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo +import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey +import com.android.systemui.keyboard.shortcut.shortcutCustomizationViewModelFactory +import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testScope +import com.android.systemui.res.R +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidJUnit4::class) +class ShortcutCustomizationViewModelTest : SysuiTestCase() { + + private val kosmos = Kosmos() + private val testScope = kosmos.testScope + private val viewModel = kosmos.shortcutCustomizationViewModelFactory.create() + + @Test + fun uiState_inactiveByDefault() { + testScope.runTest { + val uiState by collectLastValue(viewModel.shortcutCustomizationUiState) + + assertThat(uiState).isEqualTo(ShortcutCustomizationUiState.Inactive) + } + } + + @Test + fun uiState_correctlyUpdatedWhenAddShortcutCustomizationIsRequested() { + testScope.runTest { + viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest) + val uiState by collectLastValue(viewModel.shortcutCustomizationUiState) + + assertThat(uiState).isEqualTo(expectedStandardAddShortcutUiState) + } + } + + @Test + fun uiState_consumedOnAddDialogShown() { + testScope.runTest { + val uiState by collectLastValue(viewModel.shortcutCustomizationUiState) + viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest) + viewModel.onAddShortcutDialogShown() + + assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).isDialogShowing) + .isTrue() + } + } + + @Test + fun uiState_inactiveAfterDialogIsDismissed() { + testScope.runTest { + val uiState by collectLastValue(viewModel.shortcutCustomizationUiState) + viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest) + viewModel.onAddShortcutDialogShown() + viewModel.onAddShortcutDialogDismissed() + assertThat(uiState).isEqualTo(ShortcutCustomizationUiState.Inactive) + } + } + + private val standardAddShortcutRequest = + ShortcutCustomizationRequestInfo.Add( + label = "Standard shortcut", + categoryType = ShortcutCategoryType.System, + subCategoryLabel = "Standard subcategory", + ) + + private val expectedStandardAddShortcutUiState = + ShortcutCustomizationUiState.AddShortcutDialog( + shortcutLabel = "Standard shortcut", + shouldShowErrorMessage = false, + isValidKeyCombination = false, + defaultCustomShortcutModifierKey = + ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta), + isDialogShowing = false, + ) +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt index e1845a17a767..7e85dd5d3236 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt @@ -213,7 +213,7 @@ class KeyguardBottomAreaViewModelTest(flags: FlagsParameterization) : SysuiTestC ) val keyguardTouchHandlingInteractor = KeyguardTouchHandlingInteractor( - appContext = mContext, + context = mContext, scope = testScope.backgroundScope, transitionInteractor = kosmos.keyguardTransitionInteractor, repository = repository, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt index e72109d4d8e3..a3c518128b47 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt @@ -27,16 +27,15 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderListListener import com.android.systemui.statusbar.notification.collection.render.NotifStackController -import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.withArgCaptor import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.Mockito.verify -import org.mockito.Mockito.verifyNoMoreInteractions -import org.mockito.MockitoAnnotations.initMocks +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.verifyNoMoreInteractions @SmallTest @RunWith(AndroidJUnit4::class) @@ -47,14 +46,13 @@ class DataStoreCoordinatorTest : SysuiTestCase() { private lateinit var entry: NotificationEntry - @Mock private lateinit var pipeline: NotifPipeline - @Mock private lateinit var notifLiveDataStoreImpl: NotifLiveDataStoreImpl - @Mock private lateinit var stackController: NotifStackController - @Mock private lateinit var section: NotifSection + private val pipeline: NotifPipeline = mock() + private val notifLiveDataStoreImpl: NotifLiveDataStoreImpl = mock() + private val stackController: NotifStackController = mock() + private val section: NotifSection = mock() @Before fun setUp() { - initMocks(this) entry = NotificationEntryBuilder().setSection(section).build() coordinator = DataStoreCoordinator(notifLiveDataStoreImpl) coordinator.attach(pipeline) @@ -76,31 +74,35 @@ class DataStoreCoordinatorTest : SysuiTestCase() { listOf( notificationEntry("foo", 1), notificationEntry("foo", 2), - GroupEntryBuilder().setSummary( - notificationEntry("bar", 1) - ).setChildren( - listOf( - notificationEntry("bar", 2), - notificationEntry("bar", 3), - notificationEntry("bar", 4) + GroupEntryBuilder() + .setSummary(notificationEntry("bar", 1)) + .setChildren( + listOf( + notificationEntry("bar", 2), + notificationEntry("bar", 3), + notificationEntry("bar", 4), + ) ) - ).setSection(section).build(), - notificationEntry("baz", 1) + .setSection(section) + .build(), + notificationEntry("baz", 1), ), - stackController + stackController, ) val list: List<NotificationEntry> = withArgCaptor { verify(notifLiveDataStoreImpl).setActiveNotifList(capture()) } - assertThat(list.map { it.key }).containsExactly( - "0|foo|1|null|0", - "0|foo|2|null|0", - "0|bar|1|null|0", - "0|bar|2|null|0", - "0|bar|3|null|0", - "0|bar|4|null|0", - "0|baz|1|null|0" - ).inOrder() + assertThat(list.map { it.key }) + .containsExactly( + "0|foo|1|null|0", + "0|foo|2|null|0", + "0|bar|1|null|0", + "0|bar|2|null|0", + "0|bar|3|null|0", + "0|bar|4|null|0", + "0|baz|1|null|0", + ) + .inOrder() verifyNoMoreInteractions(notifLiveDataStoreImpl) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt index 56b70bde2cca..2c37f510a45c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt @@ -38,41 +38,37 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController -import com.android.systemui.util.mockito.eq -import com.android.systemui.util.mockito.withArgCaptor import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.Mockito.verify -import org.mockito.Mockito.verifyNoMoreInteractions -import org.mockito.MockitoAnnotations.initMocks -import org.mockito.Mockito.`when` as whenever +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.eq +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.verifyNoMoreInteractions +import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) @RunWithLooper class StackCoordinatorTest : SysuiTestCase() { + private lateinit var entry: NotificationEntry private lateinit var coordinator: StackCoordinator private lateinit var afterRenderListListener: OnAfterRenderListListener - private lateinit var entry: NotificationEntry - - @Mock private lateinit var pipeline: NotifPipeline - @Mock private lateinit var groupExpansionManagerImpl: GroupExpansionManagerImpl - @Mock private lateinit var renderListInteractor: RenderNotificationListInteractor - @Mock private lateinit var activeNotificationsInteractor: ActiveNotificationsInteractor - @Mock - private lateinit var sensitiveNotificationProtectionController: - SensitiveNotificationProtectionController - @Mock private lateinit var stackController: NotifStackController - @Mock private lateinit var section: NotifSection - @Mock private lateinit var row: ExpandableNotificationRow + private val pipeline: NotifPipeline = mock() + private val groupExpansionManagerImpl: GroupExpansionManagerImpl = mock() + private val renderListInteractor: RenderNotificationListInteractor = mock() + private val activeNotificationsInteractor: ActiveNotificationsInteractor = mock() + private val sensitiveNotificationProtectionController: + SensitiveNotificationProtectionController = + mock() + private val stackController: NotifStackController = mock() + private val section: NotifSection = mock() + private val row: ExpandableNotificationRow = mock() @Before fun setUp() { - initMocks(this) - whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(false) entry = NotificationEntryBuilder().setSection(section).build() @@ -86,9 +82,9 @@ class StackCoordinatorTest : SysuiTestCase() { sensitiveNotificationProtectionController, ) coordinator.attach(pipeline) - afterRenderListListener = withArgCaptor { - verify(pipeline).addOnAfterRenderListListener(capture()) - } + val captor = argumentCaptor<OnAfterRenderListListener>() + verify(pipeline).addOnAfterRenderListListener(captor.capture()) + afterRenderListListener = captor.lastValue } @Test @@ -109,7 +105,16 @@ class StackCoordinatorTest : SysuiTestCase() { fun testSetNotificationStats_clearableAlerting() { whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) - verify(stackController).setNotifStats(NotifStats(1, false, true, false, false)) + verify(stackController) + .setNotifStats( + NotifStats( + 1, + hasNonClearableAlertingNotifs = false, + hasClearableAlertingNotifs = true, + hasNonClearableSilentNotifs = false, + hasClearableSilentNotifs = false, + ) + ) verifyNoMoreInteractions(activeNotificationsInteractor) } @@ -120,7 +125,16 @@ class StackCoordinatorTest : SysuiTestCase() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true) whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) - verify(stackController).setNotifStats(NotifStats(1, true, false, false, false)) + verify(stackController) + .setNotifStats( + NotifStats( + 1, + hasNonClearableAlertingNotifs = true, + hasClearableAlertingNotifs = false, + hasNonClearableSilentNotifs = false, + hasClearableSilentNotifs = false, + ) + ) verifyNoMoreInteractions(activeNotificationsInteractor) } @@ -129,7 +143,16 @@ class StackCoordinatorTest : SysuiTestCase() { fun testSetNotificationStats_clearableSilent() { whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) - verify(stackController).setNotifStats(NotifStats(1, false, false, false, true)) + verify(stackController) + .setNotifStats( + NotifStats( + 1, + hasNonClearableAlertingNotifs = false, + hasClearableAlertingNotifs = false, + hasNonClearableSilentNotifs = false, + hasClearableSilentNotifs = true, + ) + ) verifyNoMoreInteractions(activeNotificationsInteractor) } @@ -140,7 +163,16 @@ class StackCoordinatorTest : SysuiTestCase() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true) whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) - verify(stackController).setNotifStats(NotifStats(1, false, false, true, false)) + verify(stackController) + .setNotifStats( + NotifStats( + 1, + hasNonClearableAlertingNotifs = false, + hasClearableAlertingNotifs = false, + hasNonClearableSilentNotifs = true, + hasClearableSilentNotifs = false, + ) + ) verifyNoMoreInteractions(activeNotificationsInteractor) } @@ -150,7 +182,15 @@ class StackCoordinatorTest : SysuiTestCase() { whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) - .setNotifStats(NotifStats(1, false, true, false, false)) + .setNotifStats( + NotifStats( + 1, + hasNonClearableAlertingNotifs = false, + hasClearableAlertingNotifs = true, + hasNonClearableSilentNotifs = false, + hasClearableSilentNotifs = false, + ) + ) verifyNoMoreInteractions(stackController) } @@ -158,14 +198,22 @@ class StackCoordinatorTest : SysuiTestCase() { @EnableFlags( FooterViewRefactor.FLAG_NAME, FLAG_SCREENSHARE_NOTIFICATION_HIDING, - FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX + FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX, ) fun testSetNotificationStats_footerFlagOn_isSensitiveStateActive_nonClearableAlerting() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true) whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) - .setNotifStats(NotifStats(1, true, false, false, false)) + .setNotifStats( + NotifStats( + 1, + hasNonClearableAlertingNotifs = true, + hasClearableAlertingNotifs = false, + hasNonClearableSilentNotifs = false, + hasClearableSilentNotifs = false, + ) + ) verifyNoMoreInteractions(stackController) } @@ -175,7 +223,15 @@ class StackCoordinatorTest : SysuiTestCase() { whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) - .setNotifStats(NotifStats(1, false, false, false, true)) + .setNotifStats( + NotifStats( + 1, + hasNonClearableAlertingNotifs = false, + hasClearableAlertingNotifs = false, + hasNonClearableSilentNotifs = false, + hasClearableSilentNotifs = true, + ) + ) verifyNoMoreInteractions(stackController) } @@ -183,27 +239,41 @@ class StackCoordinatorTest : SysuiTestCase() { @EnableFlags( FooterViewRefactor.FLAG_NAME, FLAG_SCREENSHARE_NOTIFICATION_HIDING, - FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX + FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX, ) fun testSetNotificationStats_footerFlagOn_isSensitiveStateActive_nonClearableSilent() { whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true) whenever(section.bucket).thenReturn(BUCKET_SILENT) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) - .setNotifStats(NotifStats(1, false, false, true, false)) + .setNotifStats( + NotifStats( + 1, + hasNonClearableAlertingNotifs = false, + hasClearableAlertingNotifs = false, + hasNonClearableSilentNotifs = true, + hasClearableSilentNotifs = false, + ) + ) verifyNoMoreInteractions(stackController) } @Test - @EnableFlags( - FooterViewRefactor.FLAG_NAME - ) + @EnableFlags(FooterViewRefactor.FLAG_NAME) fun testSetNotificationStats_footerFlagOn_nonClearableRedacted() { entry.setSensitive(true, true) whenever(section.bucket).thenReturn(BUCKET_ALERTING) afterRenderListListener.onAfterRenderList(listOf(entry), stackController) verify(activeNotificationsInteractor) - .setNotifStats(NotifStats(1, hasNonClearableAlertingNotifs = true, false, false, false)) + .setNotifStats( + NotifStats( + 1, + hasNonClearableAlertingNotifs = true, + hasClearableAlertingNotifs = false, + hasNonClearableSilentNotifs = false, + hasClearableSilentNotifs = false, + ) + ) verifyNoMoreInteractions(stackController) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index b142fc2deea9..c9ada7e7f5ba 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -155,7 +155,6 @@ import com.android.systemui.shade.ShadeController; import com.android.systemui.shade.ShadeControllerImpl; import com.android.systemui.shade.ShadeExpansionStateManager; import com.android.systemui.shade.ShadeLogger; -import com.android.systemui.shade.StatusBarLongPressGestureDetector; import com.android.systemui.shared.notifications.domain.interactor.NotificationSettingsInteractor; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.KeyboardShortcutListSearch; @@ -175,6 +174,7 @@ import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarStateControllerImpl; import com.android.systemui.statusbar.core.StatusBarConnectedDisplays; import com.android.systemui.statusbar.core.StatusBarInitializerImpl; +import com.android.systemui.statusbar.core.StatusBarOrchestrator; import com.android.systemui.statusbar.data.repository.FakeStatusBarModeRepository; import com.android.systemui.statusbar.data.repository.StatusBarModePerDisplayRepository; import com.android.systemui.statusbar.notification.NotifPipelineFlags; @@ -372,7 +372,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { @Mock private EmergencyGestureIntentFactory mEmergencyGestureIntentFactory; @Mock private NotificationSettingsInteractor mNotificationSettingsInteractor; @Mock private ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; - @Mock private StatusBarLongPressGestureDetector mStatusBarLongPressGestureDetector; + @Mock private StatusBarOrchestrator mStatusBarOrchestrator; private ShadeController mShadeController; private final FakeSystemClock mFakeSystemClock = new FakeSystemClock(); private final FakeGlobalSettings mFakeGlobalSettings = new FakeGlobalSettings(); @@ -607,7 +607,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mShadeController, mWindowRootViewVisibilityInteractor, mStatusBarKeyguardViewManager, - () -> mStatusBarLongPressGestureDetector, mViewMediatorCallback, mInitController, new Handler(TestableLooper.get(this).getLooper()), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt index 69efa87a9cac..638f195df00c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt @@ -40,13 +40,14 @@ import com.android.systemui.flags.Flags import com.android.systemui.plugins.fakeDarkIconDispatcher import com.android.systemui.res.R import com.android.systemui.scene.ui.view.WindowRootView +import com.android.systemui.shade.LongPressGestureDetector import com.android.systemui.shade.ShadeControllerImpl import com.android.systemui.shade.ShadeLogger import com.android.systemui.shade.ShadeViewController -import com.android.systemui.shade.StatusBarLongPressGestureDetector import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.data.repository.fakeStatusBarContentInsetsProviderStore +import com.android.systemui.statusbar.data.repository.statusBarContentInsetsProviderStore import com.android.systemui.statusbar.policy.Clock import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.window.StatusBarWindowStateController @@ -97,7 +98,7 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() { @Mock private lateinit var windowRootView: Provider<WindowRootView> @Mock private lateinit var shadeLogger: ShadeLogger @Mock private lateinit var viewUtil: ViewUtil - @Mock private lateinit var mStatusBarLongPressGestureDetector: StatusBarLongPressGestureDetector + @Mock private lateinit var longPressGestureDetector: LongPressGestureDetector private lateinit var statusBarWindowStateController: StatusBarWindowStateController private lateinit var view: PhoneStatusBarView @@ -394,7 +395,7 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() { shadeControllerImpl, shadeViewController, panelExpansionInteractor, - { mStatusBarLongPressGestureDetector }, + { longPressGestureDetector }, windowRootView, shadeLogger, viewUtil, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/data/repository/KeyguardBypassRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/data/repository/KeyguardBypassRepositoryTest.kt index 0c0b5baad821..a2fabf3b9baa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/data/repository/KeyguardBypassRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/data/repository/KeyguardBypassRepositoryTest.kt @@ -34,45 +34,27 @@ import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POST import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN import com.android.systemui.statusbar.policy.devicePostureController import com.android.systemui.testKosmos -import com.android.systemui.tuner.TunerService -import com.android.systemui.tuner.tunerService -import com.android.systemui.util.mockito.withArgCaptor +import com.android.systemui.util.settings.data.repository.userAwareSecureSettingsRepository import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest -import org.junit.Before -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.anyInt -import org.mockito.ArgumentMatchers.eq -import org.mockito.Mockito.verify -import org.mockito.MockitoAnnotations -import org.mockito.junit.MockitoJUnit -import org.mockito.junit.MockitoRule -import org.mockito.kotlin.whenever @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) @EnableSceneContainer class KeyguardBypassRepositoryTest : SysuiTestCase() { - @JvmField @Rule val mockito: MockitoRule = MockitoJUnit.rule() - private lateinit var tunableCallback: TunerService.Tunable private lateinit var postureControllerCallback: DevicePostureController.Callback private val kosmos = testKosmos() private lateinit var underTest: KeyguardBypassRepository private val testScope = kosmos.testScope - @Before - fun setup() { - MockitoAnnotations.initMocks(this) - } - // overrideFaceBypassSetting overridden to true // isFaceEnrolledAndEnabled true // isPostureAllowedForFaceAuth true/false on posture changes @@ -148,24 +130,25 @@ class KeyguardBypassRepositoryTest : SysuiTestCase() { val bypassEnabled by collectLastValue(underTest.isBypassAvailable) runCurrent() postureControllerCallback = kosmos.devicePostureController.verifyCallback() - tunableCallback = kosmos.tunerService.captureCallback() // Update face auth posture to match config postureControllerCallback.onPostureChanged(DEVICE_POSTURE_CLOSED) // FACE_UNLOCK_DISMISSES_KEYGUARD setting true - whenever(kosmos.tunerService.getValue(eq(faceUnlockDismissesKeyguard), anyInt())) - .thenReturn(1) - tunableCallback.onTuningChanged(faceUnlockDismissesKeyguard, "") + kosmos.userAwareSecureSettingsRepository.setBoolean( + Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, + true, + ) runCurrent() // Assert bypass enabled assertThat(bypassEnabled).isTrue() // FACE_UNLOCK_DISMISSES_KEYGUARD setting false - whenever(kosmos.tunerService.getValue(eq(faceUnlockDismissesKeyguard), anyInt())) - .thenReturn(0) - tunableCallback.onTuningChanged(faceUnlockDismissesKeyguard, "") + kosmos.userAwareSecureSettingsRepository.setBoolean( + Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, + false, + ) runCurrent() // Assert bypass not enabled @@ -229,10 +212,3 @@ class KeyguardBypassRepositoryTest : SysuiTestCase() { private const val FACE_UNLOCK_BYPASS_NEVER = 2 } } - -private const val faceUnlockDismissesKeyguard = Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD - -private fun TunerService.captureCallback() = - withArgCaptor<TunerService.Tunable> { - verify(this@captureCallback).addTunable(capture(), eq(faceUnlockDismissesKeyguard)) - } diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index fc318d56a8d5..856333ea724e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -49,6 +49,7 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -2507,17 +2508,54 @@ public class BubblesTest extends SysuiTestCase { @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) @Test - public void testEventLogging_bubbleBar_dragBubbleToDismiss() { + public void testEventLogging_bubbleBar_dragSelectedBubbleToDismiss() { mBubbleProperties.mIsBubbleBarEnabled = true; mPositioner.setIsLargeScreen(true); FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener(); mBubbleController.registerBubbleStateListener(bubbleStateListener); mEntryListener.onEntryAdded(mRow); - mBubbleController.dragBubbleToDismiss(mRow.getKey(), 1L); + mEntryListener.onEntryAdded(mRow2); + mBubbleController.expandStackAndSelectBubbleFromLauncher(mRow2.getKey(), 0); + + clearInvocations(mBubbleLogger); + + // Dismiss selected bubble + mBubbleController.startBubbleDrag(mRow2.getKey()); + mBubbleController.dragBubbleToDismiss(mRow2.getKey(), System.currentTimeMillis()); + // Log bubble dismissed via drag and new bubble selected + verify(mBubbleLogger).log(eqBubbleWithKey(mRow2.getKey()), + eq(BubbleLogger.Event.BUBBLE_BAR_BUBBLE_DISMISSED_DRAG_BUBBLE)); + verify(mBubbleLogger).log(eqBubbleWithKey(mRow.getKey()), + eq(BubbleLogger.Event.BUBBLE_BAR_BUBBLE_SWITCHED)); + + verifyNoMoreInteractions(mBubbleLogger); + } + + @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) + @Test + public void testEventLogging_bubbleBar_dragOtherBubbleToDismiss() { + mBubbleProperties.mIsBubbleBarEnabled = true; + mPositioner.setIsLargeScreen(true); + FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener(); + mBubbleController.registerBubbleStateListener(bubbleStateListener); + + mEntryListener.onEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow2); + mBubbleController.expandStackAndSelectBubbleFromLauncher(mRow2.getKey(), 0); + + clearInvocations(mBubbleLogger); + + // Dismiss other bubble + mBubbleController.startBubbleDrag(mRow.getKey()); + mBubbleController.dragBubbleToDismiss(mRow.getKey(), System.currentTimeMillis()); + + // Log bubble dismissed via drag, but no switch event verify(mBubbleLogger).log(eqBubbleWithKey(mRow.getKey()), eq(BubbleLogger.Event.BUBBLE_BAR_BUBBLE_DISMISSED_DRAG_BUBBLE)); + + verifyNoMoreInteractions(mBubbleLogger); } @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) @@ -2643,6 +2681,32 @@ public class BubblesTest extends SysuiTestCase { eq(BubbleLogger.Event.BUBBLE_BAR_EXPANDED)); } + @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) + @Test + public void testEventLogging_bubbleBar_switchBubble() { + mBubbleProperties.mIsBubbleBarEnabled = true; + mPositioner.setIsLargeScreen(true); + FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener(); + mBubbleController.registerBubbleStateListener(bubbleStateListener); + + mEntryListener.onEntryAdded(mRow); + mEntryListener.onEntryAdded(mRow2); + mBubbleController.expandStackAndSelectBubbleFromLauncher(mRow.getKey(), 0); + + // First select is expand + verify(mBubbleLogger).log(eqBubbleWithKey(mRow.getKey()), + eq(BubbleLogger.Event.BUBBLE_BAR_EXPANDED)); + verify(mBubbleLogger, never()).log(eqBubbleWithKey(mRow.getKey()), + eq(BubbleLogger.Event.BUBBLE_BAR_BUBBLE_SWITCHED)); + + // Second select is switch + mBubbleController.expandStackAndSelectBubbleFromLauncher(mRow2.getKey(), 0); + verify(mBubbleLogger).log(eqBubbleWithKey(mRow2.getKey()), + eq(BubbleLogger.Event.BUBBLE_BAR_BUBBLE_SWITCHED)); + verify(mBubbleLogger, never()).log(eqBubbleWithKey(mRow2.getKey()), + eq(BubbleLogger.Event.BUBBLE_BAR_EXPANDED)); + } + /** Creates a bubble using the userId and package. */ private Bubble createBubble(int userId, String pkg) { final UserHandle userHandle = new UserHandle(userId); diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayWindowPropertiesRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayWindowPropertiesRepository.kt index 92dc89747db8..7fd927654ca6 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayWindowPropertiesRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayWindowPropertiesRepository.kt @@ -35,4 +35,9 @@ class FakeDisplayWindowPropertiesRepository : DisplayWindowPropertiesRepository ) .also { properties.put(displayId, windowType, it) } } + + /** Sets an instance, just for testing purposes. */ + fun insert(instance: DisplayWindowProperties) { + properties.put(instance.displayId, instance.windowType, instance) + } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt new file mode 100644 index 000000000000..b24b3ad05117 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.dreams.ui.viewmodel + +import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.shade.domain.interactor.shadeInteractor + +val Kosmos.dreamUserActionsViewModel by + Kosmos.Fixture { + DreamUserActionsViewModel( + deviceUnlockedInteractor = deviceUnlockedInteractor, + shadeInteractor = shadeInteractor, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt index f52f039b6758..903bc8ebf42d 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt @@ -109,6 +109,7 @@ val Kosmos.customShortcutCategoriesRepository by applicationCoroutineScope, testDispatcher, shortcutCategoriesUtils, + applicationContext, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBypassRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBypassRepositoryKosmos.kt index c91823cc2999..0de456be7477 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBypassRepositoryKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBypassRepositoryKosmos.kt @@ -25,8 +25,8 @@ import com.android.systemui.res.R import com.android.systemui.statusbar.policy.DevicePostureController import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN -import com.android.systemui.tuner.tunerService import com.android.systemui.util.mockito.withArgCaptor +import com.android.systemui.util.settings.data.repository.userAwareSecureSettingsRepository import org.mockito.ArgumentMatchers.any import org.mockito.Mockito.never import org.mockito.Mockito.verify @@ -37,7 +37,7 @@ val Kosmos.keyguardBypassRepository: KeyguardBypassRepository by Fixture { biometricSettingsRepository, devicePostureRepository, dumpManager, - tunerService, + userAwareSecureSettingsRepository, testDispatcher, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt index 769612c988ba..255a780a84be 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt @@ -30,7 +30,7 @@ import com.android.systemui.shade.pulsingGestureListener val Kosmos.keyguardTouchHandlingInteractor by Kosmos.Fixture { KeyguardTouchHandlingInteractor( - appContext = applicationContext, + context = applicationContext, scope = applicationCoroutineScope, transitionInteractor = keyguardTransitionInteractor, repository = keyguardRepository, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt index 63e6eb6c0ef5..3cd613b21f4b 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt @@ -71,14 +71,17 @@ import com.android.systemui.shade.shadeController import com.android.systemui.shade.ui.viewmodel.notificationShadeWindowModel import com.android.systemui.statusbar.chips.ui.viewmodel.ongoingActivityChipsViewModel import com.android.systemui.statusbar.data.repository.fakeStatusBarModePerDisplayRepository +import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor import com.android.systemui.statusbar.notification.domain.interactor.seenNotificationsInteractor import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor +import com.android.systemui.statusbar.phone.keyguardBypassController import com.android.systemui.statusbar.phone.scrimController import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository import com.android.systemui.statusbar.pipeline.wifi.data.repository.fakeWifiRepository import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.wifiInteractor +import com.android.systemui.statusbar.policy.configurationController import com.android.systemui.statusbar.policy.data.repository.fakeDeviceProvisioningRepository import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor import com.android.systemui.statusbar.ui.viewmodel.keyguardStatusBarViewModel @@ -105,6 +108,7 @@ class KosmosJavaAdapter() { val testScope by lazy { kosmos.testScope } val fakeExecutor by lazy { kosmos.fakeExecutor } val fakeExecutorHandler by lazy { kosmos.fakeExecutorHandler } + val configurationController by lazy { kosmos.configurationController } val configurationRepository by lazy { kosmos.fakeConfigurationRepository } val configurationInteractor by lazy { kosmos.configurationInteractor } val bouncerRepository by lazy { kosmos.bouncerRepository } @@ -115,6 +119,7 @@ class KosmosJavaAdapter() { val seenNotificationsInteractor by lazy { kosmos.seenNotificationsInteractor } val keyguardRepository by lazy { kosmos.fakeKeyguardRepository } val keyguardBouncerRepository by lazy { kosmos.fakeKeyguardBouncerRepository } + val keyguardBypassController by lazy { kosmos.keyguardBypassController } val keyguardInteractor by lazy { kosmos.keyguardInteractor } val keyguardTransitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository } val keyguardTransitionInteractor by lazy { kosmos.keyguardTransitionInteractor } @@ -158,6 +163,7 @@ class KosmosJavaAdapter() { val shadeRepository by lazy { kosmos.shadeRepository } val shadeInteractor by lazy { kosmos.shadeInteractor } val notificationShadeWindowModel by lazy { kosmos.notificationShadeWindowModel } + val visualStabilityProvider by lazy { kosmos.visualStabilityProvider } val wifiInteractor by lazy { kosmos.wifiInteractor } val fakeWifiRepository by lazy { kosmos.fakeWifiRepository } val volumeDialogInteractor by lazy { kosmos.volumeDialogInteractor } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepositoryKosmos.kt new file mode 100644 index 000000000000..92eeef97f7c4 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepositoryKosmos.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.events.data.repository + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState +import kotlinx.coroutines.flow.MutableStateFlow + +val Kosmos.systemStatusEventAnimationRepository: FakeSystemStatusEventAnimationRepository by + Kosmos.Fixture { FakeSystemStatusEventAnimationRepository() } + +class FakeSystemStatusEventAnimationRepository : SystemStatusEventAnimationRepository { + override val animationState = MutableStateFlow(SystemEventAnimationState.Idle) +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractorKosmos.kt new file mode 100644 index 000000000000..7513fead0187 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractorKosmos.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.events.domain.interactor + +import com.android.systemui.common.ui.domain.interactor.configurationInteractor +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.applicationCoroutineScope +import com.android.systemui.statusbar.events.data.repository.systemStatusEventAnimationRepository + +val Kosmos.systemStatusEventAnimationInteractor by + Kosmos.Fixture { + SystemStatusEventAnimationInteractor( + repo = systemStatusEventAnimationRepository, + configurationInteractor = configurationInteractor, + scope = applicationCoroutineScope, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt index 32c582f79ed7..2ec801620212 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/model/ActiveNotificationModelBuilder.kt @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.data.model import android.app.PendingIntent import android.graphics.drawable.Icon import com.android.systemui.statusbar.StatusBarIconView +import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.systemui.statusbar.notification.shared.CallType import com.android.systemui.statusbar.notification.stack.BUCKET_UNKNOWN @@ -46,6 +47,7 @@ fun activeNotificationModel( contentIntent: PendingIntent? = null, bucket: Int = BUCKET_UNKNOWN, callType: CallType = CallType.None, + promotedContent: PromotedNotificationContentModel? = null, ) = ActiveNotificationModel( key = key, @@ -69,4 +71,5 @@ fun activeNotificationModel( isGroupSummary = isGroupSummary, bucket = bucket, callType = callType, + promotedContent = promotedContent, ) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt index 3a7ada2e61b8..03e4c894c2f2 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt @@ -24,6 +24,7 @@ import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInter import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.statusbar.chips.ui.viewmodel.ongoingActivityChipsViewModel +import com.android.systemui.statusbar.events.domain.interactor.systemStatusEventAnimationInteractor import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor import com.android.systemui.statusbar.phone.domain.interactor.lightsOutInteractor import com.android.systemui.statusbar.pipeline.shared.domain.interactor.collapsedStatusBarInteractor @@ -40,6 +41,7 @@ val Kosmos.homeStatusBarViewModel: HomeStatusBarViewModel by sceneContainerOcclusionInteractor, shadeInteractor, ongoingActivityChipsViewModel, + systemStatusEventAnimationInteractor, applicationCoroutineScope, ) } diff --git a/ravenwood/scripts/run-ravenwood-tests.sh b/ravenwood/scripts/run-ravenwood-tests.sh index fe2269a8dc38..27c5ea1bd0d7 100755 --- a/ravenwood/scripts/run-ravenwood-tests.sh +++ b/ravenwood/scripts/run-ravenwood-tests.sh @@ -33,7 +33,7 @@ include_re="" exclude_re="" smoke_exclude_re="" dry_run="" -while getopts "sx:f:dt" opt; do +while getopts "sx:f:dtb" opt; do case "$opt" in s) # Remove slow tests. @@ -52,8 +52,13 @@ case "$opt" in dry_run="echo" ;; t) + # Redirect log to terminal export RAVENWOOD_LOG_OUT=$(tty) ;; + b) + # Build only + ATEST=m + ;; '?') exit 1 ;; @@ -99,11 +104,16 @@ done # Calculate the removed tests. -diff="$(diff <(echo "${all_tests[@]}" | tr ' ' '\n') <(echo "${targets[@]}" | tr ' ' '\n') )" +diff="$(diff <(echo "${all_tests[@]}" | tr ' ' '\n') <(echo "${targets[@]}" | tr ' ' '\n') | grep -v [0-9] )" if [[ "$diff" != "" ]]; then echo "Excluded tests:" echo "$diff" fi -$dry_run ${ATEST:-atest} "${targets[@]}" +run() { + echo "Running: ${@}" + "${@}" +} + +run $dry_run ${ATEST:-atest} "${targets[@]}" diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh b/ravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh index 3726ca972564..b389a67a8e4c 100755 --- a/ravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh +++ b/ravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh @@ -30,7 +30,7 @@ help() { EOF } -source "${0%/*}"/../../common.sh +source "${0%/*}"/../common.sh SCRIPT_NAME="${0##*/}" @@ -61,7 +61,6 @@ esac done shift $(($OPTIND - 1)) - # Build the dump files, which are the input of this test. run m dump-jar tiny-framework-dump-test diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionExecutors.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionExecutors.java index 44ae1d1fbbbf..81e83b563945 100644 --- a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionExecutors.java +++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionExecutors.java @@ -16,7 +16,6 @@ package com.android.server.appfunctions; -import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -24,15 +23,21 @@ import java.util.concurrent.TimeUnit; /** Executors for App function operations. */ public final class AppFunctionExecutors { + static final int sConcurrency = Runtime.getRuntime().availableProcessors(); + /** Executor for operations that do not need to block. */ - public static final Executor THREAD_POOL_EXECUTOR = + public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor( - /* corePoolSize= */ Runtime.getRuntime().availableProcessors(), - /* maxConcurrency= */ Runtime.getRuntime().availableProcessors(), - /* keepAliveTime= */ 0L, + /* corePoolSize= */ sConcurrency, + /* maxConcurrency= */ sConcurrency, + /* keepAliveTime= */ 1L, /* unit= */ TimeUnit.SECONDS, /* workQueue= */ new LinkedBlockingQueue<>(), new NamedThreadFactory("AppFunctionExecutors")); + static { + THREAD_POOL_EXECUTOR.allowCoreThreadTimeOut(true); + } + private AppFunctionExecutors() {} } diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 0bd879b7568d..827e3effcf32 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -607,7 +607,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku // ... and see if these are hosts we've been awaiting. // NOTE: We are backing up and restoring only the owner. // TODO: http://b/22388012 - if (newPackageAdded && userId == mUserManager.getMainUser().getIdentifier()) { + UserHandle mainUser = mUserManager.getMainUser(); + if (newPackageAdded && mainUser != null && userId == mainUser.getIdentifier()) { final int uid = getUidForPackage(pkgName, userId); if (uid >= 0 ) { resolveHostUidLocked(pkgName, uid); diff --git a/services/autofill/features.aconfig b/services/autofill/features.aconfig index 1dc3b73d2bd3..bd46debf12ca 100644 --- a/services/autofill/features.aconfig +++ b/services/autofill/features.aconfig @@ -22,3 +22,11 @@ flag { description: "Guards against Autofill-Credman Phase1 developer integration via new APIs" bug: "320730001" } + +flag { + name: "fill_dialog_improvements" + is_exported: true + namespace: "autofill" + description: "Improvements for Fill Dialog, including deprecation of pre-trigger API's" + bug: "336223371" +} diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java index cd2a535aa2c5..e59bb42fd666 100644 --- a/services/autofill/java/com/android/server/autofill/Helper.java +++ b/services/autofill/java/com/android/server/autofill/Helper.java @@ -28,8 +28,11 @@ import android.app.ActivityManager; import android.app.assist.AssistStructure; import android.app.assist.AssistStructure.ViewNode; import android.app.assist.AssistStructure.WindowNode; +import android.app.slice.Slice; +import android.app.slice.SliceItem; import android.content.ComponentName; import android.content.Context; +import android.graphics.drawable.Icon; import android.hardware.display.DisplayManager; import android.metrics.LogMaker; import android.os.UserHandle; @@ -97,11 +100,12 @@ public final class Helper { @UserIdInt int userId, @NonNull RemoteViews rView) { final AtomicBoolean permissionsOk = new AtomicBoolean(true); - rView.visitUris(uri -> { - int uriOwnerId = android.content.ContentProvider.getUserIdFromUri(uri); - boolean allowed = uriOwnerId == userId; - permissionsOk.set(allowed & permissionsOk.get()); - }); + rView.visitUris( + uri -> { + int uriOwnerId = android.content.ContentProvider.getUserIdFromUri(uri, userId); + boolean allowed = uriOwnerId == userId; + permissionsOk.set(allowed & permissionsOk.get()); + }); return permissionsOk.get(); } @@ -150,6 +154,47 @@ public final class Helper { return (ok ? rView : null); } + /** + * Checks the URI permissions of the icon in the slice, to see if the current userId is able to + * access it. + * + * <p>Returns null if slice contains user inaccessible icons + * + * <p>TODO: instead of returning a null Slice when the current userId cannot access an icon, + * return a reconstructed Slice without the icons. This is currently non-trivial since there are + * no public methods to generically add SliceItems to Slices + */ + public static @Nullable Slice sanitizeSlice(Slice slice) { + if (slice == null) { + return null; + } + + int userId = ActivityManager.getCurrentUser(); + + // Recontruct the Slice, filtering out bad icons + for (SliceItem sliceItem : slice.getItems()) { + if (!sliceItem.getFormat().equals(SliceItem.FORMAT_IMAGE)) { + // Not an image slice + continue; + } + + Icon icon = sliceItem.getIcon(); + if (icon.getType() != Icon.TYPE_URI + && icon.getType() != Icon.TYPE_URI_ADAPTIVE_BITMAP) { + // No URIs to sanitize + continue; + } + + int iconUriId = android.content.ContentProvider.getUserIdFromUri(icon.getUri(), userId); + + if (iconUriId != userId) { + Slog.w(TAG, "sanitizeSlice() user: " + userId + " cannot access icons in Slice"); + return null; + } + } + + return slice; + } @Nullable static AutofillId[] toArray(@Nullable ArraySet<AutofillId> set) { diff --git a/services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java b/services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java index 38a412fa063d..50a26b355537 100644 --- a/services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java +++ b/services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java @@ -27,6 +27,7 @@ import android.service.autofill.InlinePresentation; import android.util.Slog; import com.android.server.LocalServices; +import com.android.server.autofill.Helper; import com.android.server.autofill.RemoteInlineSuggestionRenderService; import com.android.server.inputmethod.InputMethodManagerInternal; @@ -83,6 +84,10 @@ final class RemoteInlineSuggestionViewConnector { */ public boolean renderSuggestion(int width, int height, @NonNull IInlineSuggestionUiCallback callback) { + if (Helper.sanitizeSlice(mInlinePresentation.getSlice()) == null) { + if (sDebug) Slog.d(TAG, "Skipped rendering inline suggestion."); + return false; + } if (mRemoteRenderService != null) { if (sDebug) Slog.d(TAG, "Request to recreate the UI"); mRemoteRenderService.renderSuggestion(callback, mInlinePresentation, width, height, diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index cb89f2895902..dfddc089e4a4 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -668,6 +668,8 @@ public class ActivityManagerService extends IActivityManager.Stub */ private static final boolean ENABLE_PROC_LOCK = true; + private static final int DEFAULT_INTENT_CREATOR_UID = -1; + /** * The lock for process management. * @@ -19308,22 +19310,36 @@ public class ActivityManagerService extends IActivityManager.Stub if (!preventIntentRedirect()) return; if (intent == null) return; + + String targetPackage = intent.getComponent() != null + ? intent.getComponent().getPackageName() + : intent.getPackage(); + final boolean isCreatorSameAsTarget = creatorPackage != null && creatorPackage.equals( + targetPackage); + final boolean noExtraIntentKeys = + intent.getExtraIntentKeys() == null || intent.getExtraIntentKeys().isEmpty(); + final int creatorUid = noExtraIntentKeys ? DEFAULT_INTENT_CREATOR_UID : Binder.getCallingUid(); + intent.forEachNestedCreatorToken(extraIntent -> { - IntentCreatorToken creatorToken = createIntentCreatorToken(extraIntent, creatorPackage); + if (isCreatorSameAsTarget) { + FrameworkStatsLog.write(INTENT_CREATOR_TOKEN_ADDED, creatorUid, true); + return; + } + IntentCreatorToken creatorToken = createIntentCreatorToken(extraIntent, creatorUid, + creatorPackage); if (creatorToken != null) { extraIntent.setCreatorToken(creatorToken); // TODO remove Slog.wtf once proven FrameworkStatsLog works. b/375396329 Slog.wtf(TAG, "A creator token is added to an intent. creatorPackage: " + creatorPackage + "; intent: " + extraIntent); - FrameworkStatsLog.write(INTENT_CREATOR_TOKEN_ADDED, - creatorToken.getCreatorUid()); + FrameworkStatsLog.write(INTENT_CREATOR_TOKEN_ADDED, creatorUid, false); } }); } - private IntentCreatorToken createIntentCreatorToken(Intent intent, String creatorPackage) { + private IntentCreatorToken createIntentCreatorToken(Intent intent, int creatorUid, + String creatorPackage) { if (IntentCreatorToken.isValid(intent)) return null; - int creatorUid = getCallingUid(); IntentCreatorToken.Key key = new IntentCreatorToken.Key(creatorUid, creatorPackage, intent); IntentCreatorToken token; synchronized (sIntentCreatorTokenCache) { diff --git a/services/core/java/com/android/server/am/BroadcastController.java b/services/core/java/com/android/server/am/BroadcastController.java index 8a128582c507..446b3671a94a 100644 --- a/services/core/java/com/android/server/am/BroadcastController.java +++ b/services/core/java/com/android/server/am/BroadcastController.java @@ -57,7 +57,6 @@ import android.app.ApplicationExitInfo; import android.app.ApplicationThreadConstants; import android.app.BackgroundStartPrivileges; import android.app.BroadcastOptions; -import android.app.BroadcastStickyCache; import android.app.IApplicationThread; import android.app.compat.CompatChanges; import android.appwidget.AppWidgetManager; @@ -702,7 +701,6 @@ class BroadcastController { boolean serialized, boolean sticky, int userId) { mService.enforceNotIsolatedCaller("broadcastIntent"); - int result; synchronized (mService) { intent = verifyBroadcastLocked(intent); @@ -724,7 +722,7 @@ class BroadcastController { final long origId = Binder.clearCallingIdentity(); try { - result = broadcastIntentLocked(callerApp, + return broadcastIntentLocked(callerApp, callerApp != null ? callerApp.info.packageName : null, callingFeatureId, intent, resolvedType, resultToApp, resultTo, resultCode, resultData, resultExtras, requiredPermissions, excludedPermissions, excludedPackages, @@ -735,10 +733,6 @@ class BroadcastController { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } - if (sticky && result == ActivityManager.BROADCAST_SUCCESS) { - BroadcastStickyCache.incrementVersion(intent.getAction()); - } - return result; } // Not the binder call surface @@ -749,7 +743,6 @@ class BroadcastController { boolean serialized, boolean sticky, int userId, BackgroundStartPrivileges backgroundStartPrivileges, @Nullable int[] broadcastAllowList) { - int result; synchronized (mService) { intent = verifyBroadcastLocked(intent); @@ -757,7 +750,7 @@ class BroadcastController { String[] requiredPermissions = requiredPermission == null ? null : new String[] {requiredPermission}; try { - result = broadcastIntentLocked(null, packageName, featureId, intent, resolvedType, + return broadcastIntentLocked(null, packageName, featureId, intent, resolvedType, resultToApp, resultTo, resultCode, resultData, resultExtras, requiredPermissions, null, null, OP_NONE, bOptions, serialized, sticky, -1, uid, realCallingUid, realCallingPid, userId, @@ -767,10 +760,6 @@ class BroadcastController { Binder.restoreCallingIdentity(origId); } } - if (sticky && result == ActivityManager.BROADCAST_SUCCESS) { - BroadcastStickyCache.incrementVersion(intent.getAction()); - } - return result; } @GuardedBy("mService") @@ -1469,7 +1458,6 @@ class BroadcastController { list.add(StickyBroadcast.create(new Intent(intent), deferUntilActive, callingUid, callerAppProcessState, resolvedType)); } - BroadcastStickyCache.incrementVersion(intent.getAction()); } } @@ -1736,7 +1724,6 @@ class BroadcastController { Slog.w(TAG, msg); throw new SecurityException(msg); } - final ArrayList<String> changedStickyBroadcasts = new ArrayList<>(); synchronized (mStickyBroadcasts) { ArrayMap<String, ArrayList<StickyBroadcast>> stickies = mStickyBroadcasts.get(userId); if (stickies != null) { @@ -1753,16 +1740,12 @@ class BroadcastController { if (list.size() <= 0) { stickies.remove(intent.getAction()); } - changedStickyBroadcasts.add(intent.getAction()); } if (stickies.size() <= 0) { mStickyBroadcasts.remove(userId); } } } - for (int i = changedStickyBroadcasts.size() - 1; i >= 0; --i) { - BroadcastStickyCache.incrementVersionIfExists(changedStickyBroadcasts.get(i)); - } } void finishReceiver(IBinder caller, int resultCode, String resultData, @@ -1925,9 +1908,7 @@ class BroadcastController { private void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { mService.mProcessList.sendPackageBroadcastLocked(cmd, packages, userId); - } - - private List<ResolveInfo> collectReceiverComponents( + }private List<ResolveInfo> collectReceiverComponents( Intent intent, String resolvedType, int callingUid, int callingPid, int[] users, int[] broadcastAllowList) { // TODO: come back and remove this assumption to triage all broadcasts @@ -2143,18 +2124,9 @@ class BroadcastController { } void removeStickyBroadcasts(int userId) { - final ArrayList<String> changedStickyBroadcasts = new ArrayList<>(); synchronized (mStickyBroadcasts) { - final ArrayMap<String, ArrayList<StickyBroadcast>> stickies = - mStickyBroadcasts.get(userId); - if (stickies != null) { - changedStickyBroadcasts.addAll(stickies.keySet()); - } mStickyBroadcasts.remove(userId); } - for (int i = changedStickyBroadcasts.size() - 1; i >= 0; --i) { - BroadcastStickyCache.incrementVersionIfExists(changedStickyBroadcasts.get(i)); - } } @NeverCompile diff --git a/services/core/java/com/android/server/am/BroadcastFilter.java b/services/core/java/com/android/server/am/BroadcastFilter.java index 3c7fb52b11b4..d899228472ad 100644 --- a/services/core/java/com/android/server/am/BroadcastFilter.java +++ b/services/core/java/com/android/server/am/BroadcastFilter.java @@ -40,7 +40,7 @@ public final class BroadcastFilter extends IntentFilter { @ChangeId @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE) @VisibleForTesting - static final long CHANGE_RESTRICT_PRIORITY_VALUES = 371309185L; + static final long RESTRICT_PRIORITY_VALUES = 371309185L; // Back-pointer to the list this filter is in. final ReceiverList receiverList; @@ -130,7 +130,7 @@ public final class BroadcastFilter extends IntentFilter { return priority; } if (!platformCompat.isChangeEnabledByUidInternalNoLogging( - CHANGE_RESTRICT_PRIORITY_VALUES, owningUid)) { + RESTRICT_PRIORITY_VALUES, owningUid)) { return priority; } if (!UserHandle.isCore(owningUid)) { diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java index 38df10a0bc8c..e8ce1731f739 100644 --- a/services/core/java/com/android/server/am/BroadcastRecord.java +++ b/services/core/java/com/android/server/am/BroadcastRecord.java @@ -88,7 +88,7 @@ final class BroadcastRecord extends Binder { @ChangeId @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE) @VisibleForTesting - static final long CHANGE_LIMIT_PRIORITY_SCOPE = 371307720L; + static final long LIMIT_PRIORITY_SCOPE = 371307720L; final @NonNull Intent intent; // the original intent that generated us final @Nullable ComponentName targetComp; // original component name set on the intent @@ -781,7 +781,7 @@ final class BroadcastRecord extends Binder { } else { if (Flags.limitPriorityScope()) { final boolean[] changeEnabled = calculateChangeStateForReceivers( - receivers, CHANGE_LIMIT_PRIORITY_SCOPE, platformCompat); + receivers, LIMIT_PRIORITY_SCOPE, platformCompat); // Priority of the previous tranche int lastTranchePriority = 0; diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 416c11090515..da5b1fd1c079 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -101,7 +101,7 @@ import java.util.Random; import java.util.Set; import java.util.concurrent.Executor; -public final class CachedAppOptimizer { +public class CachedAppOptimizer { // Flags stored in the DeviceConfig API. @VisibleForTesting static final String KEY_USE_COMPACTION = "use_compaction"; diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index c0676623a1e9..b84bf6b90711 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -19,6 +19,7 @@ package com.android.server.am; import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL; import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL_IMPLICIT; import static android.app.ActivityManager.PROCESS_CAPABILITY_BFSL; +import static android.app.ActivityManager.PROCESS_CAPABILITY_CPU_TIME; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; @@ -155,6 +156,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; +import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; @@ -469,7 +471,6 @@ public class OomAdjuster { } Process.setThreadPriority(tid, priority); } - } // TODO(b/346822474): hook up global state usage. @@ -499,7 +500,8 @@ public class OomAdjuster { } OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, - ServiceThread adjusterThread, GlobalState globalState, Injector injector) { + ServiceThread adjusterThread, GlobalState globalState, + CachedAppOptimizer cachedAppOptimizer, Injector injector) { mService = service; mGlobalState = globalState; mInjector = injector; @@ -508,7 +510,7 @@ public class OomAdjuster { mActiveUids = activeUids; mConstants = mService.mConstants; - mCachedAppOptimizer = new CachedAppOptimizer(mService); + mCachedAppOptimizer = cachedAppOptimizer; mCacheOomRanker = new CacheOomRanker(service); mLogger = new OomAdjusterDebugLogger(this, mService.mConstants); @@ -2597,6 +2599,7 @@ public class OomAdjuster { } capability |= getDefaultCapability(app, procState); + capability |= getCpuCapability(app, now); // Procstates below BFGS should never have this capability. if (procState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { @@ -2739,8 +2742,12 @@ public class OomAdjuster { if (app.mOptRecord.setShouldNotFreeze(true, dryRun, app.mOptRecord.shouldNotFreezeReason() | client.mOptRecord.shouldNotFreezeReason(), mAdjSeq)) { - // Bail out early, as we only care about the return value for a dryrun. - return true; + if (Flags.useCpuTimeCapability()) { + // Do nothing, capability updated check will handle the dryrun output. + } else { + // Bail out early, as we only care about the return value for a dryrun. + return true; + } } } @@ -2751,6 +2758,8 @@ public class OomAdjuster { // we check the final procstate, and remove it if the procsate is below BFGS. capability |= getBfslCapabilityFromClient(client); + capability |= getCpuCapabilityFromClient(client); + if (cr.notHasFlag(Context.BIND_WAIVE_PRIORITY)) { if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { capability |= cstate.getCurCapability(); @@ -2809,9 +2818,14 @@ public class OomAdjuster { app.mOptRecord.shouldNotFreezeReason() | ProcessCachedOptimizerRecord .SHOULD_NOT_FREEZE_REASON_BINDER_ALLOW_OOM_MANAGEMENT, mAdjSeq)) { - // Bail out early, as we only care about the return value for a dryrun. - return true; + if (Flags.useCpuTimeCapability()) { + // Do nothing, capability updated check will handle the dryrun output. + } else { + // Bail out early, as we only care about the return value for a dryrun. + return true; + } } + capability |= PROCESS_CAPABILITY_CPU_TIME; } // Not doing bind OOM management, so treat // this guy more like a started service. @@ -3053,9 +3067,14 @@ public class OomAdjuster { app.mOptRecord.shouldNotFreezeReason() | ProcessCachedOptimizerRecord .SHOULD_NOT_FREEZE_REASON_BIND_WAIVE_PRIORITY, mAdjSeq)) { - // Bail out early, as we only care about the return value for a dryrun. - return true; + if (Flags.useCpuTimeCapability()) { + // Do nothing, capability updated check will handle the dryrun output. + } else { + // Bail out early, as we only care about the return value for a dryrun. + return true; + } } + capability |= PROCESS_CAPABILITY_CPU_TIME; } } if (cr.hasFlag(Context.BIND_TREAT_LIKE_ACTIVITY)) { @@ -3108,9 +3127,24 @@ public class OomAdjuster { capability &= ~PROCESS_CAPABILITY_BFSL; } if (!updated) { - updated = adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup - || (capability != prevCapability - && (capability & prevCapability) == prevCapability); + if (adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup) { + updated = true; + } + + if (Flags.useCpuTimeCapability()) { + if ((capability != prevCapability) + && ((capability & prevCapability) == prevCapability)) { + updated = true; + } + } else { + // Ignore PROCESS_CAPABILITY_CPU_TIME in capability comparison + final int curFiltered = capability & ~PROCESS_CAPABILITY_CPU_TIME; + final int prevFiltered = prevCapability & ~PROCESS_CAPABILITY_CPU_TIME; + if ((curFiltered != prevFiltered) + && ((curFiltered & prevFiltered) == prevFiltered)) { + updated = true; + } + } } if (dryRun) { @@ -3186,6 +3220,8 @@ public class OomAdjuster { // we check the final procstate, and remove it if the procsate is below BFGS. capability |= getBfslCapabilityFromClient(client); + capability |= getCpuCapabilityFromClient(client); + if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. @@ -3196,8 +3232,12 @@ public class OomAdjuster { if (app.mOptRecord.setShouldNotFreeze(true, dryRun, app.mOptRecord.shouldNotFreezeReason() | client.mOptRecord.shouldNotFreezeReason(), mAdjSeq)) { - // Bail out early, as we only care about the return value for a dryrun. - return true; + if (Flags.useCpuTimeCapability()) { + // Do nothing, capability updated check will handle the dryrun output. + } else { + // Bail out early, as we only care about the return value for a dryrun. + return true; + } } } @@ -3273,10 +3313,25 @@ public class OomAdjuster { capability &= ~PROCESS_CAPABILITY_BFSL; } - if (dryRun && (adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup - || (capability != prevCapability - && (capability & prevCapability) == prevCapability))) { - return true; + if (dryRun) { + if (adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup) { + return true; + } + + if (Flags.useCpuTimeCapability()) { + if ((capability != prevCapability) + && ((capability & prevCapability) == prevCapability)) { + return true; + } + } else { + // Ignore PROCESS_CAPABILITY_CPU_TIME in capability comparison + final int curFiltered = capability & ~PROCESS_CAPABILITY_CPU_TIME; + final int prevFiltered = prevCapability & ~PROCESS_CAPABILITY_CPU_TIME; + if ((curFiltered != prevFiltered) + && ((curFiltered & prevFiltered) == prevFiltered)) { + return true; + } + } } if (adj < prevRawAdj) { @@ -3328,6 +3383,29 @@ public class OomAdjuster { return baseCapabilities | networkCapabilities; } + private static int getCpuCapability(ProcessRecord app, long nowUptime) { + final UidRecord uidRec = app.getUidRecord(); + if (uidRec != null && uidRec.isCurAllowListed()) { + // Process has user visible activities. + return PROCESS_CAPABILITY_CPU_TIME; + } + if (UserHandle.isCore(app.uid)) { + // Make sure all system components are not frozen. + return PROCESS_CAPABILITY_CPU_TIME; + } + if (app.mState.getCachedHasVisibleActivities()) { + // Process has user visible activities. + return PROCESS_CAPABILITY_CPU_TIME; + } + if (app.mServices.hasUndemotedShortForegroundService(nowUptime)) { + // It running a short fgs, just give it cpu time. + return PROCESS_CAPABILITY_CPU_TIME; + } + // TODO(b/370817323): Populate this method with all of the reasons to keep a process + // unfrozen. + return 0; + } + /** * @return the BFSL capability from a client (of a service binding or provider). */ @@ -3376,6 +3454,15 @@ public class OomAdjuster { } /** + * @return the CPU capability from a client (of a service binding or provider). + */ + private static int getCpuCapabilityFromClient(ProcessRecord client) { + // Just grant CPU capability every time + // TODO(b/370817323): Populate with reasons to not propagate cpu capability across bindings. + return client.mState.getCurCapability() & PROCESS_CAPABILITY_CPU_TIME; + } + + /** * Checks if for the given app and client, there's a cycle that should skip over the client * for now or use partial values to evaluate the effect of the client binding. * @param app @@ -3955,6 +4042,39 @@ public class OomAdjuster { mCacheOomRanker.dump(pw); } + /** + * Return whether or not a process should be frozen. + */ + boolean getFreezePolicy(ProcessRecord proc) { + // Reasons to not freeze: + if (Flags.useCpuTimeCapability()) { + if ((proc.mState.getCurCapability() & PROCESS_CAPABILITY_CPU_TIME) != 0) { + /// App is important enough (see {@link #getCpuCapability}) or bound by something + /// important enough to not be frozen. + return false; + } + } else { + // The CPU capability handling covers all setShouldNotFreeze paths. Must check + // shouldNotFreeze, if the CPU capability is not being used. + if (proc.mOptRecord.shouldNotFreeze()) { + return false; + } + } + + if (proc.mOptRecord.isFreezeExempt()) { + return false; + } + + // Reasons to freeze: + if (proc.mState.getCurAdj() >= FREEZER_CUTOFF_ADJ) { + // Oomscore is in a high enough state, it is safe to freeze. + return true; + } + + // Default, do not freeze a process. + return false; + } + @GuardedBy({"mService", "mProcLock"}) void updateAppFreezeStateLSP(ProcessRecord app, @OomAdjReason int oomAdjReason, boolean immediate, int oldOomAdj) { @@ -3969,43 +4089,44 @@ public class OomAdjuster { (state.getCurAdj() >= FREEZER_CUTOFF_ADJ ^ oldOomAdj >= FREEZER_CUTOFF_ADJ) || oldOomAdj == UNKNOWN_ADJ; final boolean shouldNotFreezeChanged = opt.shouldNotFreezeAdjSeq() == mAdjSeq; - if ((oomAdjChanged || shouldNotFreezeChanged) + final boolean hasCpuCapability = + (PROCESS_CAPABILITY_CPU_TIME & app.mState.getCurCapability()) + == PROCESS_CAPABILITY_CPU_TIME; + final boolean usedToHaveCpuCapability = + (PROCESS_CAPABILITY_CPU_TIME & app.mState.getSetCapability()) + == PROCESS_CAPABILITY_CPU_TIME; + final boolean cpuCapabilityChanged = hasCpuCapability != usedToHaveCpuCapability; + if ((oomAdjChanged || shouldNotFreezeChanged || cpuCapabilityChanged) && Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) { Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, CachedAppOptimizer.ATRACE_FREEZER_TRACK, "updateAppFreezeStateLSP " + app.processName + + " pid: " + app.getPid() + " isFreezeExempt: " + opt.isFreezeExempt() + " isFrozen: " + opt.isFrozen() + " shouldNotFreeze: " + opt.shouldNotFreeze() + " shouldNotFreezeReason: " + opt.shouldNotFreezeReason() + " curAdj: " + state.getCurAdj() + " oldOomAdj: " + oldOomAdj - + " immediate: " + immediate); + + " immediate: " + immediate + + " cpuCapability: " + hasCpuCapability); } } - if (app.mOptRecord.isFreezeExempt()) { - return; - } - - // if an app is already frozen and shouldNotFreeze becomes true, immediately unfreeze - if (opt.isFrozen() && opt.shouldNotFreeze()) { - mCachedAppOptimizer.unfreezeAppLSP(app, - CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason)); - return; - } - - // Use current adjustment when freezing, set adjustment when unfreezing. - if (state.getCurAdj() >= FREEZER_CUTOFF_ADJ && !opt.isFrozen() - && !opt.shouldNotFreeze()) { - if (!immediate) { - mCachedAppOptimizer.freezeAppAsyncLSP(app); - } else { + if (getFreezePolicy(app)) { + // This process should be frozen. + if (immediate && !opt.isFrozen()) { + // And it will be frozen immediately. mCachedAppOptimizer.freezeAppAsyncAtEarliestLSP(app); + } else if (!opt.isFrozen() || !opt.isPendingFreeze()) { + mCachedAppOptimizer.freezeAppAsyncLSP(app); + } + } else { + // This process should not be frozen. + if (opt.isFrozen() || opt.isPendingFreeze()) { + mCachedAppOptimizer.unfreezeAppLSP(app, + CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason)); } - } else if (state.getSetAdj() < FREEZER_CUTOFF_ADJ) { - mCachedAppOptimizer.unfreezeAppLSP(app, - CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason)); } } @@ -4029,7 +4150,8 @@ public class OomAdjuster { final int size = processes.size(); for (int i = 0; i < size; i++) { ProcessRecord proc = processes.get(i); - mCachedAppOptimizer.unfreezeTemporarily(proc, reason); + mCachedAppOptimizer.unfreezeTemporarily(proc, + CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(reason)); } processes.clear(); } diff --git a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java index 8b660559f550..1b7e8f0bd244 100644 --- a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java +++ b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java @@ -758,8 +758,9 @@ public class OomAdjusterModernImpl extends OomAdjuster { OomAdjusterModernImpl(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, ServiceThread adjusterThread, GlobalState globalState, - Injector injector) { - super(service, processList, activeUids, adjusterThread, globalState, injector); + CachedAppOptimizer cachedAppOptimizer, Injector injector) { + super(service, processList, activeUids, adjusterThread, globalState, cachedAppOptimizer, + injector); } private final ProcessRecordNodes mProcessRecordProcStateNodes = new ProcessRecordNodes( diff --git a/services/core/java/com/android/server/am/ProcessServiceRecord.java b/services/core/java/com/android/server/am/ProcessServiceRecord.java index 5cb8b954a2ba..364497491785 100644 --- a/services/core/java/com/android/server/am/ProcessServiceRecord.java +++ b/services/core/java/com/android/server/am/ProcessServiceRecord.java @@ -256,18 +256,24 @@ final class ProcessServiceRecord { } // Now we need to look at all short-FGS within the process and see if all of them are // procstate-timed-out or not. + return !hasUndemotedShortForegroundService(nowUptime); + } + + boolean hasUndemotedShortForegroundService(long nowUptime) { for (int i = mServices.size() - 1; i >= 0; i--) { final ServiceRecord sr = mServices.valueAt(i); if (!sr.isShortFgs() || !sr.hasShortFgsInfo()) { continue; } if (sr.getShortFgsInfo().getProcStateDemoteTime() >= nowUptime) { - return false; + // This short fgs has not timed out yet. + return true; } } - return true; + return false; } + int getReportedForegroundServiceTypes() { return mRepFgServiceTypes; } diff --git a/services/core/java/com/android/server/am/ProcessStateController.java b/services/core/java/com/android/server/am/ProcessStateController.java index 01468c640f6c..57899228e6ad 100644 --- a/services/core/java/com/android/server/am/ProcessStateController.java +++ b/services/core/java/com/android/server/am/ProcessStateController.java @@ -29,6 +29,7 @@ import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.server.ServiceThread; /** @@ -44,13 +45,14 @@ public class ProcessStateController { private final GlobalState mGlobalState = new GlobalState(); private ProcessStateController(ActivityManagerService ams, ProcessList processList, - ActiveUids activeUids, ServiceThread handlerThread, OomAdjuster.Injector oomAdjInjector, + ActiveUids activeUids, ServiceThread handlerThread, + CachedAppOptimizer cachedAppOptimizer, OomAdjuster.Injector oomAdjInjector, boolean useOomAdjusterModernImpl) { mOomAdjuster = useOomAdjusterModernImpl ? new OomAdjusterModernImpl(ams, processList, activeUids, handlerThread, - mGlobalState, oomAdjInjector) + mGlobalState, cachedAppOptimizer, oomAdjInjector) : new OomAdjuster(ams, processList, activeUids, handlerThread, mGlobalState, - oomAdjInjector); + cachedAppOptimizer, oomAdjInjector); } /** @@ -594,6 +596,7 @@ public class ProcessStateController { private final ActiveUids mActiveUids; private ServiceThread mHandlerThread = null; + private CachedAppOptimizer mCachedAppOptimizer = null; private OomAdjuster.Injector mOomAdjInjector = null; private boolean mUseOomAdjusterModernImpl = false; @@ -610,24 +613,38 @@ public class ProcessStateController { if (mHandlerThread == null) { mHandlerThread = OomAdjuster.createAdjusterThread(); } + if (mCachedAppOptimizer == null) { + mCachedAppOptimizer = new CachedAppOptimizer(mAms); + } if (mOomAdjInjector == null) { mOomAdjInjector = new OomAdjuster.Injector(); } return new ProcessStateController(mAms, mProcessList, mActiveUids, mHandlerThread, - mOomAdjInjector, mUseOomAdjusterModernImpl); + mCachedAppOptimizer, mOomAdjInjector, mUseOomAdjusterModernImpl); } /** * For Testing Purposes. Set what thread OomAdjuster will offload tasks on to. */ + @VisibleForTesting public Builder setHandlerThread(ServiceThread handlerThread) { mHandlerThread = handlerThread; return this; } /** + * For Testing Purposes. Set the CachedAppOptimzer used by OomAdjuster. + */ + @VisibleForTesting + public Builder setCachedAppOptimizer(CachedAppOptimizer cachedAppOptimizer) { + mCachedAppOptimizer = cachedAppOptimizer; + return this; + } + + /** * For Testing Purposes. Set an injector for OomAdjuster. */ + @VisibleForTesting public Builder setOomAdjusterInjector(OomAdjuster.Injector injector) { mOomAdjInjector = injector; return this; diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index 3dd5ec9a3834..ef5296eef492 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -221,6 +221,7 @@ public class SettingsToPropertiesMapper { "preload_safety", "printing", "privacy_infra_policy", + "psap_ai", "ravenwood", "resource_manager", "responsible_apis", diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig index 8395685349e4..711b163ea424 100644 --- a/services/core/java/com/android/server/am/flags.aconfig +++ b/services/core/java/com/android/server/am/flags.aconfig @@ -253,3 +253,10 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "use_cpu_time_capability" + namespace: "backstage_power" + description: "Use PROCESS_CAPABILITY_CPU_TIME to control unfreeze state." + bug: "370817323" +} diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java index e8fa41749473..afdc0c0294a6 100644 --- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java +++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java @@ -119,9 +119,16 @@ class PreAuthInfo { == BiometricManager.Authenticators.IDENTITY_CHECK; boolean isMandatoryBiometricsAuthentication = false; + final int effectiveUserId; + if (Flags.effectiveUserBp()) { + effectiveUserId = userManager.getCredentialOwnerProfile(userId); + } else { + effectiveUserId = userId; + } + if (dropCredentialFallback(promptInfo.getAuthenticators(), settingObserver.getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser( - userId), trustManager)) { + effectiveUserId), trustManager)) { isMandatoryBiometricsAuthentication = true; promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG); if (promptInfo.getNegativeButtonText() == null) { @@ -145,13 +152,6 @@ class PreAuthInfo { final List<BiometricSensor> eligibleSensors = new ArrayList<>(); final List<Pair<BiometricSensor, Integer>> ineligibleSensors = new ArrayList<>(); - final int effectiveUserId; - if (Flags.effectiveUserBp()) { - effectiveUserId = userManager.getCredentialOwnerProfile(userId); - } else { - effectiveUserId = userId; - } - if (biometricRequested) { for (BiometricSensor sensor : sensors) { diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 5a2610b00772..abb756b294a3 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -2460,6 +2460,15 @@ public final class DisplayManagerService extends SystemService { DisplayManagerGlobal.EVENT_DISPLAY_HDR_SDR_RATIO_CHANGED); } + private void handleLogicalDisplayRefreshRateChangedLocked(@NonNull LogicalDisplay display) { + sendDisplayEventIfEnabledLocked(display, + DisplayManagerGlobal.EVENT_DISPLAY_REFRESH_RATE_CHANGED); + } + + private void handleLogicalDisplayStateChangedLocked(@NonNull LogicalDisplay display) { + sendDisplayEventIfEnabledLocked(display, DisplayManagerGlobal.EVENT_DISPLAY_STATE_CHANGED); + } + private void notifyDefaultDisplayDeviceUpdated(LogicalDisplay display) { mDisplayModeDirector.defaultDisplayDeviceUpdated(display.getPrimaryDisplayDeviceLocked() .mDisplayDeviceConfig); @@ -3991,6 +4000,12 @@ public final class DisplayManagerService extends SystemService { case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_DISCONNECTED: handleLogicalDisplayDisconnectedLocked(display); break; + case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REFRESH_RATE_CHANGED: + handleLogicalDisplayRefreshRateChangedLocked(display); + break; + case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_STATE_CHANGED: + handleLogicalDisplayStateChangedLocked(display); + break; } } @@ -4198,6 +4213,13 @@ public final class DisplayManagerService extends SystemService { return (mask & DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0; + case DisplayManagerGlobal.EVENT_DISPLAY_REFRESH_RATE_CHANGED: + return (mask + & DisplayManagerGlobal + .INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE) != 0; + case DisplayManagerGlobal.EVENT_DISPLAY_STATE_CHANGED: + return (mask & DisplayManagerGlobal + .INTERNAL_EVENT_FLAG_DISPLAY_STATE) != 0; default: // This should never happen. Slog.e(TAG, "Unknown display event " + event); diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index 09fa4e6aa628..c0903a9bafac 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -79,15 +79,18 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { // 'adb shell setprop persist.log.tag.LogicalDisplayMapper DEBUG && adb reboot' private static final boolean DEBUG = DebugUtils.isDebuggable(TAG); - public static final int LOGICAL_DISPLAY_EVENT_ADDED = 1; - public static final int LOGICAL_DISPLAY_EVENT_CHANGED = 2; - public static final int LOGICAL_DISPLAY_EVENT_REMOVED = 3; - public static final int LOGICAL_DISPLAY_EVENT_SWAPPED = 4; - public static final int LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED = 5; - public static final int LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION = 6; - public static final int LOGICAL_DISPLAY_EVENT_HDR_SDR_RATIO_CHANGED = 7; - public static final int LOGICAL_DISPLAY_EVENT_CONNECTED = 8; - public static final int LOGICAL_DISPLAY_EVENT_DISCONNECTED = 9; + public static final int LOGICAL_DISPLAY_EVENT_BASE = 0; + public static final int LOGICAL_DISPLAY_EVENT_ADDED = 1 << 0; + public static final int LOGICAL_DISPLAY_EVENT_CHANGED = 1 << 1; + public static final int LOGICAL_DISPLAY_EVENT_REMOVED = 1 << 2; + public static final int LOGICAL_DISPLAY_EVENT_SWAPPED = 1 << 3; + public static final int LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED = 1 << 4; + public static final int LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION = 1 << 5; + public static final int LOGICAL_DISPLAY_EVENT_HDR_SDR_RATIO_CHANGED = 1 << 6; + public static final int LOGICAL_DISPLAY_EVENT_CONNECTED = 1 << 7; + public static final int LOGICAL_DISPLAY_EVENT_DISCONNECTED = 1 << 8; + public static final int LOGICAL_DISPLAY_EVENT_REFRESH_RATE_CHANGED = 1 << 9; + public static final int LOGICAL_DISPLAY_EVENT_STATE_CHANGED = 1 << 10; public static final int DISPLAY_GROUP_EVENT_ADDED = 1; public static final int DISPLAY_GROUP_EVENT_CHANGED = 2; @@ -804,6 +807,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { final boolean wasPreviouslyUpdated = updateState != UPDATE_STATE_NEW; final boolean wasPreviouslyEnabled = mDisplaysEnabledCache.get(displayId); final boolean isCurrentlyEnabled = display.isEnabledLocked(); + int logicalDisplayEventMask = mLogicalDisplaysToUpdate + .get(displayId, LOGICAL_DISPLAY_EVENT_BASE); // The display is no longer valid and needs to be removed. if (!display.isValidLocked()) { @@ -821,20 +826,20 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { if (mDisplaysEnabledCache.get(displayId)) { // We still need to send LOGICAL_DISPLAY_EVENT_DISCONNECTED reloop = true; - mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_REMOVED); + logicalDisplayEventMask |= LOGICAL_DISPLAY_EVENT_REMOVED; } else { mUpdatedLogicalDisplays.delete(displayId); - mLogicalDisplaysToUpdate.put(displayId, - LOGICAL_DISPLAY_EVENT_DISCONNECTED); + logicalDisplayEventMask |= LOGICAL_DISPLAY_EVENT_DISCONNECTED; } } else { mUpdatedLogicalDisplays.delete(displayId); - mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_REMOVED); + logicalDisplayEventMask |= LOGICAL_DISPLAY_EVENT_REMOVED; } } else { // This display never left this class, safe to remove without notification mLogicalDisplays.removeAt(i); } + mLogicalDisplaysToUpdate.put(displayId, logicalDisplayEventMask); continue; // The display is new. @@ -842,38 +847,40 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { if (mFlags.isConnectedDisplayManagementEnabled()) { // We still need to send LOGICAL_DISPLAY_EVENT_ADDED reloop = true; - mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_CONNECTED); + logicalDisplayEventMask |= LOGICAL_DISPLAY_EVENT_CONNECTED; } else { - mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_ADDED); + logicalDisplayEventMask |= LOGICAL_DISPLAY_EVENT_ADDED; } // Underlying displays device has changed to a different one. } else if (!TextUtils.equals(mTempDisplayInfo.uniqueId, newDisplayInfo.uniqueId)) { - mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_SWAPPED); + logicalDisplayEventMask |= LOGICAL_DISPLAY_EVENT_SWAPPED; // Something about the display device has changed. } else if (mFlags.isConnectedDisplayManagementEnabled() && wasPreviouslyEnabled != isCurrentlyEnabled) { int event = isCurrentlyEnabled ? LOGICAL_DISPLAY_EVENT_ADDED : LOGICAL_DISPLAY_EVENT_REMOVED; - mLogicalDisplaysToUpdate.put(displayId, event); + logicalDisplayEventMask |= event; } else if (wasDirty || !mTempDisplayInfo.equals(newDisplayInfo)) { // If only the hdr/sdr ratio changed, then send just the event for that case if ((diff == DisplayDeviceInfo.DIFF_HDR_SDR_RATIO)) { - mLogicalDisplaysToUpdate.put(displayId, - LOGICAL_DISPLAY_EVENT_HDR_SDR_RATIO_CHANGED); + logicalDisplayEventMask |= LOGICAL_DISPLAY_EVENT_HDR_SDR_RATIO_CHANGED; } else { - mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_CHANGED); + logicalDisplayEventMask |= LOGICAL_DISPLAY_EVENT_CHANGED; } - // The display is involved in a display layout transition + if (mFlags.isDisplayListenerPerformanceImprovementsEnabled()) { + logicalDisplayEventMask + |= updateAndGetMaskForDisplayPropertyChanges(newDisplayInfo); + } + + // The display is involved in a display layout transition } else if (updateState == UPDATE_STATE_TRANSITION) { - mLogicalDisplaysToUpdate.put(displayId, - LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION); + logicalDisplayEventMask |= LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION; // Display frame rate overrides changed. } else if (!display.getPendingFrameRateOverrideUids().isEmpty()) { - mLogicalDisplaysToUpdate.put( - displayId, LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED); + logicalDisplayEventMask |= LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED; // Non-override display values changed. } else { @@ -882,10 +889,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { // things like display cutouts. display.getNonOverrideDisplayInfoLocked(mTempDisplayInfo); if (!mTempNonOverrideDisplayInfo.equals(mTempDisplayInfo)) { - mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_CHANGED); + logicalDisplayEventMask |= LOGICAL_DISPLAY_EVENT_CHANGED; } } - + mLogicalDisplaysToUpdate.put(displayId, logicalDisplayEventMask); mUpdatedLogicalDisplays.put(displayId, UPDATE_STATE_UPDATED); } @@ -922,6 +929,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_DISCONNECTED); } sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_CHANGED); + sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_REFRESH_RATE_CHANGED); + sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_STATE_CHANGED); sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED); sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_SWAPPED); if (mFlags.isConnectedDisplayManagementEnabled()) { @@ -944,13 +953,25 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { } } + @VisibleForTesting + int updateAndGetMaskForDisplayPropertyChanges(DisplayInfo newDisplayInfo) { + int mask = LOGICAL_DISPLAY_EVENT_BASE; + if (mTempDisplayInfo.getRefreshRate() != newDisplayInfo.getRefreshRate()) { + mask |= LOGICAL_DISPLAY_EVENT_REFRESH_RATE_CHANGED; + } + + if (mTempDisplayInfo.state != newDisplayInfo.state) { + mask |= LOGICAL_DISPLAY_EVENT_STATE_CHANGED; + } + return mask; + } /** * Send the specified message for all relevant displays in the specified display-to-message map. */ - private void sendUpdatesForDisplaysLocked(int msg) { + private void sendUpdatesForDisplaysLocked(int logicalDisplayEvent) { for (int i = mLogicalDisplaysToUpdate.size() - 1; i >= 0; --i) { - final int currMsg = mLogicalDisplaysToUpdate.valueAt(i); - if (currMsg != msg) { + final int logicalDisplayEventMask = mLogicalDisplaysToUpdate.valueAt(i); + if ((logicalDisplayEventMask & logicalDisplayEvent) == 0) { continue; } @@ -959,25 +980,25 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { if (DEBUG) { final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); final String uniqueId = device == null ? "null" : device.getUniqueId(); - Slog.d(TAG, "Sending " + displayEventToString(msg) + " for display=" + id - + " with device=" + uniqueId); + Slog.d(TAG, "Sending " + displayEventToString(logicalDisplayEvent) + " for " + + "display=" + id + " with device=" + uniqueId); } if (mFlags.isConnectedDisplayManagementEnabled()) { - if (msg == LOGICAL_DISPLAY_EVENT_ADDED) { + if (logicalDisplayEvent == LOGICAL_DISPLAY_EVENT_ADDED) { mDisplaysEnabledCache.put(id, true); - } else if (msg == LOGICAL_DISPLAY_EVENT_REMOVED) { + } else if (logicalDisplayEvent == LOGICAL_DISPLAY_EVENT_REMOVED) { mDisplaysEnabledCache.delete(id); } } - mListener.onLogicalDisplayEventLocked(display, msg); + mListener.onLogicalDisplayEventLocked(display, logicalDisplayEvent); if (mFlags.isConnectedDisplayManagementEnabled()) { - if (msg == LOGICAL_DISPLAY_EVENT_DISCONNECTED) { + if (logicalDisplayEvent == LOGICAL_DISPLAY_EVENT_DISCONNECTED) { mLogicalDisplays.delete(id); } - } else if (msg == LOGICAL_DISPLAY_EVENT_REMOVED) { + } else if (logicalDisplayEvent == LOGICAL_DISPLAY_EVENT_REMOVED) { // We wait until we sent the EVENT_REMOVED event before actually removing the // display. mLogicalDisplays.delete(id); @@ -1348,6 +1369,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { return "connected"; case LOGICAL_DISPLAY_EVENT_DISCONNECTED: return "disconnected"; + case LOGICAL_DISPLAY_EVENT_STATE_CHANGED: + return "state_changed"; + case LOGICAL_DISPLAY_EVENT_REFRESH_RATE_CHANGED: + return "refresh_rate_changed"; } return null; } diff --git a/services/core/java/com/android/server/display/OWNERS b/services/core/java/com/android/server/display/OWNERS index 9439eaa3a4c6..9f0cabfd9208 100644 --- a/services/core/java/com/android/server/display/OWNERS +++ b/services/core/java/com/android/server/display/OWNERS @@ -1,5 +1,4 @@ michaelwr@google.com -dangittik@google.com hackbod@google.com ogunwale@google.com santoscordon@google.com @@ -7,5 +6,6 @@ flc@google.com wilczynskip@google.com brup@google.com petsjonkin@google.com +olb@google.com per-file ColorDisplayService.java=christyfranks@google.com diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java index 71f17d1f411e..1a7d74ae1713 100644 --- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java @@ -246,6 +246,10 @@ public class DisplayManagerFlags { Flags.FLAG_ENABLE_PLUGIN_MANAGER, Flags::enablePluginManager ); + private final FlagState mDisplayListenerPerformanceImprovementsFlagState = new FlagState( + Flags.FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS, + Flags::displayListenerPerformanceImprovements + ); /** * @return {@code true} if 'port' is allowed in display layout configuration file. @@ -527,6 +531,13 @@ public class DisplayManagerFlags { } /** + * @return {@code true} if the flag for display listener performance improvements is enabled + */ + public boolean isDisplayListenerPerformanceImprovementsEnabled() { + return mDisplayListenerPerformanceImprovementsFlagState.isEnabled(); + } + + /** * dumps all flagstates * @param pw printWriter */ @@ -578,6 +589,7 @@ public class DisplayManagerFlags { pw.println(" " + mHasArrSupport); pw.println(" " + mAutoBrightnessModeBedtimeWearFlagState); pw.println(" " + mEnablePluginManagerFlagState); + pw.println(" " + mDisplayListenerPerformanceImprovementsFlagState); } private static class FlagState { diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig index 7850360c7dbf..586d59492f57 100644 --- a/services/core/java/com/android/server/display/feature/display_flags.aconfig +++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig @@ -440,6 +440,14 @@ flag { } flag { + name: "display_listener_performance_improvements" + namespace: "display_manager" + description: "Feature flag for an API to let the apps subscribe to a specific property change of the Display." + bug: "372700957" + is_fixed_read_only: true +} + +flag { name: "enable_get_supported_refresh_rates" namespace: "core_graphics" description: "Flag to use the surfaceflinger rates for getSupportedRefreshRates" @@ -454,3 +462,11 @@ flag { bug: "354059797" is_fixed_read_only: true } + +flag { + name: "enable_display_content_mode_management" + namespace: "lse_desktop_experience" + description: "Enable switching the content mode of connected displays between mirroring and extened. Also change the default content mode to extended mode." + bug: "378385869" + is_fixed_read_only: true +} diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index f4dd71706761..82449ce89c2c 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -623,9 +623,10 @@ public class InputManagerService extends IInputManager.Stub mKeyRemapper.systemRunning(); mPointerIconCache.systemRunning(); mKeyboardGlyphManager.systemRunning(); - mKeyGestureController.systemRunning(); - - initKeyGestures(); + if (useKeyGestureEventHandler()) { + mKeyGestureController.systemRunning(); + initKeyGestures(); + } } private void reloadDeviceAliases() { @@ -2608,9 +2609,6 @@ public class InputManagerService extends IInputManager.Stub } private void initKeyGestures() { - if (!useKeyGestureEventHandler()) { - return; - } InputManager im = Objects.requireNonNull(mContext.getSystemService(InputManager.class)); im.registerKeyGestureEventHandler(new InputManager.KeyGestureEventHandler() { @Override diff --git a/services/core/java/com/android/server/input/KeyboardBacklightController.java b/services/core/java/com/android/server/input/KeyboardBacklightController.java index c3205afe14f2..0defd27eaae2 100644 --- a/services/core/java/com/android/server/input/KeyboardBacklightController.java +++ b/services/core/java/com/android/server/input/KeyboardBacklightController.java @@ -20,6 +20,7 @@ import android.animation.ValueAnimator; import android.annotation.BinderThread; import android.annotation.Nullable; import android.content.Context; +import android.content.res.Resources; import android.graphics.Color; import android.hardware.input.IKeyboardBacklightListener; import android.hardware.input.IKeyboardBacklightState; @@ -81,9 +82,6 @@ final class KeyboardBacklightController implements private static final String UEVENT_KEYBOARD_BACKLIGHT_TAG = "kbd_backlight"; @VisibleForTesting - static final long USER_INACTIVITY_THRESHOLD_MILLIS = Duration.ofSeconds(30).toMillis(); - - @VisibleForTesting static final int[] DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL = new int[DEFAULT_NUM_BRIGHTNESS_CHANGE_STEPS + 1]; @@ -112,6 +110,7 @@ final class KeyboardBacklightController implements private AmbientKeyboardBacklightController.AmbientKeyboardBacklightListener mAmbientListener; private int mAmbientBacklightValue = 0; + private final int mUserInactivityThresholdMs; static { // Fixed brightness levels to avoid issues when converting back and forth from the @@ -139,6 +138,9 @@ final class KeyboardBacklightController implements mAnimatorFactory = animatorFactory; mAmbientController = new AmbientKeyboardBacklightController(context, looper); mUEventManager = uEventManager; + Resources res = mContext.getResources(); + mUserInactivityThresholdMs = res.getInteger( + com.android.internal.R.integer.config_keyboardBacklightTimeoutMs); } @Override @@ -300,7 +302,7 @@ final class KeyboardBacklightController implements } mHandler.removeMessages(MSG_NOTIFY_USER_INACTIVITY); mHandler.sendEmptyMessageAtTime(MSG_NOTIFY_USER_INACTIVITY, - SystemClock.uptimeMillis() + USER_INACTIVITY_THRESHOLD_MILLIS); + SystemClock.uptimeMillis() + mUserInactivityThresholdMs); } private void handleUserInactivity() { diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java index bb4ae96da53b..a132876b72a3 100644 --- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java +++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java @@ -46,7 +46,6 @@ import android.util.Slog; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; -import com.android.server.integrity.model.RuleMetadata; import java.io.File; import java.nio.charset.StandardCharsets; diff --git a/services/core/java/com/android/server/integrity/model/BitInputStream.java b/services/core/java/com/android/server/integrity/model/BitInputStream.java deleted file mode 100644 index e7cc81eab26b..000000000000 --- a/services/core/java/com/android/server/integrity/model/BitInputStream.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.model; - -import java.io.IOException; -import java.io.InputStream; - -/** A wrapper class for reading a stream of bits. - * - * <p>Note: this class reads from underlying stream byte-by-byte. It is advised to apply buffering - * to underlying streams. - */ -public class BitInputStream { - - private long mBitsRead; - - private InputStream mInputStream; - - private byte mCurrentByte; - - public BitInputStream(InputStream inputStream) { - mInputStream = inputStream; - } - - /** - * Read the next number of bits from the stream. - * - * @param numOfBits The number of bits to read. - * @return The value read from the stream. - */ - public int getNext(int numOfBits) throws IOException { - int component = 0; - int count = 0; - - while (count++ < numOfBits) { - if (mBitsRead % 8 == 0) { - mCurrentByte = getNextByte(); - } - int offset = 7 - (int) (mBitsRead % 8); - - component <<= 1; - component |= (mCurrentByte >>> offset) & 1; - - mBitsRead++; - } - - return component; - } - - /** Check if there are bits left in the stream. */ - public boolean hasNext() throws IOException { - return mInputStream.available() > 0; - } - - private byte getNextByte() throws IOException { - return (byte) mInputStream.read(); - } -} diff --git a/services/core/java/com/android/server/integrity/model/BitOutputStream.java b/services/core/java/com/android/server/integrity/model/BitOutputStream.java deleted file mode 100644 index 14b35fd016eb..000000000000 --- a/services/core/java/com/android/server/integrity/model/BitOutputStream.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.model; - -import static com.android.server.integrity.model.ComponentBitSize.BYTE_BITS; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Arrays; - -/** A wrapper class for writing a stream of bits. */ -public class BitOutputStream { - - private static final int BUFFER_SIZE = 4 * 1024; - - private int mNextBitIndex; - - private final OutputStream mOutputStream; - private final byte[] mBuffer; - - public BitOutputStream(OutputStream outputStream) { - mBuffer = new byte[BUFFER_SIZE]; - mNextBitIndex = 0; - mOutputStream = outputStream; - } - - /** - * Set the next number of bits in the stream to value. - * - * @param numOfBits The number of bits used to represent the value. - * @param value The value to convert to bits. - */ - public void setNext(int numOfBits, int value) throws IOException { - if (numOfBits <= 0) { - return; - } - - // optional: we can do some clever size checking to "OR" an entire segment of bits instead - // of setting bits one by one, but it is probably not worth it. - int nextBitMask = 1 << (numOfBits - 1); - while (numOfBits-- > 0) { - setNext((value & nextBitMask) != 0); - nextBitMask >>>= 1; - } - } - - /** - * Set the next bit in the stream to value. - * - * @param value The value to set the bit to - */ - public void setNext(boolean value) throws IOException { - int byteToWrite = mNextBitIndex / BYTE_BITS; - if (byteToWrite == BUFFER_SIZE) { - mOutputStream.write(mBuffer); - reset(); - byteToWrite = 0; - } - if (value) { - mBuffer[byteToWrite] |= 1 << (BYTE_BITS - 1 - (mNextBitIndex % BYTE_BITS)); - } - mNextBitIndex++; - } - - /** Set the next bit in the stream to true. */ - public void setNext() throws IOException { - setNext(/* value= */ true); - } - - /** - * Flush the data written to the underlying {@link java.io.OutputStream}. Any unfinished bytes - * will be padded with 0. - */ - public void flush() throws IOException { - int endByte = mNextBitIndex / BYTE_BITS; - if (mNextBitIndex % BYTE_BITS != 0) { - // If next bit is not the first bit of a byte, then mNextBitIndex / BYTE_BITS would be - // the byte that includes already written bits. We need to increment it so this byte - // gets written. - endByte++; - } - mOutputStream.write(mBuffer, 0, endByte); - reset(); - } - - /** Reset this output stream to start state. */ - private void reset() { - mNextBitIndex = 0; - Arrays.fill(mBuffer, (byte) 0); - } -} diff --git a/services/core/java/com/android/server/integrity/model/ByteTrackedOutputStream.java b/services/core/java/com/android/server/integrity/model/ByteTrackedOutputStream.java deleted file mode 100644 index ceed054e4a53..000000000000 --- a/services/core/java/com/android/server/integrity/model/ByteTrackedOutputStream.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.model; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * An output stream that tracks the total number written bytes since construction and allows - * querying this value any time during the execution. - * - * <p>This class is used for constructing the rule indexing. - */ -public class ByteTrackedOutputStream extends OutputStream { - - private int mWrittenBytesCount; - private final OutputStream mOutputStream; - - public ByteTrackedOutputStream(OutputStream outputStream) { - mWrittenBytesCount = 0; - mOutputStream = outputStream; - } - - @Override - public void write(int b) throws IOException { - mWrittenBytesCount++; - mOutputStream.write(b); - } - - /** - * Writes the given bytes into the output stream provided in constructor and updates the total - * number of written bytes. - */ - @Override - public void write(byte[] bytes) throws IOException { - write(bytes, 0, bytes.length); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - mWrittenBytesCount += len; - mOutputStream.write(b, off, len); - } - - /** Returns the total number of bytes written into the output stream at the requested time. */ - public int getWrittenBytesCount() { - return mWrittenBytesCount; - } -} diff --git a/services/core/java/com/android/server/integrity/model/ComponentBitSize.java b/services/core/java/com/android/server/integrity/model/ComponentBitSize.java deleted file mode 100644 index 94e6708c3038..000000000000 --- a/services/core/java/com/android/server/integrity/model/ComponentBitSize.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.model; - -import android.content.integrity.Rule; - -/** - * A helper class containing information about the binary representation of different {@link Rule} - * components. - */ -public final class ComponentBitSize { - public static final int FORMAT_VERSION_BITS = 8; - - public static final int EFFECT_BITS = 3; - public static final int KEY_BITS = 4; - public static final int OPERATOR_BITS = 3; - public static final int CONNECTOR_BITS = 2; - public static final int SEPARATOR_BITS = 3; - public static final int VALUE_SIZE_BITS = 8; - public static final int IS_HASHED_BITS = 1; - - public static final int ATOMIC_FORMULA_START = 0; - public static final int COMPOUND_FORMULA_START = 1; - public static final int COMPOUND_FORMULA_END = 2; - public static final int INSTALLER_ALLOWED_BY_MANIFEST_START = 3; - - public static final int DEFAULT_FORMAT_VERSION = 1; - public static final int SIGNAL_BIT = 1; - - public static final int BYTE_BITS = 8; -} diff --git a/services/core/java/com/android/server/integrity/model/IntegrityCheckResult.java b/services/core/java/com/android/server/integrity/model/IntegrityCheckResult.java deleted file mode 100644 index b0647fc46473..000000000000 --- a/services/core/java/com/android/server/integrity/model/IntegrityCheckResult.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.model; - -import android.annotation.Nullable; -import android.content.integrity.Rule; - -import java.util.Collections; -import java.util.List; - -/** - * A class encapsulating the result from the evaluation engine after evaluating rules against app - * install metadata. - * - * <p>It contains the outcome effect (whether to allow or block the install), and the rule causing - * that effect. - */ -public final class IntegrityCheckResult { - - public enum Effect { - ALLOW, - DENY - } - - private final Effect mEffect; - private final List<Rule> mRuleList; - - private IntegrityCheckResult(Effect effect, @Nullable List<Rule> ruleList) { - this.mEffect = effect; - this.mRuleList = ruleList; - } - - public Effect getEffect() { - return mEffect; - } - - public List<Rule> getMatchedRules() { - return mRuleList; - } - - /** - * Create an ALLOW evaluation outcome. - * - * @return An evaluation outcome with ALLOW effect and no rule. - */ - public static IntegrityCheckResult allow() { - return new IntegrityCheckResult(Effect.ALLOW, Collections.emptyList()); - } - - /** - * Create an ALLOW evaluation outcome. - * - * @return An evaluation outcome with ALLOW effect and rule causing that effect. - */ - public static IntegrityCheckResult allow(List<Rule> ruleList) { - return new IntegrityCheckResult(Effect.ALLOW, ruleList); - } - - /** - * Create a DENY evaluation outcome. - * - * @param ruleList All valid rules that cause the DENY effect. - * @return An evaluation outcome with DENY effect and rule causing that effect. - */ - public static IntegrityCheckResult deny(List<Rule> ruleList) { - return new IntegrityCheckResult(Effect.DENY, ruleList); - } - - /** Returns true when the {@code mEffect} is caused by an app certificate mismatch. */ - public boolean isCausedByAppCertRule() { - return mRuleList.stream().anyMatch(rule -> rule.getFormula().isAppCertificateFormula()); - } - - /** Returns true when the {@code mEffect} is caused by an installer rule. */ - public boolean isCausedByInstallerRule() { - return mRuleList.stream().anyMatch(rule -> rule.getFormula().isInstallerFormula()); - } - -} diff --git a/services/core/java/com/android/server/integrity/model/RuleMetadata.java b/services/core/java/com/android/server/integrity/model/RuleMetadata.java deleted file mode 100644 index 6b582ae7b5f2..000000000000 --- a/services/core/java/com/android/server/integrity/model/RuleMetadata.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.model; - -import android.annotation.Nullable; - -/** Data class containing relevant metadata associated with a rule set. */ -public class RuleMetadata { - - private final String mRuleProvider; - private final String mVersion; - - public RuleMetadata(String ruleProvider, String version) { - mRuleProvider = ruleProvider; - mVersion = version; - } - - @Nullable - public String getRuleProvider() { - return mRuleProvider; - } - - @Nullable - public String getVersion() { - return mVersion; - } -} diff --git a/services/core/java/com/android/server/location/contexthub/OWNERS b/services/core/java/com/android/server/location/contexthub/OWNERS index c62e3237e487..6536ca084421 100644 --- a/services/core/java/com/android/server/location/contexthub/OWNERS +++ b/services/core/java/com/android/server/location/contexthub/OWNERS @@ -1,3 +1,4 @@ bduddie@google.com +arthuri@google.com matthewsedam@google.com stange@google.com diff --git a/services/core/java/com/android/server/media/quality/MediaQualityDbHelper.java b/services/core/java/com/android/server/media/quality/MediaQualityDbHelper.java new file mode 100644 index 000000000000..04f6216694a9 --- /dev/null +++ b/services/core/java/com/android/server/media/quality/MediaQualityDbHelper.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.media.quality; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.media.quality.MediaQualityContract.BaseParameters; + +public class MediaQualityDbHelper extends SQLiteOpenHelper { + + private static final String TAG = "MediaQualityDbHelper"; + + static final int DATABASE_VERSION_1 = 1; + private static final String DATABASE_NAME = "media_quality.db"; + public static final String PICTURE_QUALITY_TABLE_NAME = "picture_quality"; + public static final String SOUND_QUALITY_TABLE_NAME = "sound_quality"; + public static final String SETTINGS = "settings"; + + MediaQualityDbHelper(Context context) { + super(context, DATABASE_NAME, null, getDbVersion()); + } + + private static int getDbVersion() { + return DATABASE_VERSION_1; + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL(getTableCreateStatement(PICTURE_QUALITY_TABLE_NAME)); + db.execSQL(getTableCreateStatement(SOUND_QUALITY_TABLE_NAME)); + } + + private String getTableCreateStatement(String tableName) { + return + "CREATE TABLE " + tableName + "(" + + BaseParameters.PARAMETER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + + BaseParameters.PARAMETER_TYPE + " INTEGER," + + BaseParameters.PARAMETER_NAME + " STRING," + + BaseParameters.PARAMETER_PACKAGE + " STRING," + + BaseParameters.PARAMETER_INPUT_ID + " STRING," + + SETTINGS + " TEXT)"; + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + // to do + } + +} diff --git a/services/core/java/com/android/server/media/quality/MediaQualityService.java b/services/core/java/com/android/server/media/quality/MediaQualityService.java index 21ae1820f6f7..c5c8a5ea9d82 100644 --- a/services/core/java/com/android/server/media/quality/MediaQualityService.java +++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java @@ -16,20 +16,31 @@ package com.android.server.media.quality; +import android.content.ContentValues; import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; import android.media.quality.AmbientBacklightSettings; import android.media.quality.IAmbientBacklightCallback; import android.media.quality.IMediaQualityManager; import android.media.quality.IPictureProfileCallback; import android.media.quality.ISoundProfileCallback; +import android.media.quality.MediaQualityContract.PictureQuality; import android.media.quality.ParamCapability; import android.media.quality.PictureProfile; import android.media.quality.SoundProfile; +import android.os.Bundle; +import android.util.Log; import com.android.server.SystemService; +import org.json.JSONException; +import org.json.JSONObject; + import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.Locale; /** * This service manage picture profile and sound profile for TV setting. Also communicates with the @@ -40,10 +51,14 @@ public class MediaQualityService extends SystemService { private static final boolean DEBUG = false; private static final String TAG = "MediaQualityService"; private final Context mContext; + private final MediaQualityDbHelper mMediaQualityDbHelper; public MediaQualityService(Context context) { super(context); mContext = context; + mMediaQualityDbHelper = new MediaQualityDbHelper(mContext); + mMediaQualityDbHelper.setWriteAheadLoggingEnabled(true); + mMediaQualityDbHelper.setIdleConnectionTimeout(30); } @Override @@ -53,11 +68,23 @@ public class MediaQualityService extends SystemService { // TODO: Add additional APIs. b/373951081 private final class BinderService extends IMediaQualityManager.Stub { + @Override public PictureProfile createPictureProfile(PictureProfile pp) { - // TODO: implement - return pp; + SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase(); + + ContentValues values = new ContentValues(); + values.put(PictureQuality.PARAMETER_TYPE, pp.getProfileType()); + values.put(PictureQuality.PARAMETER_NAME, pp.getName()); + values.put(PictureQuality.PARAMETER_PACKAGE, pp.getPackageName()); + values.put(PictureQuality.PARAMETER_INPUT_ID, pp.getInputId()); + values.put(mMediaQualityDbHelper.SETTINGS, bundleToJson(pp.getParameters())); + + // id is auto-generated by SQLite upon successful insertion of row + long id = db.insert(mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME, null, values); + return new PictureProfile.Builder(pp).setProfileId(Long.toString(id)).build(); } + @Override public void updatePictureProfile(String id, PictureProfile pp) { // TODO: implement @@ -66,21 +93,159 @@ public class MediaQualityService extends SystemService { public void removePictureProfile(String id) { // TODO: implement } + @Override public PictureProfile getPictureProfile(int type, String name) { - return null; + SQLiteDatabase db = mMediaQualityDbHelper.getReadableDatabase(); + + String selection = PictureQuality.PARAMETER_TYPE + " = ? AND " + + PictureQuality.PARAMETER_NAME + " = ?"; + String[] selectionArguments = {Integer.toString(type), name}; + + try ( + Cursor cursor = db.query( + mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME, + getAllPictureProfileColumns(), + selection, + selectionArguments, + /*groupBy=*/ null, + /*having=*/ null, + /*orderBy=*/ null) + ) { + int count = cursor.getCount(); + if (count == 0) { + return null; + } + if (count > 1) { + Log.wtf(TAG, String.format(Locale.US, "%d entries found for type=%d and name=%s" + + " in %s. Should only ever be 0 or 1.", count, type, name, + mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME)); + return null; + } + cursor.moveToFirst(); + return getPictureProfileFromCursor(cursor); + } + } + + private String bundleToJson(Bundle bundle) { + JSONObject jsonObject = new JSONObject(); + if (bundle == null) { + return jsonObject.toString(); + } + for (String key : bundle.keySet()) { + try { + jsonObject.put(key, bundle.getString(key)); + } catch (JSONException e) { + Log.e(TAG, "Unable to serialize ", e); + } + } + return jsonObject.toString(); } + + private Bundle jsonToBundle(String jsonString) { + JSONObject jsonObject = null; + Bundle bundle = new Bundle(); + + try { + jsonObject = new JSONObject(jsonString); + + Iterator<String> keys = jsonObject.keys(); + while (keys.hasNext()) { + String key = keys.next(); + Object value = jsonObject.get(key); + + if (value instanceof String) { + bundle.putString(key, (String) value); + } else if (value instanceof Integer) { + bundle.putInt(key, (Integer) value); + } else if (value instanceof Boolean) { + bundle.putBoolean(key, (Boolean) value); + } else if (value instanceof Double) { + bundle.putDouble(key, (Double) value); + } else if (value instanceof Long) { + bundle.putLong(key, (Long) value); + } + } + } catch (JSONException e) { + throw new RuntimeException(e); + } + + return bundle; + } + + private String[] getAllPictureProfileColumns() { + return new String[]{ + PictureQuality.PARAMETER_ID, + PictureQuality.PARAMETER_TYPE, + PictureQuality.PARAMETER_NAME, + PictureQuality.PARAMETER_INPUT_ID, + PictureQuality.PARAMETER_PACKAGE, + mMediaQualityDbHelper.SETTINGS + }; + } + + private PictureProfile getPictureProfileFromCursor(Cursor cursor) { + String returnId = cursor.getString( + cursor.getColumnIndexOrThrow(PictureQuality.PARAMETER_ID)); + int type = cursor.getInt( + cursor.getColumnIndexOrThrow(PictureQuality.PARAMETER_TYPE)); + String name = cursor.getString( + cursor.getColumnIndexOrThrow(PictureQuality.PARAMETER_NAME)); + String inputId = cursor.getString( + cursor.getColumnIndexOrThrow(PictureQuality.PARAMETER_INPUT_ID)); + String packageName = cursor.getString( + cursor.getColumnIndexOrThrow(PictureQuality.PARAMETER_PACKAGE)); + String settings = cursor.getString( + cursor.getColumnIndexOrThrow(mMediaQualityDbHelper.SETTINGS)); + return new PictureProfile(returnId, type, name, inputId, + packageName, jsonToBundle(settings)); + } + @Override public List<PictureProfile> getPictureProfilesByPackage(String packageName) { - return new ArrayList<>(); + String selection = PictureQuality.PARAMETER_PACKAGE + " = ?"; + String[] selectionArguments = {packageName}; + return getPictureProfilesBasedOnConditions(getAllPictureProfileColumns(), selection, + selectionArguments); } + @Override public List<PictureProfile> getAvailablePictureProfiles() { return new ArrayList<>(); } + @Override public List<String> getPictureProfilePackageNames() { - return new ArrayList<>(); + String [] column = {PictureQuality.PARAMETER_NAME}; + List<PictureProfile> pictureProfiles = getPictureProfilesBasedOnConditions(column, + null, null); + List<String> packageNames = new ArrayList<>(); + for (PictureProfile pictureProfile: pictureProfiles) { + packageNames.add(pictureProfile.getName()); + } + return packageNames; + } + + private List<PictureProfile> getPictureProfilesBasedOnConditions(String[] columns, + String selection, String[] selectionArguments) { + SQLiteDatabase db = mMediaQualityDbHelper.getReadableDatabase(); + + try ( + Cursor cursor = db.query( + mMediaQualityDbHelper.PICTURE_QUALITY_TABLE_NAME, + columns, + selection, + selectionArguments, + /*groupBy=*/ null, + /*having=*/ null, + /*orderBy=*/ null) + ) { + List<PictureProfile> pictureProfiles = new ArrayList<>(); + while (cursor.moveToNext()) { + pictureProfiles.add(getPictureProfileFromCursor(cursor)); + } + return pictureProfiles; + } } @Override diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java index 5914dbe44b0b..3a77d2bb67a9 100644 --- a/services/core/java/com/android/server/notification/GroupHelper.java +++ b/services/core/java/com/android/server/notification/GroupHelper.java @@ -92,10 +92,16 @@ public class GroupHelper { static final int REGROUP_REASON_CHANNEL_UPDATE = 0; // Regrouping needed because of notification bundling static final int REGROUP_REASON_BUNDLE = 1; + // Regrouping needed because of notification unbundling + static final int REGROUP_REASON_UNBUNDLE = 2; + // Regrouping needed because of notification unbundling + the original group summary exists + static final int REGROUP_REASON_UNBUNDLE_ORIGINAL_GROUP = 3; @IntDef(prefix = { "REGROUP_REASON_" }, value = { REGROUP_REASON_CHANNEL_UPDATE, REGROUP_REASON_BUNDLE, + REGROUP_REASON_UNBUNDLE, + REGROUP_REASON_UNBUNDLE_ORIGINAL_GROUP, }) @Retention(RetentionPolicy.SOURCE) @interface RegroupingReason {} @@ -103,7 +109,6 @@ public class GroupHelper { private final Callback mCallback; private final int mAutoGroupAtCount; private final int mAutogroupSparseGroupsAtCount; - private final int mAutoGroupRegroupingAtCount; private final Context mContext; private final PackageManager mPackageManager; private boolean mIsTestHarnessExempted; @@ -190,11 +195,6 @@ public class GroupHelper { mContext = context; mPackageManager = packageManager; mAutogroupSparseGroupsAtCount = autoGroupSparseGroupsAtCount; - if (notificationRegroupOnClassification()) { - mAutoGroupRegroupingAtCount = 1; - } else { - mAutoGroupRegroupingAtCount = mAutoGroupAtCount; - } NOTIFICATION_SHADE_SECTIONS = getNotificationShadeSections(); } @@ -797,7 +797,8 @@ public class GroupHelper { Slog.v(TAG, "isGroupChildInDifferentBundleThanSummary: " + record); } moveNotificationsToNewSection(record.getUserId(), pkgName, - List.of(new NotificationMoveOp(record, null, fullAggregateGroupKey))); + List.of(new NotificationMoveOp(record, null, fullAggregateGroupKey)), + REGROUP_REASON_BUNDLE); return; } } @@ -945,6 +946,27 @@ public class GroupHelper { } } + /** + * Called when a notification that was classified (bundled) is restored to its original channel. + * The notification will be restored to its original group, if any/if summary still exists. + * Otherwise it will be moved to the appropriate section as an ungrouped notification. + * + * @param record the notification which had its channel updated + * @param originalSummaryExists the original group summary exists + */ + @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING) + public void onNotificationUnbundled(final NotificationRecord record, + final boolean originalSummaryExists) { + synchronized (mAggregatedNotifications) { + ArrayMap<String, NotificationRecord> notificationsToCheck = new ArrayMap<>(); + notificationsToCheck.put(record.getKey(), record); + regroupNotifications(record.getUserId(), record.getSbn().getPackageName(), + notificationsToCheck, + originalSummaryExists ? REGROUP_REASON_UNBUNDLE_ORIGINAL_GROUP + : REGROUP_REASON_UNBUNDLE); + } + } + @GuardedBy("mAggregatedNotifications") private void regroupNotifications(int userId, String pkgName, ArrayMap<String, NotificationRecord> notificationsToCheck, @@ -973,7 +995,7 @@ public class GroupHelper { // Batch move to new section if (!notificationsToMove.isEmpty()) { - moveNotificationsToNewSection(userId, pkgName, notificationsToMove); + moveNotificationsToNewSection(userId, pkgName, notificationsToMove, regroupingReason); } } @@ -1093,7 +1115,7 @@ public class GroupHelper { @GuardedBy("mAggregatedNotifications") private void moveNotificationsToNewSection(final int userId, final String pkgName, - final List<NotificationMoveOp> notificationsToMove) { + final List<NotificationMoveOp> notificationsToMove, int regroupingReason) { record GroupUpdateOp(FullyQualifiedGroupKey groupKey, NotificationRecord record, boolean hasSummary) { } // Bundled operations to apply to groups affected by the channel update @@ -1111,7 +1133,8 @@ public class GroupHelper { if (DEBUG) { Log.i(TAG, "moveNotificationToNewSection: " + record + " " + newFullAggregateGroupKey - + " from: " + oldFullAggregateGroupKey); + + " from: " + oldFullAggregateGroupKey + " regroupingReason: " + + regroupingReason); } // Update/remove aggregate summary for old group @@ -1140,28 +1163,35 @@ public class GroupHelper { // Add moved notifications to the ungrouped list for new group and do grouping // after all notifications have been handled if (newFullAggregateGroupKey != null) { - final ArrayMap<String, NotificationAttributes> newAggregatedNotificationsAttrs = + if (notificationRegroupOnClassification() + && regroupingReason == REGROUP_REASON_UNBUNDLE_ORIGINAL_GROUP) { + // Just reset override group key, original summary exists + // => will be grouped back to its original group + record.setOverrideGroupKey(null); + } else { + final ArrayMap<String, NotificationAttributes> newAggregatedNotificationsAttrs = mAggregatedNotifications.getOrDefault(newFullAggregateGroupKey, new ArrayMap<>()); - boolean hasSummary = !newAggregatedNotificationsAttrs.isEmpty(); - ArrayMap<String, NotificationAttributes> ungrouped = + boolean hasSummary = !newAggregatedNotificationsAttrs.isEmpty(); + ArrayMap<String, NotificationAttributes> ungrouped = mUngroupedAbuseNotifications.getOrDefault(newFullAggregateGroupKey, new ArrayMap<>()); - ungrouped.put(record.getKey(), new NotificationAttributes( + ungrouped.put(record.getKey(), new NotificationAttributes( record.getFlags(), record.getNotification().getSmallIcon(), record.getNotification().color, record.getNotification().visibility, record.getNotification().getGroupAlertBehavior(), record.getChannel().getId())); - mUngroupedAbuseNotifications.put(newFullAggregateGroupKey, ungrouped); + mUngroupedAbuseNotifications.put(newFullAggregateGroupKey, ungrouped); - record.setOverrideGroupKey(null); + record.setOverrideGroupKey(null); - // Only add once, for triggering notification - if (!groupsToUpdate.containsKey(newFullAggregateGroupKey)) { - groupsToUpdate.put(newFullAggregateGroupKey, - new GroupUpdateOp(newFullAggregateGroupKey, record, hasSummary)); + // Only add once, for triggering notification + if (!groupsToUpdate.containsKey(newFullAggregateGroupKey)) { + groupsToUpdate.put(newFullAggregateGroupKey, + new GroupUpdateOp(newFullAggregateGroupKey, record, hasSummary)); + } } } } @@ -1176,7 +1206,7 @@ public class GroupHelper { NotificationRecord triggeringNotification = groupsToUpdate.get(groupKey).record; boolean hasSummary = groupsToUpdate.get(groupKey).hasSummary; //Group needs to be created/updated - if (ungrouped.size() >= mAutoGroupRegroupingAtCount + if (ungrouped.size() >= mAutoGroupAtCount || (hasSummary && !aggregatedNotificationsAttrs.isEmpty())) { NotificationSectioner sectioner = getSection(triggeringNotification); if (sectioner == null) { diff --git a/services/core/java/com/android/server/notification/NotificationManagerInternal.java b/services/core/java/com/android/server/notification/NotificationManagerInternal.java index d5d4070ee4c3..52ddb800fa40 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerInternal.java +++ b/services/core/java/com/android/server/notification/NotificationManagerInternal.java @@ -22,8 +22,11 @@ import android.app.NotificationChannelGroup; import android.app.backup.BackupRestoreEventLogger; import android.service.notification.DeviceEffectsApplier; +import com.android.internal.annotations.Keep; + import java.util.Set; +@Keep public interface NotificationManagerInternal { NotificationChannel getNotificationChannel(String pkg, int uid, String channelId); NotificationChannelGroup getNotificationChannelGroup(String pkg, int uid, String channelId); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 4d0c7ec64317..5182dfe60fcc 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -211,6 +211,7 @@ import android.app.RemoteServiceException.BadForegroundServiceNotificationExcept import android.app.RemoteServiceException.BadUserInitiatedJobNotificationException; import android.app.StatsManager; import android.app.UriGrantsManager; +import android.app.ZenBypassingApp; import android.app.admin.DevicePolicyManagerInternal; import android.app.backup.BackupManager; import android.app.backup.BackupRestoreEventLogger; @@ -238,7 +239,6 @@ import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.LauncherApps; import android.content.pm.ModuleInfo; -import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManagerInternal; @@ -3089,7 +3089,7 @@ public class NotificationManagerService extends SystemService { migrateDefaultNAS(); maybeShowInitialReviewPermissionsNotification(); - if (android.app.Flags.modesApi()) { + if (android.app.Flags.modesApi() && !mZenModeHelper.hasDeviceEffectsApplier()) { // Cannot be done earlier, as some services aren't ready until this point. mZenModeHelper.setDeviceEffectsApplier( new DefaultDeviceEffectsApplier(getContext())); @@ -4043,7 +4043,7 @@ public class NotificationManagerService extends SystemService { "canNotifyAsPackage for uid " + uid); } - return areNotificationsEnabledForPackageInt(pkg, uid); + return areNotificationsEnabledForPackageInt(uid); } /** @@ -4864,30 +4864,20 @@ public class NotificationManagerService extends SystemService { } @Override - public List<String> getPackagesBypassingDnd(int userId, - boolean includeConversationChannels) { + public ParceledListSlice<ZenBypassingApp> getPackagesBypassingDnd(int userId) + throws RemoteException { checkCallerIsSystem(); - final ArraySet<String> packageNames = new ArraySet<>(); - - List<PackageInfo> pkgs = mPackageManagerClient.getInstalledPackagesAsUser(0, userId); - for (PackageInfo pi : pkgs) { - String pkg = pi.packageName; - // If any NotificationChannel for this package is bypassing, the - // package is considered bypassing. - for (NotificationChannel channel : getNotificationChannelsBypassingDnd(pkg, - pi.applicationInfo.uid).getList()) { - // Skips non-demoted conversation channels. - if (!includeConversationChannels - && !TextUtils.isEmpty(channel.getConversationId()) - && !channel.isDemoted()) { - continue; - } - packageNames.add(pkg); + UserHandle user = UserHandle.of(userId); + ArrayList<ZenBypassingApp> bypassing = + mPreferencesHelper.getPackagesBypassingDnd(userId); + for (int i = bypassing.size() - 1; i >= 0; i--) { + String pkg = bypassing.get(i).getPkg(); + if (!areNotificationsEnabledForPackage(pkg, getUidForPackageAndUser(pkg, user))) { + bypassing.remove(i); } } - - return new ArrayList<String>(packageNames); + return new ParceledListSlice<>(bypassing); } @Override @@ -7190,13 +7180,16 @@ public class NotificationManagerService extends SystemService { Slog.i(TAG, "Removing app summary (all children bundled): " + groupSummary); } - canceledSummary = groupSummary; - mSummaryByGroupKey.remove(oldGroupKey); - cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), + if (convertSummaryToNotificationLocked(groupSummary.getKey())) { + groupSummary.isCanceled = true; + canceledSummary = groupSummary; + mSummaryByGroupKey.remove(oldGroupKey); + cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), groupSummary.getSbn().getPackageName(), groupSummary.getSbn().getTag(), groupSummary.getSbn().getId(), 0, 0, false, groupSummary.getUserId(), NotificationListenerService.REASON_GROUP_OPTIMIZATION, null); + } } } } @@ -7763,7 +7756,7 @@ public class NotificationManagerService extends SystemService { @Override public boolean areNotificationsEnabledForPackage(String pkg, int uid) { - return areNotificationsEnabledForPackageInt(pkg, uid); + return areNotificationsEnabledForPackageInt(uid); } @Override @@ -8742,7 +8735,7 @@ public class NotificationManagerService extends SystemService { } // blocked apps - boolean isBlocked = !areNotificationsEnabledForPackageInt(pkg, uid); + boolean isBlocked = !areNotificationsEnabledForPackageInt(uid); synchronized (mNotificationLock) { isBlocked |= isRecordBlockedLocked(r); } @@ -8792,7 +8785,7 @@ public class NotificationManagerService extends SystemService { } } - private boolean areNotificationsEnabledForPackageInt(String pkg, int uid) { + private boolean areNotificationsEnabledForPackageInt(int uid) { return mPermissionHelper.hasPermission(uid); } @@ -9328,7 +9321,7 @@ public class NotificationManagerService extends SystemService { * notifying all listeners to a background thread; false otherwise. */ private boolean postNotification() { - boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid); + boolean appBanned = !areNotificationsEnabledForPackageInt(uid); boolean isCallNotification = isCallNotification(pkg, uid); boolean posted = false; synchronized (NotificationManagerService.this.mNotificationLock) { @@ -11947,16 +11940,19 @@ public class NotificationManagerService extends SystemService { TrimCache trimCache = new TrimCache(sbn); final INotificationListener assistant = (INotificationListener) info.service; final StatusBarNotification sbnToPost = trimCache.ForListener(info); - final StatusBarNotificationHolder sbnHolder = - new StatusBarNotificationHolder(sbnToPost); + final NotificationRankingUpdate update = makeRankingUpdateLocked(info); + try { - if (debug) { - Slog.v(TAG, - "calling onNotificationEnqueuedWithChannel " + sbnHolder); + if (android.app.Flags.noSbnholder()) { + assistant.onNotificationEnqueuedWithChannelFull(sbnToPost, + r.getChannel(), update); + } else { + final StatusBarNotificationHolder sbnHolder = + new StatusBarNotificationHolder(sbnToPost); + + assistant.onNotificationEnqueuedWithChannel(sbnHolder, r.getChannel(), + update); } - final NotificationRankingUpdate update = makeRankingUpdateLocked(info); - assistant.onNotificationEnqueuedWithChannel(sbnHolder, r.getChannel(), - update); } catch (RemoteException ex) { Slog.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex); } @@ -11976,7 +11972,7 @@ public class NotificationManagerService extends SystemService { r.getSbn(), r.getNotificationType(), true /* sameUserOnly */, - (assistant, sbnHolder) -> { + (assistant, unused) -> { try { assistant.onNotificationVisibilityChanged(key, isVisible); } catch (RemoteException ex) { @@ -11996,7 +11992,7 @@ public class NotificationManagerService extends SystemService { sbn, notificationType, true /* sameUserOnly */, - (assistant, sbnHolder) -> { + (assistant, unused) -> { try { assistant.onNotificationExpansionChanged(key, isUserAction, isExpanded); } catch (RemoteException ex) { @@ -12013,7 +12009,7 @@ public class NotificationManagerService extends SystemService { r.getSbn(), r.getNotificationType(), true /* sameUserOnly */, - (assistant, sbnHolder) -> { + (assistant, unused) -> { try { assistant.onNotificationDirectReply(key); } catch (RemoteException ex) { @@ -12031,7 +12027,7 @@ public class NotificationManagerService extends SystemService { sbn, notificationType, true /* sameUserOnly */, - (assistant, sbnHolder) -> { + (assistant, unused) -> { try { assistant.onSuggestedReplySent( key, @@ -12054,7 +12050,7 @@ public class NotificationManagerService extends SystemService { r.getSbn(), r.getNotificationType(), true /* sameUserOnly */, - (assistant, sbnHolder) -> { + (assistant, unused) -> { try { assistant.onActionClicked( key, @@ -12079,10 +12075,17 @@ public class NotificationManagerService extends SystemService { r.getSbn(), r.getNotificationType(), true /* sameUserOnly */, - (assistant, sbnHolder) -> { + (assistant, sbnToPost) -> { try { - assistant.onNotificationSnoozedUntilContext( - sbnHolder, snoozeCriterionId); + if (android.app.Flags.noSbnholder()) { + assistant.onNotificationSnoozedUntilContextFull( + sbnToPost, snoozeCriterionId); + } else { + final StatusBarNotificationHolder sbnHolder = + new StatusBarNotificationHolder(sbnToPost); + assistant.onNotificationSnoozedUntilContext( + sbnHolder, snoozeCriterionId); + } } catch (RemoteException ex) { Slog.e(TAG, "unable to notify assistant (snoozed): " + assistant, ex); } @@ -12096,7 +12099,7 @@ public class NotificationManagerService extends SystemService { r.getSbn(), r.getNotificationType(), true /* sameUserOnly */, - (assistant, sbnHolder) -> { + (assistant, unused) -> { try { assistant.onNotificationClicked(key); } catch (RemoteException ex) { @@ -12139,7 +12142,7 @@ public class NotificationManagerService extends SystemService { final StatusBarNotification sbn, int notificationType, boolean sameUserOnly, - BiConsumer<INotificationListener, StatusBarNotificationHolder> callback) { + BiConsumer<INotificationListener, StatusBarNotification> callback) { TrimCache trimCache = new TrimCache(sbn); // There should be only one, but it's a list, so while we enforce // singularity elsewhere, we keep it general here, to avoid surprises. @@ -12161,9 +12164,7 @@ public class NotificationManagerService extends SystemService { } final INotificationListener assistant = (INotificationListener) info.service; final StatusBarNotification sbnToPost = trimCache.ForListener(info); - final StatusBarNotificationHolder sbnHolder = - new StatusBarNotificationHolder(sbnToPost); - mHandler.post(() -> callback.accept(assistant, sbnHolder)); + mHandler.post(() -> callback.accept(assistant, sbnToPost)); } } @@ -13409,9 +13410,13 @@ public class NotificationManagerService extends SystemService { private void notifyPosted(final ManagedServiceInfo info, final StatusBarNotification sbn, NotificationRankingUpdate rankingUpdate) { final INotificationListener listener = (INotificationListener) info.service; - StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn); try { - listener.onNotificationPosted(sbnHolder, rankingUpdate); + if (android.app.Flags.noSbnholder()) { + listener.onNotificationPostedFull(sbn, rankingUpdate); + } else { + StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn); + listener.onNotificationPosted(sbnHolder, rankingUpdate); + } } catch (DeadObjectException ex) { Slog.wtf(TAG, "unable to notify listener (posted): " + info, ex); } catch (RemoteException ex) { @@ -13422,7 +13427,6 @@ public class NotificationManagerService extends SystemService { private void notifyRemoved(ManagedServiceInfo info, StatusBarNotification sbn, NotificationRankingUpdate rankingUpdate, NotificationStats stats, int reason) { final INotificationListener listener = (INotificationListener) info.service; - StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn); try { if (!CompatChanges.isChangeEnabled(NOTIFICATION_CANCELLATION_REASONS, info.uid) && (reason == REASON_CHANNEL_REMOVED || reason == REASON_CLEAR_DATA)) { @@ -13434,7 +13438,12 @@ public class NotificationManagerService extends SystemService { && reason == REASON_ASSISTANT_CANCEL) { reason = REASON_LISTENER_CANCEL; } - listener.onNotificationRemoved(sbnHolder, rankingUpdate, stats, reason); + if (android.app.Flags.noSbnholder()) { + listener.onNotificationRemovedFull(sbn, rankingUpdate, stats, reason); + } else { + StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn); + listener.onNotificationRemoved(sbnHolder, rankingUpdate, stats, reason); + } } catch (DeadObjectException ex) { Slog.wtf(TAG, "unable to notify listener (removed): " + info, ex); } catch (RemoteException ex) { diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index 9f0b4b0b6299..e6f784c71ef3 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -57,6 +57,7 @@ import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.app.NotificationManager; +import android.app.ZenBypassingApp; import android.content.AttributionSource; import android.content.Context; import android.content.pm.ApplicationInfo; @@ -1950,6 +1951,35 @@ public class PreferencesHelper implements RankingConfig { } /** + * Gets all apps that can bypass DND, and a boolean indicating whether all (true) or some + * (false) of its notification channels can currently bypass. + */ + public @NonNull ArrayList<ZenBypassingApp> getPackagesBypassingDnd(@UserIdInt int userId) { + ArrayList<ZenBypassingApp> bypassing = new ArrayList<>(); + synchronized (mLock) { + for (PackagePreferences p : mPackagePreferences.values()) { + if (p.userId != userId) { + continue; + } + int totalChannelCount = p.channels.size(); + int bypassingCount = 0; + if (totalChannelCount == 0) { + continue; + } + for (NotificationChannel channel : p.channels.values()) { + if (channelIsLiveLocked(p, channel) && channel.canBypassDnd()) { + bypassingCount++; + } + } + if (bypassingCount > 0) { + bypassing.add(new ZenBypassingApp(p.pkg, totalChannelCount == bypassingCount)); + } + } + } + return bypassing; + } + + /** * True for pre-O apps that only have the default channel, or pre O apps that have no * channels yet. This method will create the default channel for pre-O apps that don't have it. * Should never be true for O+ targeting apps, but that's enforced on boot/when an app diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index cfeacdf2bb0d..ca4f83fd46f6 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -24,6 +24,8 @@ import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_ENABLED; import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_REMOVED; import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_UNKNOWN; import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY; +import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_CONFIG; +import static android.app.backup.NotificationLoggingConstants.ERROR_XML_PARSING; import static android.service.notification.Condition.SOURCE_UNKNOWN; import static android.service.notification.Condition.SOURCE_USER_ACTION; import static android.service.notification.Condition.STATE_FALSE; @@ -44,8 +46,6 @@ import static android.service.notification.ZenModeConfig.isImplicitRuleId; import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE; import static com.android.internal.util.Preconditions.checkArgument; -import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_CONFIG; -import static android.app.backup.NotificationLoggingConstants.ERROR_XML_PARSING; import static java.util.Objects.requireNonNull; @@ -303,6 +303,15 @@ public class ZenModeHelper { } /** + * @return whether a {@link DeviceEffectsApplier} has already been set or not + */ + boolean hasDeviceEffectsApplier() { + synchronized (mConfigLock) { + return mDeviceEffectsApplier != null; + } + } + + /** * Set the {@link DeviceEffectsApplier} used to apply the consolidated effects. * * <p>Previously calculated effects (as loaded from the user's {@link ZenModeConfig}) will be diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java index 76ea0b963036..4690e020b12a 100644 --- a/services/core/java/com/android/server/pm/PackageArchiver.java +++ b/services/core/java/com/android/server/pm/PackageArchiver.java @@ -880,7 +880,8 @@ public class PackageArchiver { PackageInstaller.STATUS_PENDING_USER_ACTION); broadcastIntent.putExtra(Intent.EXTRA_INTENT, dialogIntent); broadcastIntent.putExtra(Intent.EXTRA_USER, user); - sendIntent(statusReceiver, packageName, /* message= */ "", broadcastIntent); + mPm.mHandler.post( + () -> sendIntent(statusReceiver, packageName, /* message= */ "", broadcastIntent)); } private void verifyUninstallPermissions() { diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 5518bfae8277..1052c94d7799 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -1022,7 +1022,7 @@ public class ShortcutService extends IShortcutService.Stub { // Close. file.finishWrite(outs); } catch (IOException e) { - Slog.e(TAG, "Failed to write to file " + file.getBaseFile(), e); + Slog.w(TAG, "Failed to write to file " + file.getBaseFile(), e); file.failWrite(outs); } } @@ -1055,7 +1055,7 @@ public class ShortcutService extends IShortcutService.Stub { final String tag = parser.getName(); if (depth == 1) { if (!TAG_ROOT.equals(tag)) { - Slog.e(TAG, "Invalid root tag: " + tag); + Slog.v(TAG, "Invalid root tag: " + tag); return; } continue; @@ -1066,7 +1066,7 @@ public class ShortcutService extends IShortcutService.Stub { mRawLastResetTime.set(parseLongAttribute(parser, ATTR_VALUE)); break; default: - Slog.e(TAG, "Invalid tag: " + tag); + Slog.v(TAG, "Invalid tag: " + tag); break; } } @@ -1113,7 +1113,7 @@ public class ShortcutService extends IShortcutService.Stub { // Remove all dangling bitmap files. cleanupDanglingBitmapDirectoriesLocked(userId); } catch (XmlPullParserException | IOException e) { - Slog.e(TAG, "Failed to write to file " + file, e); + Slog.w(TAG, "Failed to write to file " + file, e); file.failWrite(os); } } diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 06e29c2c1408..b2b8aaf7dd2a 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -4984,7 +4984,10 @@ public class UserManagerService extends IUserManager.Stub { res.getValue(com.android.internal.R.string.owner_name, mOwnerNameTypedValue, true); final CharSequence ownerName = mOwnerNameTypedValue.coerceToString(); mOwnerName.set(ownerName != null ? ownerName.toString() : null); + // Invalidate when owners name changes due to config change. + UserManager.invalidateCacheOnUserDataChanged(); } + } private void scheduleWriteUserList() { @@ -4997,6 +5000,8 @@ public class UserManagerService extends IUserManager.Stub { Message msg = mHandler.obtainMessage(WRITE_USER_LIST_MSG); mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY); } + // Invalidate cache when {@link UserData} changed, but write was scheduled for later. + UserManager.invalidateCacheOnUserDataChanged(); } private void scheduleWriteUser(@UserIdInt int userId) { @@ -5009,6 +5014,8 @@ public class UserManagerService extends IUserManager.Stub { Message msg = mHandler.obtainMessage(WRITE_USER_MSG, userId); mHandler.sendMessageDelayed(msg, WRITE_USER_DELAY); } + // Invalidate cache when {@link Data} changed, but write was scheduled for later. + UserManager.invalidateCacheOnUserDataChanged(); } private ResilientAtomicFile getUserFile(int userId) { @@ -5032,6 +5039,9 @@ public class UserManagerService extends IUserManager.Stub { if (DBG) { debug("writeUserLP " + userData); } + // invalidate caches related to any {@link UserData} change. + UserManager.invalidateCacheOnUserDataChanged(); + try (ResilientAtomicFile userFile = getUserFile(userData.info.id)) { FileOutputStream fos = null; try { @@ -5196,6 +5206,8 @@ public class UserManagerService extends IUserManager.Stub { if (DBG) { debug("writeUserList"); } + // invalidate caches related to any {@link UserData} change. + UserManager.invalidateCacheOnUserDataChanged(); try (ResilientAtomicFile file = getUserListFile()) { FileOutputStream fos = null; @@ -7958,7 +7970,7 @@ public class UserManagerService extends IUserManager.Stub { Settings.Secure.getIntForUser(mContext.getContentResolver(), HIDE_PRIVATESPACE_ENTRY_POINT, parentId) == 1); } catch (Settings.SettingNotFoundException e) { - throw new RuntimeException(e); + config.putBoolean(PRIVATE_SPACE_ENTRYPOINT_HIDDEN, false); } } return new LauncherUserInfo.Builder(userDetails.getName(), diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java index 7469c9293e22..09feb18d07bf 100644 --- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java @@ -36,6 +36,7 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.PermissionInfo; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; +import android.health.connect.HealthPermissions; import android.media.RingtoneManager; import android.media.midi.MidiManager; import android.net.Uri; @@ -48,6 +49,7 @@ import android.os.Process; import android.os.UserHandle; import android.os.storage.StorageManager; import android.permission.PermissionManager; +import android.permission.flags.Flags; import android.print.PrintManager; import android.provider.CalendarContract; import android.provider.ContactsContract; @@ -214,8 +216,13 @@ final class DefaultPermissionGrantPolicy { private static final Set<String> SENSORS_PERMISSIONS = new ArraySet<>(); static { - SENSORS_PERMISSIONS.add(Manifest.permission.BODY_SENSORS); - SENSORS_PERMISSIONS.add(Manifest.permission.BODY_SENSORS_BACKGROUND); + if (Flags.replaceBodySensorPermissionEnabled()) { + SENSORS_PERMISSIONS.add(HealthPermissions.READ_HEART_RATE); + SENSORS_PERMISSIONS.add(HealthPermissions.READ_HEALTH_DATA_IN_BACKGROUND); + } else { + SENSORS_PERMISSIONS.add(Manifest.permission.BODY_SENSORS); + SENSORS_PERMISSIONS.add(Manifest.permission.BODY_SENSORS_BACKGROUND); + } } private static final Set<String> STORAGE_PERMISSIONS = new ArraySet<>(); diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java index 2c0ce252df18..17459df2bc1a 100644 --- a/services/core/java/com/android/server/power/hint/HintManagerService.java +++ b/services/core/java/com/android/server/power/hint/HintManagerService.java @@ -33,11 +33,15 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.hardware.power.ChannelConfig; +import android.hardware.power.CpuHeadroomParams; +import android.hardware.power.GpuHeadroomParams; import android.hardware.power.IPower; import android.hardware.power.SessionConfig; import android.hardware.power.SessionTag; import android.hardware.power.WorkDuration; import android.os.Binder; +import android.os.CpuHeadroomParamsInternal; +import android.os.GpuHeadroomParamsInternal; import android.os.Handler; import android.os.IBinder; import android.os.IHintManager; @@ -90,6 +94,10 @@ public final class HintManagerService extends SystemService { private static final int EVENT_CLEAN_UP_UID = 3; @VisibleForTesting static final int CLEAN_UP_UID_DELAY_MILLIS = 1000; + private static final int DEFAULT_GPU_HEADROOM_INTERVAL_MILLIS = 1000; + private static final int DEFAULT_CPU_HEADROOM_INTERVAL_MILLIS = 1000; + private static final int HEADROOM_INTERVAL_UNSUPPORTED = -1; + @VisibleForTesting static final int DEFAULT_HEADROOM_PID = -1; @VisibleForTesting final long mHintSessionPreferredRate; @@ -160,10 +168,76 @@ public final class HintManagerService extends SystemService { private static final String PROPERTY_SF_ENABLE_CPU_HINT = "debug.sf.enable_adpf_cpu_hint"; private static final String PROPERTY_HWUI_ENABLE_HINT_MANAGER = "debug.hwui.use_hint_manager"; + private static final String PROPERTY_USE_HAL_HEADROOMS = "persist.hms.use_hal_headrooms"; private Boolean mFMQUsesIntegratedEventFlag = false; - @VisibleForTesting final IHintManager.Stub mService = new BinderService(); + private final Object mCpuHeadroomLock = new Object(); + + private static class CpuHeadroomCacheItem { + long mExpiredTimeMillis; + CpuHeadroomParamsInternal mParams; + float[] mHeadroom; + long mPid; + + CpuHeadroomCacheItem(long expiredTimeMillis, CpuHeadroomParamsInternal params, + float[] headroom, long pid) { + mExpiredTimeMillis = expiredTimeMillis; + mParams = params; + mPid = pid; + mHeadroom = headroom; + } + + private boolean match(CpuHeadroomParamsInternal params, long pid) { + if (mParams == null && params == null) return true; + if (mParams != null) { + return mParams.equals(params) && pid == mPid; + } + return false; + } + + private boolean isExpired() { + return System.currentTimeMillis() > mExpiredTimeMillis; + } + } + + @GuardedBy("mCpuHeadroomLock") + private final List<CpuHeadroomCacheItem> mCpuHeadroomCache; + private final long mCpuHeadroomIntervalMillis; + + private final Object mGpuHeadroomLock = new Object(); + + private static class GpuHeadroomCacheItem { + long mExpiredTimeMillis; + GpuHeadroomParamsInternal mParams; + float mHeadroom; + + GpuHeadroomCacheItem(long expiredTimeMillis, GpuHeadroomParamsInternal params, + float headroom) { + mExpiredTimeMillis = expiredTimeMillis; + mParams = params; + mHeadroom = headroom; + } + + private boolean match(GpuHeadroomParamsInternal params) { + if (mParams == null && params == null) return true; + if (mParams != null) { + return mParams.equals(params); + } + return false; + } + + private boolean isExpired() { + return System.currentTimeMillis() > mExpiredTimeMillis; + } + } + + @GuardedBy("mGpuHeadroomLock") + private final List<GpuHeadroomCacheItem> mGpuHeadroomCache; + private final long mGpuHeadroomIntervalMillis; + + @VisibleForTesting + final IHintManager.Stub mService = new BinderService(); public HintManagerService(Context context) { this(context, new Injector()); @@ -197,13 +271,72 @@ public final class HintManagerService extends SystemService { mPowerHal = injector.createIPower(); mPowerHalVersion = 0; mUsesFmq = false; + long cpuHeadroomIntervalMillis = HEADROOM_INTERVAL_UNSUPPORTED; + long gpuHeadroomIntervalMillis = HEADROOM_INTERVAL_UNSUPPORTED; if (mPowerHal != null) { try { mPowerHalVersion = mPowerHal.getInterfaceVersion(); + if (mPowerHal.getInterfaceVersion() >= 6) { + if (SystemProperties.getBoolean(PROPERTY_USE_HAL_HEADROOMS, true)) { + cpuHeadroomIntervalMillis = checkCpuHeadroomSupport(); + gpuHeadroomIntervalMillis = checkGpuHeadroomSupport(); + } + } } catch (RemoteException e) { throw new IllegalStateException("Could not contact PowerHAL!", e); } } + mCpuHeadroomIntervalMillis = cpuHeadroomIntervalMillis; + mGpuHeadroomIntervalMillis = gpuHeadroomIntervalMillis; + if (mCpuHeadroomIntervalMillis > 0) { + mCpuHeadroomCache = new ArrayList<>(4); + } else { + mCpuHeadroomCache = null; + } + if (mGpuHeadroomIntervalMillis > 0) { + mGpuHeadroomCache = new ArrayList<>(2); + } else { + mGpuHeadroomCache = null; + } + } + + private long checkCpuHeadroomSupport() { + try { + synchronized (mCpuHeadroomLock) { + final CpuHeadroomParams defaultParams = new CpuHeadroomParams(); + defaultParams.pid = Process.myPid(); + float[] ret = mPowerHal.getCpuHeadroom(defaultParams); + if (ret != null && ret.length > 0) { + return Math.max( + DEFAULT_CPU_HEADROOM_INTERVAL_MILLIS, + mPowerHal.getCpuHeadroomMinIntervalMillis()); + } + } + + } catch (UnsupportedOperationException e) { + Slog.w(TAG, "getCpuHeadroom HAL API is not supported", e); + } catch (RemoteException e) { + Slog.e(TAG, "getCpuHeadroom HAL API fails, disabling the API", e); + } + return HEADROOM_INTERVAL_UNSUPPORTED; + } + + private long checkGpuHeadroomSupport() { + try { + synchronized (mGpuHeadroomLock) { + float ret = mPowerHal.getGpuHeadroom(new GpuHeadroomParams()); + if (!Float.isNaN(ret)) { + return Math.max( + DEFAULT_GPU_HEADROOM_INTERVAL_MILLIS, + mPowerHal.getGpuHeadroomMinIntervalMillis()); + } + } + } catch (UnsupportedOperationException e) { + Slog.w(TAG, "getGpuHeadroom HAL API is not supported", e); + } catch (RemoteException e) { + Slog.e(TAG, "getGpuHeadroom HAL API fails, disabling the API", e); + } + return HEADROOM_INTERVAL_UNSUPPORTED; } private ServiceThread createCleanUpThread() { @@ -738,7 +871,7 @@ public final class HintManagerService extends SystemService { mLinked = false; } if (mConfig != null) { - try { + try { mPowerHal.closeSessionChannel(mTgid, mUid); } catch (RemoteException e) { throw new IllegalStateException("Failed to close session channel!", e); @@ -982,13 +1115,13 @@ public final class HintManagerService extends SystemService { } // returns the first invalid tid or null if not found - private Integer checkTidValid(int uid, int tgid, int [] tids, IntArray nonIsolated) { + private Integer checkTidValid(int uid, int tgid, int[] tids, IntArray nonIsolated) { // Make sure all tids belongs to the same UID (including isolated UID), // tids can belong to different application processes. List<Integer> isolatedPids = null; for (int i = 0; i < tids.length; i++) { int tid = tids[i]; - final String[] procStatusKeys = new String[] { + final String[] procStatusKeys = new String[]{ "Uid:", "Tgid:" }; @@ -1058,7 +1191,7 @@ public final class HintManagerService extends SystemService { Slogf.w(TAG, errMsg); throw new SecurityException(errMsg); } - if (resetOnForkEnabled()){ + if (resetOnForkEnabled()) { try { for (int tid : tids) { int policy = Process.getThreadScheduler(tid); @@ -1214,6 +1347,124 @@ public final class HintManagerService extends SystemService { } @Override + public float[] getCpuHeadroom(@Nullable CpuHeadroomParamsInternal params) { + if (mCpuHeadroomIntervalMillis <= 0) { + throw new UnsupportedOperationException(); + } + CpuHeadroomParams halParams = new CpuHeadroomParams(); + halParams.pid = Binder.getCallingPid(); + if (params != null) { + halParams.calculationType = params.calculationType; + halParams.selectionType = params.selectionType; + if (params.usesDeviceHeadroom) { + halParams.pid = DEFAULT_HEADROOM_PID; + } + } + synchronized (mCpuHeadroomLock) { + while (!mCpuHeadroomCache.isEmpty()) { + if (mCpuHeadroomCache.getFirst().isExpired()) { + mCpuHeadroomCache.removeFirst(); + } else { + break; + } + } + for (int i = 0; i < mCpuHeadroomCache.size(); ++i) { + final CpuHeadroomCacheItem item = mCpuHeadroomCache.get(i); + if (item.match(params, halParams.pid)) { + item.mExpiredTimeMillis = + System.currentTimeMillis() + mCpuHeadroomIntervalMillis; + mCpuHeadroomCache.remove(i); + mCpuHeadroomCache.add(item); + return item.mHeadroom; + } + } + } + // return from HAL directly + try { + float[] headroom = mPowerHal.getCpuHeadroom(halParams); + if (headroom == null || headroom.length == 0) { + Slog.wtf(TAG, + "CPU headroom from Power HAL is invalid: " + Arrays.toString(headroom)); + return new float[]{Float.NaN}; + } + synchronized (mCpuHeadroomLock) { + mCpuHeadroomCache.add(new CpuHeadroomCacheItem( + System.currentTimeMillis() + mCpuHeadroomIntervalMillis, + params, headroom, halParams.pid + )); + } + return headroom; + + } catch (RemoteException e) { + return new float[]{Float.NaN}; + } + } + + @Override + public float getGpuHeadroom(@Nullable GpuHeadroomParamsInternal params) { + if (mGpuHeadroomIntervalMillis <= 0) { + throw new UnsupportedOperationException(); + } + GpuHeadroomParams halParams = new GpuHeadroomParams(); + if (params != null) { + halParams.calculationType = params.calculationType; + } + synchronized (mGpuHeadroomLock) { + while (!mGpuHeadroomCache.isEmpty()) { + if (mGpuHeadroomCache.getFirst().isExpired()) { + mGpuHeadroomCache.removeFirst(); + } else { + break; + } + } + for (int i = 0; i < mGpuHeadroomCache.size(); ++i) { + final GpuHeadroomCacheItem item = mGpuHeadroomCache.get(i); + if (item.match(params)) { + item.mExpiredTimeMillis = + System.currentTimeMillis() + mGpuHeadroomIntervalMillis; + mGpuHeadroomCache.remove(i); + mGpuHeadroomCache.add(item); + return item.mHeadroom; + } + } + } + // return from HAL directly + try { + float headroom = mPowerHal.getGpuHeadroom(halParams); + if (Float.isNaN(headroom)) { + Slog.wtf(TAG, + "GPU headroom from Power HAL is NaN"); + return Float.NaN; + } + synchronized (mGpuHeadroomLock) { + mGpuHeadroomCache.add(new GpuHeadroomCacheItem( + System.currentTimeMillis() + mGpuHeadroomIntervalMillis, + params, headroom + )); + } + return headroom; + } catch (RemoteException e) { + return Float.NaN; + } + } + + @Override + public long getCpuHeadroomMinIntervalMillis() throws RemoteException { + if (mCpuHeadroomIntervalMillis <= 0) { + throw new UnsupportedOperationException(); + } + return mCpuHeadroomIntervalMillis; + } + + @Override + public long getGpuHeadroomMinIntervalMillis() throws RemoteException { + if (mGpuHeadroomIntervalMillis <= 0) { + throw new UnsupportedOperationException(); + } + return mGpuHeadroomIntervalMillis; + } + + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) { return; @@ -1235,6 +1486,25 @@ public final class HintManagerService extends SystemService { } } } + pw.println("CPU Headroom Interval: " + mCpuHeadroomIntervalMillis); + pw.println("GPU Headroom Interval: " + mGpuHeadroomIntervalMillis); + try { + CpuHeadroomParamsInternal params = new CpuHeadroomParamsInternal(); + params.selectionType = CpuHeadroomParams.SelectionType.ALL; + params.usesDeviceHeadroom = true; + pw.println("CPU headroom: " + Arrays.toString(getCpuHeadroom(params))); + params = new CpuHeadroomParamsInternal(); + params.selectionType = CpuHeadroomParams.SelectionType.PER_CORE; + params.usesDeviceHeadroom = true; + pw.println("CPU headroom per core: " + Arrays.toString(getCpuHeadroom(params))); + } catch (Exception e) { + pw.println("CPU headroom: N/A"); + } + try { + pw.println("GPU headroom: " + getGpuHeadroom(null)); + } catch (Exception e) { + pw.println("GPU headroom: N/A"); + } } private void logPerformanceHintSessionAtom(int uid, long sessionId, @@ -1467,7 +1737,7 @@ public final class HintManagerService extends SystemService { Slogf.w(TAG, errMsg); throw new SecurityException(errMsg); } - if (resetOnForkEnabled()){ + if (resetOnForkEnabled()) { try { for (int tid : tids) { int policy = Process.getThreadScheduler(tid); diff --git a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java index 1260eeec098f..e780be490181 100644 --- a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java +++ b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java @@ -46,6 +46,7 @@ import com.android.server.SystemService; import com.android.server.pm.UserManagerInternal; import com.android.server.security.advancedprotection.features.AdvancedProtectionHook; import com.android.server.security.advancedprotection.features.AdvancedProtectionProvider; +import com.android.server.security.advancedprotection.features.DisallowInstallUnknownSourcesAdvancedProtectionHook; import java.io.FileDescriptor; import java.util.ArrayList; @@ -76,10 +77,9 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub } private void initFeatures(boolean enabled) { - // Empty until features are added. - // Examples: - // mHooks.add(new SideloadingAdvancedProtectionHook(mContext, enabled)); - // mProviders.add(new WifiAdvancedProtectionProvider()); + if (android.security.Flags.aapmFeatureDisableInstallUnknownSources()) { + mHooks.add(new DisallowInstallUnknownSourcesAdvancedProtectionHook(mContext, enabled)); + } } // Only for tests diff --git a/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java b/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java new file mode 100644 index 000000000000..21752e524619 --- /dev/null +++ b/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.security.advancedprotection.features; + +import static android.security.advancedprotection.AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY; +import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES; + +import android.annotation.NonNull; +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.os.UserManager; +import android.security.advancedprotection.AdvancedProtectionFeature; +import android.util.Slog; + +/** @hide */ +public final class DisallowInstallUnknownSourcesAdvancedProtectionHook + extends AdvancedProtectionHook { + private static final String TAG = "AdvancedProtectionDisallowInstallUnknown"; + + private final AdvancedProtectionFeature mFeature = new AdvancedProtectionFeature( + FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES); + private final DevicePolicyManager mDevicePolicyManager; + + public DisallowInstallUnknownSourcesAdvancedProtectionHook(@NonNull Context context, + boolean enabled) { + super(context, enabled); + mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class); + onAdvancedProtectionChanged(enabled); + } + + @NonNull + @Override + public AdvancedProtectionFeature getFeature() { + return mFeature; + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public void onAdvancedProtectionChanged(boolean enabled) { + if (enabled) { + Slog.d(TAG, "Setting DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY restriction"); + mDevicePolicyManager.addUserRestrictionGlobally(ADVANCED_PROTECTION_SYSTEM_ENTITY, + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY); + return; + } + Slog.d(TAG, "Clearing DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY restriction"); + mDevicePolicyManager.clearUserRestrictionGlobally(ADVANCED_PROTECTION_SYSTEM_ENTITY, + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY); + + // TODO(b/369361373): + // 1. After clearing the restriction, set AppOpsManager.OP_REQUEST_INSTALL_PACKAGES to + // disabled. + // 2. Update dialog strings. + } +} diff --git a/services/core/java/com/android/server/stats/Android.bp b/services/core/java/com/android/server/stats/Android.bp index f7955e86660a..40923b6009a5 100644 --- a/services/core/java/com/android/server/stats/Android.bp +++ b/services/core/java/com/android/server/stats/Android.bp @@ -11,3 +11,10 @@ java_aconfig_library { name: "stats_flags_lib", aconfig_declarations: "stats_flags", } + +java_aconfig_library { + name: "stats_flags_lib_host", + aconfig_declarations: "stats_flags", + host_supported: true, + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index 54e4f8e9a110..40ea9319c6be 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -61,6 +61,10 @@ import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_STATS__SOFTWARE_SHORTCUT_TYPE__UNKNOWN_TYPE; import static com.android.internal.util.FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__NOT_OPPORTUNISTIC; import static com.android.internal.util.FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__OPPORTUNISTIC; +import static com.android.internal.util.FrameworkStatsLog.PRESSURE_STALL_INFORMATION__PSI_RESOURCE__PSI_RESOURCE_CPU; +import static com.android.internal.util.FrameworkStatsLog.PRESSURE_STALL_INFORMATION__PSI_RESOURCE__PSI_RESOURCE_IO; +import static com.android.internal.util.FrameworkStatsLog.PRESSURE_STALL_INFORMATION__PSI_RESOURCE__PSI_RESOURCE_MEMORY; +import static com.android.internal.util.FrameworkStatsLog.PRESSURE_STALL_INFORMATION__PSI_RESOURCE__PSI_RESOURCE_UNKNOWN; import static com.android.internal.util.FrameworkStatsLog.TIME_ZONE_DETECTOR_STATE__DETECTION_MODE__GEO; import static com.android.internal.util.FrameworkStatsLog.TIME_ZONE_DETECTOR_STATE__DETECTION_MODE__MANUAL; import static com.android.internal.util.FrameworkStatsLog.TIME_ZONE_DETECTOR_STATE__DETECTION_MODE__TELEPHONY; @@ -68,6 +72,7 @@ import static com.android.internal.util.FrameworkStatsLog.TIME_ZONE_DETECTOR_STA import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; import static com.android.server.stats.Flags.accumulateNetworkStatsSinceBoot; import static com.android.server.stats.Flags.addMobileBytesTransferByProcStatePuller; +import static com.android.server.stats.Flags.addPressureStallInformationPuller; import static com.android.server.stats.Flags.applyNetworkStatsPollRateLimit; import static com.android.server.stats.pull.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs; import static com.android.server.stats.pull.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs; @@ -234,6 +239,8 @@ import com.android.server.stats.pull.IonMemoryUtil.IonAllocations; import com.android.server.stats.pull.netstats.NetworkStatsAccumulator; import com.android.server.stats.pull.netstats.NetworkStatsExt; import com.android.server.stats.pull.netstats.SubInfo; +import com.android.server.stats.pull.psi.PsiData; +import com.android.server.stats.pull.psi.PsiExtractor; import com.android.server.storage.DiskStatsFileLogger; import com.android.server.storage.DiskStatsLoggingService; import com.android.server.timezonedetector.MetricsTimeZoneDetectorState; @@ -459,6 +466,10 @@ public class StatsPullAtomService extends SystemService { public static final boolean ENABLE_MOBILE_DATA_STATS_AGGREGATED_PULLER = addMobileBytesTransferByProcStatePuller(); + // Whether or not to enable the new puller with pressure stall information. + public static final boolean ENABLE_PRESSURE_STALL_INFORMATION_PULLER = + addPressureStallInformationPuller(); + // Puller locks private final Object mDataBytesTransferLock = new Object(); private final Object mBluetoothBytesTransferLock = new Object(); @@ -835,6 +846,8 @@ public class StatsPullAtomService extends SystemService { return pullHdrCapabilities(atomTag, data); case FrameworkStatsLog.CACHED_APPS_HIGH_WATERMARK: return pullCachedAppsHighWatermark(atomTag, data); + case FrameworkStatsLog.PRESSURE_STALL_INFORMATION: + return pullPressureStallInformation(atomTag, data); default: throw new UnsupportedOperationException("Unknown tagId=" + atomTag); } @@ -1045,6 +1058,9 @@ public class StatsPullAtomService extends SystemService { registerPinnerServiceStats(); registerHdrCapabilitiesPuller(); registerCachedAppsHighWatermarkPuller(); + if (ENABLE_PRESSURE_STALL_INFORMATION_PULLER) { + registerPressureStallInformation(); + } } private void initMobileDataStatsPuller() { @@ -5156,6 +5172,55 @@ public class StatsPullAtomService extends SystemService { ); } + private void registerPressureStallInformation() { + int tagId = FrameworkStatsLog.PRESSURE_STALL_INFORMATION; + mStatsManager.setPullAtomCallback( + tagId, + null, + DIRECT_EXECUTOR, + mStatsCallbackImpl + ); + } + + int pullPressureStallInformation(int atomTag, List<StatsEvent> pulledData) { + PsiExtractor psiExtractor = new PsiExtractor(); + for (PsiData.ResourceType resourceType: PsiData.ResourceType.values()) { + PsiData psiData = psiExtractor.getPsiData(resourceType); + if (psiData == null) { + Slog.e( + TAG, + "Failed to pull PressureStallInformation atom for resource: " + + resourceType.toString()); + continue; + } + pulledData.add(FrameworkStatsLog.buildStatsEvent( + atomTag, + toProtoPsiResourceType(psiData.getResourceType()), + psiData.getSomeAvg10SecPercentage(), + psiData.getSomeAvg60SecPercentage(), + psiData.getSomeAvg300SecPercentage(), + psiData.getSomeTotalUsec(), + psiData.getFullAvg10SecPercentage(), + psiData.getFullAvg60SecPercentage(), + psiData.getFullAvg300SecPercentage(), + psiData.getFullTotalUsec())); + } + return StatsManager.PULL_SUCCESS; + } + + private int toProtoPsiResourceType(PsiData.ResourceType resourceType) { + if (resourceType == PsiData.ResourceType.CPU) { + return PRESSURE_STALL_INFORMATION__PSI_RESOURCE__PSI_RESOURCE_CPU; + } else if (resourceType == PsiData.ResourceType.MEMORY) { + return PRESSURE_STALL_INFORMATION__PSI_RESOURCE__PSI_RESOURCE_MEMORY; + } else if (resourceType == PsiData.ResourceType.IO) { + return PRESSURE_STALL_INFORMATION__PSI_RESOURCE__PSI_RESOURCE_IO; + } else { + return PRESSURE_STALL_INFORMATION__PSI_RESOURCE__PSI_RESOURCE_UNKNOWN; + } + } + + int pullSystemServerPinnerStats(int atomTag, List<StatsEvent> pulledData) { PinnerService pinnerService = LocalServices.getService(PinnerService.class); List<PinnedFileStats> pinnedFileStats = pinnerService.dumpDataForStatsd(); diff --git a/services/core/java/com/android/server/stats/stats_flags.aconfig b/services/core/java/com/android/server/stats/stats_flags.aconfig index 8686458ff8d4..f5f31746a09f 100644 --- a/services/core/java/com/android/server/stats/stats_flags.aconfig +++ b/services/core/java/com/android/server/stats/stats_flags.aconfig @@ -38,3 +38,11 @@ flag { bug: "352537247" is_fixed_read_only: true } + +flag { + name: "add_pressure_stall_information_puller" + namespace: "statsd" + description: "Adds PressureStallInformation atom logging" + bug: "365731097" + is_fixed_read_only: true +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java b/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java index 42203b113498..07d9ad16aca5 100644 --- a/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java +++ b/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java @@ -112,6 +112,14 @@ abstract class AbstractVibratorStep extends Step { } protected void stopVibrating() { + if (conductor.isInSession) { + if (VibrationThread.DEBUG) { + Slog.d(VibrationThread.TAG, + "Vibration in session, skipping request to turn off vibrator " + + getVibratorId()); + } + return; + } if (VibrationThread.DEBUG) { Slog.d(VibrationThread.TAG, "Turning off vibrator " + getVibratorId()); diff --git a/services/core/java/com/android/server/vibrator/DeviceAdapter.java b/services/core/java/com/android/server/vibrator/DeviceAdapter.java index 751e83c7b9a9..370f212957cb 100644 --- a/services/core/java/com/android/server/vibrator/DeviceAdapter.java +++ b/services/core/java/com/android/server/vibrator/DeviceAdapter.java @@ -55,8 +55,9 @@ final class DeviceAdapter implements CombinedVibration.VibratorAdapter { DeviceAdapter(VibrationSettings settings, SparseArray<VibratorController> vibrators) { mSegmentAdapters = Arrays.asList( - // TODO(b/167947076): add filter that removes unsupported primitives // TODO(b/167947076): add filter that replaces unsupported prebaked with fallback + // Updates primitive delays to hardware supported pauses + new PrimitiveDelayAdapter(), // Convert segments based on device capabilities new RampToStepAdapter(settings.getRampStepDuration()), new StepToRampAdapter(), @@ -71,7 +72,9 @@ final class DeviceAdapter implements CombinedVibration.VibratorAdapter { ); mSegmentsValidators = List.of( // Validate Pwle segments base on the vibrators frequency range - new PwleSegmentsValidator() + new PwleSegmentsValidator(), + // Validate primitive segments based on device support + new PrimitiveSegmentsValidator() ); mAvailableVibrators = vibrators; mAvailableVibratorIds = new int[vibrators.size()]; diff --git a/services/core/java/com/android/server/vibrator/PrimitiveDelayAdapter.java b/services/core/java/com/android/server/vibrator/PrimitiveDelayAdapter.java new file mode 100644 index 000000000000..d63fffd4fed3 --- /dev/null +++ b/services/core/java/com/android/server/vibrator/PrimitiveDelayAdapter.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.vibrator; + +import static android.os.VibrationEffect.Composition.DELAY_TYPE_PAUSE; +import static android.os.VibrationEffect.Composition.DELAY_TYPE_RELATIVE_START_OFFSET; + +import android.os.VibrationEffect.Composition.DelayType; +import android.os.VibratorInfo; +import android.os.vibrator.Flags; +import android.os.vibrator.PrimitiveSegment; +import android.os.vibrator.VibrationEffectSegment; + +import java.util.List; + +/** + * Adapter that converts between {@link DelayType} and the HAL supported pause delays. + * + * <p>Primitives that overlap due to the delays being shorter than the previous segments will be + * dropped from the effect here. Relative timings will still use the dropped primitives to preserve + * the design intention. + */ +final class PrimitiveDelayAdapter implements VibrationSegmentsAdapter { + + PrimitiveDelayAdapter() { + } + + @Override + public int adaptToVibrator(VibratorInfo info, List<VibrationEffectSegment> segments, + int repeatIndex) { + if (!Flags.primitiveCompositionAbsoluteDelay()) { + return repeatIndex; + } + int previousStartOffset = 0; + int segmentCount = segments.size(); + for (int i = 0; i < segmentCount; i++) { + VibrationEffectSegment segment = segments.get(i); + if (i == repeatIndex) { + // Crossed the repeat line, reset start offset so repeating block is independent. + previousStartOffset = 0; + } + + if (!(segment instanceof PrimitiveSegment primitive) + || (primitive.getDelayType() == DELAY_TYPE_PAUSE)) { + // Effect will play normally, keep track of its start offset. + previousStartOffset = -calculateEffectDuration(info, segment); + continue; + } + + int pause = calculatePause(primitive, previousStartOffset); + if (pause >= 0) { + segments.set(i, toPrimitiveWithPause(primitive, pause)); + // Delay will be ignored from this calculation. + previousStartOffset = -calculateEffectDuration(info, primitive); + } else { + // Primitive overlapping with previous segment, ignore it. + segments.remove(i); + if (repeatIndex > i) { + repeatIndex--; + } + segmentCount--; + i--; + + // Keep the intended start time for future calculations. Here is an example: + // 10 20 30 40 50 60 70 | Timeline (D = relative delay, E = effect duration) + // D E E E E | D=10, E=40 | offset = 0 | pause = 10 | OK + // D E E | D=10, E=20 | offset = -40 | pause = -30 | IGNORED + // D E E | D=10, E=20 | offset = -30 | pause = -20 | IGNORED + // D E E | D=10, E=20 | offset = -20 | pause = -10 | IGNORED + // D E E | D=10, E=20 | offset = -10 | pause = 0 | OK + previousStartOffset = pause; + } + } + return repeatIndex; + } + + private static int calculatePause(PrimitiveSegment primitive, int previousStartOffset) { + if (primitive.getDelayType() == DELAY_TYPE_RELATIVE_START_OFFSET) { + return previousStartOffset + primitive.getDelay(); + } + return primitive.getDelay(); + } + + private static int calculateEffectDuration(VibratorInfo info, VibrationEffectSegment segment) { + long segmentDuration = segment.getDuration(info); + if (segmentDuration < 0) { + // Duration unknown, default to zero. + return 0; + } + int effectDuration = (int) segmentDuration; + if (segment instanceof PrimitiveSegment primitive) { + // Ignore primitive delays from effect duration. + effectDuration -= primitive.getDelay(); + } + return effectDuration; + } + + private static PrimitiveSegment toPrimitiveWithPause(PrimitiveSegment primitive, int pause) { + return new PrimitiveSegment(primitive.getPrimitiveId(), primitive.getScale(), + pause, DELAY_TYPE_PAUSE); + } +} diff --git a/services/core/java/com/android/server/vibrator/PrimitiveSegmentsValidator.java b/services/core/java/com/android/server/vibrator/PrimitiveSegmentsValidator.java new file mode 100644 index 000000000000..a1567fc470b5 --- /dev/null +++ b/services/core/java/com/android/server/vibrator/PrimitiveSegmentsValidator.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.vibrator; + +import android.annotation.SuppressLint; +import android.hardware.vibrator.IVibrator; +import android.os.VibratorInfo; +import android.os.vibrator.Flags; +import android.os.vibrator.PrimitiveSegment; +import android.os.vibrator.VibrationEffectSegment; + +import java.util.List; + +/** + * Validates primitive segments to ensure they are compatible with the device's capabilities. + * + * <p>The segments will be considered invalid if the device does not have + * {@link IVibrator#CAP_COMPOSE_EFFECTS} or if one of the primitives is not supported. + */ +final class PrimitiveSegmentsValidator implements VibrationSegmentsValidator { + + @SuppressLint("WrongConstant") // using primitive id from validated segment + @Override + public boolean hasValidSegments(VibratorInfo info, List<VibrationEffectSegment> segments) { + int segmentCount = segments.size(); + for (int i = 0; i < segmentCount; i++) { + if (!(segments.get(i) instanceof PrimitiveSegment primitive)) { + continue; + } + if (Flags.primitiveCompositionAbsoluteDelay()) { + // Primitive support checks introduced by this feature + if (!info.isPrimitiveSupported(primitive.getPrimitiveId())) { + return false; + } + } else { + // Delay type support not available without this feature + if ((primitive.getDelayType() != PrimitiveSegment.DEFAULT_DELAY_TYPE)) { + return false; + } + } + } + + return true; + } +} diff --git a/services/core/java/com/android/server/vibrator/SplitPwleSegmentsAdapter.java b/services/core/java/com/android/server/vibrator/SplitPwleSegmentsAdapter.java index ad44227d935a..a8c4ac8cdeeb 100644 --- a/services/core/java/com/android/server/vibrator/SplitPwleSegmentsAdapter.java +++ b/services/core/java/com/android/server/vibrator/SplitPwleSegmentsAdapter.java @@ -44,7 +44,7 @@ final class SplitPwleSegmentsAdapter implements VibrationSegmentsAdapter { // The vibrator does not have PWLE v2 capability, so keep the segments unchanged. return repeatIndex; } - int maxPwleDuration = info.getMaxEnvelopeEffectDurationMillis(); + int maxPwleDuration = (int) info.getMaxEnvelopeEffectDurationMillis(); if (maxPwleDuration <= 0) { // No limit set to PWLE primitive duration. return repeatIndex; diff --git a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java index 6a4790daf056..1e20debe156d 100644 --- a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java +++ b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java @@ -69,6 +69,7 @@ final class VibrationStepConductor { // Used within steps. public final VibrationSettings vibrationSettings; public final VibrationThread.VibratorManagerHooks vibratorManagerHooks; + public final boolean isInSession; private final DeviceAdapter mDeviceAdapter; private final VibrationScaler mVibrationScaler; @@ -105,12 +106,13 @@ final class VibrationStepConductor { private int mRemainingStartSequentialEffectSteps; private int mSuccessfulVibratorOnSteps; - VibrationStepConductor(HalVibration vib, VibrationSettings vibrationSettings, - DeviceAdapter deviceAdapter, VibrationScaler vibrationScaler, - VibratorFrameworkStatsLogger statsLogger, + VibrationStepConductor(HalVibration vib, boolean isInSession, + VibrationSettings vibrationSettings, DeviceAdapter deviceAdapter, + VibrationScaler vibrationScaler, VibratorFrameworkStatsLogger statsLogger, CompletableFuture<Void> requestVibrationParamsFuture, VibrationThread.VibratorManagerHooks vibratorManagerHooks) { this.mVibration = vib; + this.isInSession = isInSession; this.vibrationSettings = vibrationSettings; this.mDeviceAdapter = deviceAdapter; mVibrationScaler = vibrationScaler; @@ -286,6 +288,9 @@ final class VibrationStepConductor { if (nextStep == null) { return true; // Finished } + if (isInSession) { + return true; // Don't wait to play session vibration steps + } long waitMillis = nextStep.calculateWaitTime(); if (waitMillis <= 0) { return true; // Regular step ready diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java index 476448148e28..1030df692543 100644 --- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java +++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java @@ -1114,8 +1114,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mVibrationSettings.getRequestVibrationParamsTimeoutMs()); } - return new VibrationStepConductor(vib, mVibrationSettings, mDeviceAdapter, mVibrationScaler, - mFrameworkStatsLogger, requestVibrationParamsFuture, mVibrationThreadCallbacks); + return new VibrationStepConductor(vib, /* isInSession= */ false, mVibrationSettings, + mDeviceAdapter, mVibrationScaler, mFrameworkStatsLogger, + requestVibrationParamsFuture, mVibrationThreadCallbacks); } private Status startVibrationOnInputDevicesLocked(HalVibration vib) { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 1c11c6701643..c6e6e761c0bc 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2538,6 +2538,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } if (!activityAllDrawn && !isActivityHome) { + // Only check the special case of a fragment host task because the starting window + // may not be visible if the client organizer delays the transition ready. + if (task.mTaskFragmentHostProcessName != null) { + // It may be launched from a task trampoline that already has a starting window. + // Return NONE because 2 consecutive splashes may not look smooth in visual. + final Task prevTask = task.getParent().getTaskBelow(task); + if (prevTask != null) { + final ActivityRecord prevTaskTop = prevTask.getTopMostActivity(); + if (prevTaskTop != null && prevTaskTop.hasStartingWindow()) { + return STARTING_WINDOW_TYPE_NONE; + } + } + } return STARTING_WINDOW_TYPE_SPLASH_SCREEN; } } diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java index 9f40bed3fcc8..25fdf89afad1 100644 --- a/services/core/java/com/android/server/wm/Dimmer.java +++ b/services/core/java/com/android/server/wm/Dimmer.java @@ -17,8 +17,6 @@ package com.android.server.wm; import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_DIMMER; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.NonNull; import android.annotation.Nullable; @@ -44,7 +42,8 @@ class Dimmer { */ private final WindowContainer<?> mHost; - private static final String TAG = TAG_WITH_CLASS_NAME ? "Dimmer" : TAG_WM; + private static final String TAG = "WindowManagerDimmer"; + DimState mDimState; final DimmerAnimationHelper.AnimationAdapterFactory mAnimationAdapterFactory; @@ -69,9 +68,10 @@ class Dimmer { DimState() { mHostContainer = mHost; - mAnimationHelper = new DimmerAnimationHelper(mAnimationAdapterFactory); + mAnimationHelper = new DimmerAnimationHelper(mHost, mAnimationAdapterFactory); try { mDimSurface = makeDimLayer(); + EventLogTags.writeWmDimCreated(mHost.getName(), mDimSurface.getLayerId()); } catch (Surface.OutOfResourcesException e) { Log.w(TAG, "OutOfResourcesException creating dim surface"); } @@ -102,6 +102,11 @@ class Dimmer { * Prepare the dim for the exit animation */ void exit(@NonNull SurfaceControl.Transaction t) { + EventLogTags.writeWmDimExit(mDimState.mDimSurface.getLayerId(), + mDimState.mLastDimmingWindow != null + ? mDimState.mLastDimmingWindow.getName() : "-", + mDimState.mHostContainer.isVisible() ? 1 : 0, + mAnimateExit ? 0 : 1); if (!mAnimateExit) { remove(t); } else { @@ -111,8 +116,10 @@ class Dimmer { } void remove(@NonNull SurfaceControl.Transaction t) { + EventLogTags.writeWmDimCancelAnim(mDimSurface.getLayerId(), "ready to remove"); mAnimationHelper.stopCurrentAnimation(mDimSurface); if (mDimSurface.isValid()) { + EventLogTags.writeWmDimRemoved(mDimSurface.getLayerId()); t.remove(mDimSurface); ProtoLog.d(WM_DEBUG_DIMMER, "Removing dim surface %s on transaction %s", this, t); @@ -126,6 +133,13 @@ class Dimmer { return "Dimmer#DimState with host=" + mHostContainer + ", surface=" + mDimSurface; } + + String reasonForRemoving() { + return mLastDimmingWindow != null ? mLastDimmingWindow + + " is dimming but host " + mHostContainer + " is not visibleRequested" + : " no one is dimming"; + } + /** * Set the parameters to prepare the dim to be relative parented to the dimming container */ diff --git a/services/core/java/com/android/server/wm/DimmerAnimationHelper.java b/services/core/java/com/android/server/wm/DimmerAnimationHelper.java index 0d0e5483fc0e..1d447dd692df 100644 --- a/services/core/java/com/android/server/wm/DimmerAnimationHelper.java +++ b/services/core/java/com/android/server/wm/DimmerAnimationHelper.java @@ -76,9 +76,11 @@ public class DimmerAnimationHelper { return mDimmingContainer != null && mDimmingContainer == other.mDimmingContainer; } - void inheritPropertiesFromAnimation(@NonNull AnimationSpec anim) { - mAlpha = anim.mCurrentAlpha; - mBlurRadius = anim.mCurrentBlur; + void inheritPropertiesFromAnimation(@Nullable AnimationSpec anim) { + if (anim != null) { + mAlpha = anim.mCurrentAlpha; + mBlurRadius = anim.mCurrentBlur; + } } @Override @@ -92,11 +94,13 @@ public class DimmerAnimationHelper { private final Change mRequestedProperties = new Change(); private AnimationSpec mAlphaAnimationSpec; + private final SurfaceAnimationRunner mSurfaceAnimationRunner; private final AnimationAdapterFactory mAnimationAdapterFactory; private AnimationAdapter mLocalAnimationAdapter; - DimmerAnimationHelper(AnimationAdapterFactory animationFactory) { + DimmerAnimationHelper(WindowContainer<?> host, AnimationAdapterFactory animationFactory) { mAnimationAdapterFactory = animationFactory; + mSurfaceAnimationRunner = host.mWmService.mSurfaceAnimationRunner; } void setExitParameters() { @@ -160,6 +164,7 @@ public class DimmerAnimationHelper { } if (!startProperties.hasSameVisualProperties(mRequestedProperties)) { + EventLogTags.writeWmDimCancelAnim(dim.mDimSurface.getLayerId(), "new target values"); stopCurrentAnimation(dim.mDimSurface); if (dim.mSkipAnimation @@ -189,13 +194,15 @@ public class DimmerAnimationHelper { ProtoLog.v(WM_DEBUG_DIMMER, "Starting animation on %s", dim); mAlphaAnimationSpec = getRequestedAnimationSpec(from, to); mLocalAnimationAdapter = mAnimationAdapterFactory.get(mAlphaAnimationSpec, - dim.mHostContainer.mWmService.mSurfaceAnimationRunner); + mSurfaceAnimationRunner); float targetAlpha = to.mAlpha; + EventLogTags.writeWmDimAnimate(dim.mDimSurface.getLayerId(), targetAlpha, to.mBlurRadius); mLocalAnimationAdapter.startAnimation(dim.mDimSurface, t, ANIMATION_TYPE_DIMMER, /* finishCallback */ (type, animator) -> { synchronized (dim.mHostContainer.mWmService.mGlobalLock) { + EventLogTags.writeWmDimFinishAnim(dim.mDimSurface.getLayerId()); SurfaceControl.Transaction finishTransaction = dim.mHostContainer.getSyncTransaction(); setCurrentAlphaBlur(dim, finishTransaction); @@ -208,18 +215,12 @@ public class DimmerAnimationHelper { }); } - private boolean isAnimating() { - return mAlphaAnimationSpec != null; - } - void stopCurrentAnimation(@NonNull SurfaceControl surface) { - if (mLocalAnimationAdapter != null && isAnimating()) { - // Save the current animation progress and cancel the animation - mCurrentProperties.inheritPropertiesFromAnimation(mAlphaAnimationSpec); - mLocalAnimationAdapter.onAnimationCancelled(surface); - mLocalAnimationAdapter = null; - mAlphaAnimationSpec = null; - } + // (If animating) save the current animation progress and cancel the animation + mCurrentProperties.inheritPropertiesFromAnimation(mAlphaAnimationSpec); + mSurfaceAnimationRunner.onAnimationCancelled(surface); + mLocalAnimationAdapter = null; + mAlphaAnimationSpec = null; } @NonNull diff --git a/services/core/java/com/android/server/wm/EventLogTags.logtags b/services/core/java/com/android/server/wm/EventLogTags.logtags index cc2249de010c..9d6688648021 100644 --- a/services/core/java/com/android/server/wm/EventLogTags.logtags +++ b/services/core/java/com/android/server/wm/EventLogTags.logtags @@ -87,3 +87,16 @@ option java_package com.android.server.wm # Entering pip called 38000 wm_enter_pip (User|1|5),(Token|1|5),(Component Name|3),(is Auto Enter|3) + +# Dim layer is created +38200 wm_dim_created (Host|3),(Surface|1) +# Dimmer is ready for removal +38201 wm_dim_exit (Surface|1),(dimmingWindow|3),(hostIsVisible|1),(removeImmediately|1) +# Dimmer is starting an animation +38202 wm_dim_animate (Surface|1, (toAlpha|5), (toBlur|5)) +# Dimmer animation is cancelled +38203 wm_dim_cancel_anim (Surface|1),(reason|3) +# Dimmer animation is finished +38204 wm_dim_finish_anim (Surface|1) +# Dimmer removing surface +38205 wm_dim_removed (Surface|1)
\ No newline at end of file diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index 4b2d45430bb4..cf145f94f787 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -228,13 +228,11 @@ class InsetsStateController { changed |= provider.updateClientVisibility(caller, isImeProvider ? statsToken : null); } - if (!android.view.inputmethod.Flags.refactorInsetsController()) { - if (changed) { - notifyInsetsChanged(); - mDisplayContent.updateSystemGestureExclusion(); + if (changed) { + notifyInsetsChanged(); + mDisplayContent.updateSystemGestureExclusion(); - mDisplayContent.getDisplayPolicy().updateSystemBarAttributes(); - } + mDisplayContent.getDisplayPolicy().updateSystemBarAttributes(); } } diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index 9de96f1440a2..81a04af17703 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -326,9 +326,12 @@ class RecentTasks { ProtoLog.i(WM_DEBUG_TASKS, "Setting frozen recents task list"); // Always update the reordering time when this is called to ensure that the timeout - // is reset + // is reset. Extend this duration when running in tests. + final long timeout = ActivityManager.isRunningInUserTestHarness() + ? mFreezeTaskListTimeoutMs * 10 + : mFreezeTaskListTimeoutMs; mService.mH.removeCallbacks(mResetFreezeTaskListOnTimeoutRunnable); - mService.mH.postDelayed(mResetFreezeTaskListOnTimeoutRunnable, mFreezeTaskListTimeoutMs); + mService.mH.postDelayed(mResetFreezeTaskListOnTimeoutRunnable, timeout); } /** diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 1bb4c41e79e0..0f66b93ca273 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -706,6 +706,10 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { win.setRequestedVisibleTypes(requestedVisibleTypes); win.getDisplayContent().getInsetsPolicy().onRequestedVisibleTypesChanged(win, imeStatsToken); + final Task task = win.getTask(); + if (task != null) { + task.dispatchTaskInfoChangedIfNeeded(/* forced= */ true); + } } else { EmbeddedWindowController.EmbeddedWindow embeddedWindow = null; if (android.view.inputmethod.Flags.refactorInsetsController()) { diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 352dc528f815..dbc3b76c22a1 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -3436,7 +3436,8 @@ class Task extends TaskFragment { info.isSleeping = shouldSleepActivities(); info.isTopActivityTransparent = top != null && !top.fillsParent(); info.lastNonFullscreenBounds = topTask.mLastNonFullscreenBounds; - final WindowState windowState = top != null ? top.findMainWindow() : null; + final WindowState windowState = top != null + ? top.findMainWindow(/* includeStartingApp= */ false) : null; info.requestedVisibleTypes = (windowState != null && Flags.enableFullyImmersiveInDesktop()) ? windowState.getRequestedVisibleTypes() : WindowInsets.Type.defaultVisible(); AppCompatUtils.fillAppCompatTaskInfo(this, info, top); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 88b2d229e083..54b257cff11d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -10233,6 +10233,17 @@ public class WindowManagerService extends IWindowManager.Stub } } + /** + * Resets the spatial ordering of recents for testing purposes. + */ + void resetFreezeRecentTaskListReordering() { + if (!checkCallingPermission(permission.MANAGE_ACTIVITY_TASKS, + "resetFreezeRecentTaskListReordering()")) { + throw new SecurityException("Requires MANAGE_ACTIVITY_TASKS permission"); + } + mAtmService.getRecentTasks().resetFreezeTaskListReorderingOnTimeout(); + } + @Override public void registerTrustedPresentationListener(IBinder window, ITrustedPresentationListener listener, diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java index 21ed8d793b24..fe2bcc7a74f3 100644 --- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java +++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java @@ -161,6 +161,8 @@ public class WindowManagerShellCommand extends ShellCommand { return runReset(pw); case "disable-blur": return runSetBlurDisabled(pw); + case "reset-freeze-recent-tasks": + return runResetFreezeRecentTaskListReordering(pw); case "set-display-windowing-mode": return runSetDisplayWindowingMode(pw); case "get-display-windowing-mode": @@ -275,6 +277,11 @@ public class WindowManagerShellCommand extends ShellCommand { return 0; } + private int runResetFreezeRecentTaskListReordering(PrintWriter pw) throws RemoteException { + mInternal.resetFreezeRecentTaskListReordering(); + return 0; + } + private void printInitialDisplayDensity(PrintWriter pw , int displayId) { try { final int initialDensity = mInterface.getInitialDisplayDensity(displayId); @@ -1592,6 +1599,8 @@ public class WindowManagerShellCommand extends ShellCommand { printLetterboxHelp(pw); printMultiWindowConfigHelp(pw); + pw.println(" reset-freeze-recent-tasks"); + pw.println(" Resets the spatial ordering of the recent tasks list"); pw.println(" set-display-windowing-mode [-d DISPLAY_ID] [mode_id]"); pw.println(" As mode_id, use " + WINDOWING_MODE_UNDEFINED + " for undefined, " + WINDOWING_MODE_FREEFORM + " for freeform, " + WINDOWING_MODE_FULLSCREEN + " for" diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 079170a70433..81af78e5ce25 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2989,15 +2989,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return (mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0; } - @Override - void resolveOverrideConfiguration(Configuration newParentConfig) { - super.resolveOverrideConfiguration(newParentConfig); - if (mActivityRecord != null) { - // Let the activity decide whether to apply the size override. - return; - } - final Configuration resolvedConfig = getResolvedOverrideConfiguration(); - resolvedConfig.seq = newParentConfig.seq; + void applySizeOverride(Configuration newParentConfig, Configuration resolvedConfig) { applySizeOverrideIfNeeded( getDisplayContent(), mSession.mProcess.mInfo, @@ -3380,8 +3372,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (cleanupOnResume) { requestUpdateWallpaperIfNeeded(); } - mDestroying = false; - destroyedSomething = true; + if (!mHasSurface) { + mDestroying = false; + destroyedSomething = true; + } // Since mDestroying will affect ActivityRecord#allDrawn, we need to perform another // traversal in case we are waiting on this window to start the transition. diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 44e237aa27de..004f406035c0 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -672,6 +672,15 @@ class WindowToken extends WindowContainer<WindowState> { getResolvedOverrideConfiguration().updateFrom( mFixedRotationTransformState.mRotatedOverrideConfiguration); } + if (asActivityRecord() == null) { + // Let ActivityRecord override the config if there is one. Otherwise, override here. + // Resolve WindowToken's configuration by the latest window. + final WindowState win = getTopChild(); + if (win != null) { + final Configuration resolvedConfig = getResolvedOverrideConfiguration(); + win.applySizeOverride(newParentConfig, resolvedConfig); + } + } } @Override diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java index 984105865f7d..cb333f02757e 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java @@ -99,10 +99,11 @@ import java.util.concurrent.CompletableFuture; final class DevicePolicyEngine { static final String TAG = "DevicePolicyEngine"; - // TODO(b/281701062): reference role name from role manager once its exposed. static final String DEVICE_LOCK_CONTROLLER_ROLE = "android.app.role.SYSTEM_FINANCED_DEVICE_CONTROLLER"; + static final String SYSTEM_SUPERVISION_ROLE = "android.app.role.SYSTEM_SUPERVISION"; + private static final String CELLULAR_2G_USER_RESTRICTION_ID = DevicePolicyIdentifiers.getIdentifierForUserRestriction( UserManager.DISALLOW_CELLULAR_2G); @@ -1235,6 +1236,8 @@ final class DevicePolicyEngine { } } for (EnforcingAdmin admin : admins) { + // No need to make changes to system enforcing admins. + if (admin.isSystemAuthority()) break; if (updatedPackage == null || updatedPackage.equals(admin.getPackageName())) { if (!isPackageInstalled(admin.getPackageName(), userId)) { Slogf.i(TAG, String.format( diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 50f3f39e7e66..28eec5ca7319 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -9004,26 +9004,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } - - CallerIdentity caller; - if (Flags.setAutoTimeEnabledCoexistence()) { - caller = getCallerIdentity(who, callerPackageName); - } else { - caller = getCallerIdentity(who); - } - - if (Flags.setAutoTimeEnabledCoexistence()) { - // The effect of this policy is device-wide. - enforcePermission(SET_TIME, caller.getPackageName(), UserHandle.USER_ALL); - } else { - Objects.requireNonNull(who, "ComponentName is null"); - Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller) - || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner( - caller)); - } + CallerIdentity caller = getCallerIdentity(who); + Objects.requireNonNull(who, "ComponentName is null"); + Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller) + || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner( + caller)); mInjector.binderWithCleanCallingIdentity(() -> mInjector.settingsGlobalPutInt(Settings.Global.AUTO_TIME, enabled ? 1 : 0)); - DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_AUTO_TIME) .setAdmin(caller.getPackageName()) @@ -9039,23 +9026,74 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return false; } - CallerIdentity caller; - if (Flags.setAutoTimeEnabledCoexistence()) { - caller = getCallerIdentity(who, callerPackageName); - } else { - caller = getCallerIdentity(who); + CallerIdentity caller = getCallerIdentity(who); + + Objects.requireNonNull(who, "ComponentName is null"); + Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller) + || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner(caller)); + + return mInjector.settingsGlobalGetInt(Global.AUTO_TIME, 0) > 0; + } + + /** + * Set whether auto time is enabled on the device. + */ + @Override + public void setAutoTimePolicy(String callerPackageName, int policy) { + if (!mHasFeature) { + return; } - if (Flags.setAutoTimeEnabledCoexistence()) { - enforceCanQuery(SET_TIME, caller.getPackageName(), UserHandle.USER_ALL); + final Set<Integer> allowedValues = + Set.of( + DevicePolicyManager.AUTO_TIME_ENABLED, + DevicePolicyManager.AUTO_TIME_DISABLED, + DevicePolicyManager.AUTO_TIME_NOT_CONTROLLED_BY_POLICY); + Preconditions.checkArgument( + allowedValues.contains(policy), "Provided mode is not one of the allowed values."); + + CallerIdentity caller = getCallerIdentity(callerPackageName); + // The effect of this policy is device-wide. + EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( + /* who */ null, + SET_TIME, + caller.getPackageName(), + UserHandle.USER_ALL + ); + if (policy == DevicePolicyManager.AUTO_TIME_NOT_CONTROLLED_BY_POLICY) { + mDevicePolicyEngine.removeGlobalPolicy(PolicyDefinition.AUTO_TIME, enforcingAdmin); } else { - Objects.requireNonNull(who, "ComponentName is null"); - Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller) - || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner( - caller)); + mDevicePolicyEngine.setGlobalPolicy( + PolicyDefinition.AUTO_TIME, + enforcingAdmin, + new IntegerPolicyValue(policy)); + DevicePolicyEventLogger + .createEvent(DevicePolicyEnums.SET_AUTO_TIME) + .setAdmin(caller.getPackageName()) + .setBoolean(policy == DevicePolicyManager.AUTO_TIME_ENABLED) + .write(); } + } - return mInjector.settingsGlobalGetInt(Global.AUTO_TIME, 0) > 0; + /** + * Returns whether auto time is used on the device or not. + */ + @Override + public int getAutoTimePolicy(String callerPackageName) { + if (!mHasFeature) { + return DevicePolicyManager.AUTO_TIME_NOT_CONTROLLED_BY_POLICY; + } + CallerIdentity caller = getCallerIdentity(callerPackageName); + // The effect of this policy is device-wide. + EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( + /* who */ null, + SET_TIME, + caller.getPackageName(), + UserHandle.USER_ALL + ); + Integer state = mDevicePolicyEngine.getGlobalPolicySetByAdmin( + PolicyDefinition.AUTO_TIME, enforcingAdmin); + return state != null ? state : DevicePolicyManager.AUTO_TIME_NOT_CONTROLLED_BY_POLICY; } /** @@ -9068,35 +9106,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } - CallerIdentity caller; - if (Flags.setAutoTimeZoneEnabledCoexistence()) { - caller = getCallerIdentity(who, callerPackageName); - } else { - caller = getCallerIdentity(who); - } + CallerIdentity caller = getCallerIdentity(who); - if (Flags.setAutoTimeZoneEnabledCoexistence()) { - // The effect of this policy is device-wide. - EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( - who, - SET_TIME_ZONE, - caller.getPackageName(), - UserHandle.USER_ALL - ); - mDevicePolicyEngine.setGlobalPolicy( - PolicyDefinition.AUTO_TIMEZONE, - // TODO(b/260573124): add correct enforcing admin when permission changes are - // merged. - enforcingAdmin, - new BooleanPolicyValue(enabled)); - } else { - Objects.requireNonNull(who, "ComponentName is null"); - Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller) - || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner( - caller)); - mInjector.binderWithCleanCallingIdentity(() -> - mInjector.settingsGlobalPutInt(Global.AUTO_TIME_ZONE, enabled ? 1 : 0)); - } + Objects.requireNonNull(who, "ComponentName is null"); + Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller) + || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner( + caller)); + mInjector.binderWithCleanCallingIdentity(() -> + mInjector.settingsGlobalPutInt(Global.AUTO_TIME_ZONE, enabled ? 1 : 0)); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_AUTO_TIME_ZONE) @@ -9114,24 +9131,68 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return false; } - CallerIdentity caller; - if (Flags.setAutoTimeZoneEnabledCoexistence()) { - caller = getCallerIdentity(who, callerPackageName); - } else { - caller = getCallerIdentity(who); + CallerIdentity caller = getCallerIdentity(who); + Objects.requireNonNull(who, "ComponentName is null"); + Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller) + || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner( + caller)); + return mInjector.settingsGlobalGetInt(Global.AUTO_TIME_ZONE, 0) > 0; + } + + /** + * Set auto time zone state. + */ + public void setAutoTimeZonePolicy(String callerPackageName, int policy) { + if (!mHasFeature) { + return; } - if (Flags.setAutoTimeZoneEnabledCoexistence()) { - // The effect of this policy is device-wide. - enforceCanQuery(SET_TIME_ZONE, caller.getPackageName(), UserHandle.USER_ALL); + CallerIdentity caller = getCallerIdentity(callerPackageName); + // The effect of this policy is device-wide. + EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( + /* who */ null, + SET_TIME_ZONE, + caller.getPackageName(), + UserHandle.USER_ALL + ); + + if (policy != DevicePolicyManager.AUTO_TIME_ZONE_NOT_CONTROLLED_BY_POLICY) { + mDevicePolicyEngine.setGlobalPolicy( + PolicyDefinition.AUTO_TIME_ZONE, + enforcingAdmin, + new IntegerPolicyValue(policy)); + + DevicePolicyEventLogger + .createEvent(DevicePolicyEnums.SET_AUTO_TIME_ZONE) + .setAdmin(caller.getPackageName()) + .setBoolean(policy == DevicePolicyManager.AUTO_TIME_ZONE_ENABLED) + .write(); } else { - Objects.requireNonNull(who, "ComponentName is null"); - Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller) - || isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner( - caller)); + mDevicePolicyEngine.removeGlobalPolicy( + PolicyDefinition.AUTO_TIME_ZONE, + enforcingAdmin); } + } - return mInjector.settingsGlobalGetInt(Global.AUTO_TIME_ZONE, 0) > 0; + /** + * Returns whether auto time zone is used on the device or not. + */ + @Override + public int getAutoTimeZonePolicy(String callerPackageName) { + if (!mHasFeature) { + return DevicePolicyManager.AUTO_TIME_ZONE_NOT_CONTROLLED_BY_POLICY; + } + CallerIdentity caller = getCallerIdentity(callerPackageName); + // The effect of this policy is device-wide. + EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( + /* who */ null, + SET_TIME_ZONE, + caller.getPackageName(), + UserHandle.USER_ALL + ); + Integer state = mDevicePolicyEngine.getGlobalPolicySetByAdmin( + PolicyDefinition.AUTO_TIME_ZONE, enforcingAdmin); + return state != null ? state : DevicePolicyManager.AUTO_TIME_ZONE_NOT_CONTROLLED_BY_POLICY; } // TODO (b/137101239): remove this method in follow-up CL @@ -13301,10 +13362,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Objects.requireNonNull(systemEntity); CallerIdentity caller = getCallerIdentity(); - if (caller.getUid() != Process.SYSTEM_UID) { + if (!isSystemUid(caller)) { throw new SecurityException("Only system services can call setUserRestrictionForUser" + " on a target user: " + targetUser); } + if (!UserRestrictionsUtils.isValidRestriction(key)) { + throw new IllegalArgumentException("Invalid restriction key: " + key); + } if (VERBOSE_LOG) { Slogf.v(LOG_TAG, "Creating SystemEnforcingAdmin %s for calling package %s", systemEntity, caller.getPackageName()); @@ -13437,6 +13501,31 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { logUserRestrictionCall(key, /* enabled= */ true, /* parent= */ false, caller, UserHandle.USER_ALL); } + + @Override + public void setUserRestrictionGloballyFromSystem(@NonNull String systemEntity, String key, + boolean enabled) { + Objects.requireNonNull(systemEntity); + + CallerIdentity caller = getCallerIdentity(); + if (!isSystemUid(caller)) { + throw new SecurityException("Only system services can call" + + " setUserRestrictionGloballyFromSystem"); + } + if (!UserRestrictionsUtils.isValidRestriction(key)) { + throw new IllegalArgumentException("Invalid restriction key: " + key); + } + if (VERBOSE_LOG) { + Slogf.v(LOG_TAG, "Creating SystemEnforcingAdmin %s for calling package %s", + systemEntity, caller.getPackageName()); + } + EnforcingAdmin admin = EnforcingAdmin.createSystemEnforcingAdmin(systemEntity); + + setGlobalUserRestrictionInternal(admin, key, enabled); + + logUserRestrictionCall(key, enabled, /* parent= */ false, caller, UserHandle.USER_ALL); + } + private void setLocalUserRestrictionInternal( EnforcingAdmin admin, String key, boolean enabled, int userId) { PolicyDefinition<Boolean> policyDefinition = @@ -13454,6 +13543,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { userId); } } + private void setGlobalUserRestrictionInternal( EnforcingAdmin admin, String key, boolean enabled) { PolicyDefinition<Boolean> policyDefinition = @@ -19058,6 +19148,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + private boolean isAnyResetPasswordTokenActiveForUser(int userId) { + return mDevicePolicyEngine + .getLocalPoliciesSetByAdmins(PolicyDefinition.RESET_PASSWORD_TOKEN, userId) + .values() + .stream() + .anyMatch((p) -> isResetPasswordTokenActiveForUserLocked(p.getValue(), userId)); + } + private boolean isResetPasswordTokenActiveForUserLocked( long passwordTokenHandle, int userHandle) { if (passwordTokenHandle != 0) { @@ -20913,6 +21011,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()), String.format(NOT_SYSTEM_CALLER_MSG, "call canProfileOwnerResetPasswordWhenLocked")); + if (Flags.resetPasswordWithTokenCoexistence()) { + return isAnyResetPasswordTokenActiveForUser(userId); + } synchronized (getLockObject()) { final ActiveAdmin poAdmin = getProfileOwnerAdminLocked(userId); DevicePolicyData policy = getUserData(userId); @@ -23786,9 +23887,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Slogf.i(LOG_TAG, "Started device policies migration to the device policy engine."); // TODO(b/359188869): Move this to the current migration method. - if (Flags.setAutoTimeZoneEnabledCoexistence()) { - migrateAutoTimezonePolicy(); - } if (Flags.setPermissionGrantStateCoexistence()) { migratePermissionGrantStatePolicies(); } @@ -23837,11 +23935,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Additional migration steps should repeat the pattern above with a new backupId. } - private void migrateAutoTimezonePolicy() { - Slogf.i(LOG_TAG, "Skipping Migration of AUTO_TIMEZONE policy to device policy engine," - + "as no way to identify if the value was set by the admin or the user."); - } - private void migratePermissionGrantStatePolicies() { Slogf.i(LOG_TAG, "Migrating PERMISSION_GRANT policy to device policy engine."); for (UserInfo userInfo : mUserManager.getUsers()) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java index 634f1bc97772..58e3a7d236b4 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java @@ -280,6 +280,10 @@ final class EnforcingAdmin { return getAuthorities().contains(authority); } + boolean isSystemAuthority() { + return mIsSystemAuthority; + } + @NonNull String getPackageName() { return mPackageName; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java index f1711f5f8c0b..24b16b7c2c60 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java @@ -17,6 +17,7 @@ package com.android.server.devicepolicy; import static com.android.server.devicepolicy.DevicePolicyEngine.DEVICE_LOCK_CONTROLLER_ROLE; +import static com.android.server.devicepolicy.DevicePolicyEngine.SYSTEM_SUPERVISION_ROLE; import android.annotation.NonNull; import android.annotation.Nullable; @@ -94,14 +95,18 @@ final class PolicyDefinition<V> { private static final MostRestrictive<Boolean> TRUE_MORE_RESTRICTIVE = new MostRestrictive<>( List.of(new BooleanPolicyValue(true), new BooleanPolicyValue(false))); - static PolicyDefinition<Boolean> AUTO_TIMEZONE = new PolicyDefinition<>( + static PolicyDefinition<Integer> AUTO_TIME_ZONE = new PolicyDefinition<>( new NoArgsPolicyKey(DevicePolicyIdentifiers.AUTO_TIMEZONE_POLICY), - // auto timezone is disabled by default, hence enabling it is more restrictive. - TRUE_MORE_RESTRICTIVE, + // Auto time zone is enabled by default. Enabled state has higher priority given it + // means the time will be more precise and other applications can rely on that for + // their purposes. + new TopPriority<>(List.of( + EnforcingAdmin.getRoleAuthorityOf(SYSTEM_SUPERVISION_ROLE), + EnforcingAdmin.getRoleAuthorityOf(DEVICE_LOCK_CONTROLLER_ROLE), + EnforcingAdmin.DPC_AUTHORITY)), POLICY_FLAG_GLOBAL_ONLY_POLICY, - (Boolean value, Context context, Integer userId, PolicyKey policyKey) -> - PolicyEnforcerCallbacks.setAutoTimezoneEnabled(value, context), - new BooleanPolicySerializer()); + PolicyEnforcerCallbacks::setAutoTimeZonePolicy, + new IntegerPolicySerializer()); static final PolicyDefinition<Integer> GENERIC_PERMISSION_GRANT = new PolicyDefinition<>( @@ -344,12 +349,22 @@ final class PolicyDefinition<V> { PolicyEnforcerCallbacks::setMtePolicy, new IntegerPolicySerializer()); + static PolicyDefinition<Integer> AUTO_TIME = new PolicyDefinition<>( + new NoArgsPolicyKey(DevicePolicyIdentifiers.AUTO_TIME_POLICY), + new TopPriority<>(List.of( + EnforcingAdmin.getRoleAuthorityOf(SYSTEM_SUPERVISION_ROLE), + EnforcingAdmin.getRoleAuthorityOf(DEVICE_LOCK_CONTROLLER_ROLE), + EnforcingAdmin.DPC_AUTHORITY)), + POLICY_FLAG_GLOBAL_ONLY_POLICY, + PolicyEnforcerCallbacks::setAutoTimePolicy, + new IntegerPolicySerializer()); + private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>(); private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>(); // TODO(b/277218360): Revisit policies that should be marked as global-only. static { - POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.AUTO_TIMEZONE_POLICY, AUTO_TIMEZONE); + POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.AUTO_TIMEZONE_POLICY, AUTO_TIME_ZONE); POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.PERMISSION_GRANT_POLICY, GENERIC_PERMISSION_GRANT); POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.SECURITY_LOGGING_POLICY, @@ -392,6 +407,7 @@ final class PolicyDefinition<V> { PACKAGES_SUSPENDED); POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.MEMORY_TAGGING_POLICY, MEMORY_TAGGING); + POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.AUTO_TIME_POLICY, AUTO_TIME); // User Restriction Policies USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java index fdc0ec1a0471..8f80004a7ea5 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java @@ -81,20 +81,24 @@ final class PolicyEnforcerCallbacks { return AndroidFuture.completedFuture(true); } - static CompletableFuture<Boolean> setAutoTimezoneEnabled(@Nullable Boolean enabled, - @NonNull Context context) { + static CompletableFuture<Boolean> setAutoTimeZonePolicy( + @Nullable Integer policy, @NonNull Context context, int userId, + @NonNull PolicyKey policyKey) { if (!Flags.setAutoTimeZoneEnabledCoexistence()) { - Slogf.w(LOG_TAG, "Trying to enforce setAutoTimezoneEnabled while flag is off."); + Slogf.w(LOG_TAG, "Trying to enforce setAutoTimeZonePolicy while flag is off."); return AndroidFuture.completedFuture(true); } return Binder.withCleanCallingIdentity(() -> { Objects.requireNonNull(context); - - int value = enabled != null && enabled ? 1 : 0; - return AndroidFuture.completedFuture( - Settings.Global.putInt( - context.getContentResolver(), Settings.Global.AUTO_TIME_ZONE, - value)); + if (policy != null && + policy == DevicePolicyManager.AUTO_TIME_ZONE_NOT_CONTROLLED_BY_POLICY) { + return AndroidFuture.completedFuture(false); + } + int enabled = policy != null && + policy == DevicePolicyManager.AUTO_TIME_ZONE_ENABLED ? 1 : 0; + return AndroidFuture.completedFuture(Settings.Global.putInt( + context.getContentResolver(), Settings.Global.AUTO_TIME_ZONE, + enabled)); }); } @@ -208,6 +212,25 @@ final class PolicyEnforcerCallbacks { return AndroidFuture.completedFuture(true); } + public static CompletableFuture<Boolean> setAutoTimePolicy( + Integer policy, Context context, Integer userId, PolicyKey policyKey) { + if (!Flags.setAutoTimeEnabledCoexistence()) { + Slogf.w(LOG_TAG, "Trying to enforce setAutoTimePolicy while flag is off."); + return AndroidFuture.completedFuture(true); + } + return Binder.withCleanCallingIdentity(() -> { + Objects.requireNonNull(context); + if (policy != null + && policy == DevicePolicyManager.AUTO_TIME_NOT_CONTROLLED_BY_POLICY) { + return AndroidFuture.completedFuture(false); + } + int enabled = policy != null && policy == DevicePolicyManager.AUTO_TIME_ENABLED ? 1 : 0; + return AndroidFuture.completedFuture( + Settings.Global.putInt( + context.getContentResolver(), Settings.Global.AUTO_TIME, enabled)); + }); + } + private static class BlockingCallback { private final CountDownLatch mLatch = new CountDownLatch(1); private final AtomicReference<Boolean> mValue = new AtomicReference<>(); diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt index 69714f3ecb5b..3fdb53f5ab59 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt @@ -582,6 +582,34 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag PackageImpl::setSystemExt, true ), + getSetByValue( + AndroidPackage::getAlternateLauncherIconResIds, + PackageImpl::setAlternateLauncherIconResIds, + intArrayOf(3, 5, 7), + compare = { first, second -> + equalBy( + first, second, + { it.size }, + { it[0] }, + { it[1] }, + { it[2] } + ) + } + ), + getSetByValue( + AndroidPackage::getAlternateLauncherLabelResIds, + PackageImpl::setAlternateLauncherLabelResIds, + intArrayOf(3, 5, 7), + compare = { first, second -> + equalBy( + first, second, + { it.size }, + { it[0] }, + { it[1] }, + { it[2] } + ) + } + ), ) override fun initialObject() = PackageImpl.forParsing( diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java index 80e5ee39c13d..759976f79371 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -226,6 +226,9 @@ public class DisplayManagerServiceTest { "EVENT_DISPLAY_HDR_SDR_RATIO_CHANGED"; private static final String EVENT_DISPLAY_CONNECTED = "EVENT_DISPLAY_CONNECTED"; private static final String EVENT_DISPLAY_DISCONNECTED = "EVENT_DISPLAY_DISCONNECTED"; + private static final String EVENT_DISPLAY_REFRESH_RATE_CHANGED = + "EVENT_DISPLAY_REFRESH_RATE_CHANGED"; + private static final String EVENT_DISPLAY_STATE_CHANGED = "EVENT_DISPLAY_STATE_CHANGED"; private static final String DISPLAY_GROUP_EVENT_ADDED = "DISPLAY_GROUP_EVENT_ADDED"; private static final String DISPLAY_GROUP_EVENT_REMOVED = "DISPLAY_GROUP_EVENT_REMOVED"; private static final String DISPLAY_GROUP_EVENT_CHANGED = "DISPLAY_GROUP_EVENT_CHANGED"; @@ -4234,6 +4237,10 @@ public class DisplayManagerServiceTest { return EVENT_DISPLAY_CONNECTED; case DisplayManagerGlobal.EVENT_DISPLAY_DISCONNECTED: return EVENT_DISPLAY_DISCONNECTED; + case DisplayManagerGlobal.EVENT_DISPLAY_REFRESH_RATE_CHANGED: + return EVENT_DISPLAY_REFRESH_RATE_CHANGED; + case DisplayManagerGlobal.EVENT_DISPLAY_STATE_CHANGED: + return EVENT_DISPLAY_STATE_CHANGED; default: return "UNKNOWN: " + eventType; } diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java index b6da3ae6a5cd..ff652a2727de 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java @@ -35,7 +35,9 @@ import static com.android.server.display.DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DE import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED; import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_CONNECTED; import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_DISCONNECTED; +import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REFRESH_RATE_CHANGED; import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED; +import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_STATE_CHANGED; import static com.android.server.display.layout.Layout.Display.POSITION_REAR; import static com.android.server.display.layout.Layout.Display.POSITION_UNKNOWN; import static com.android.server.utils.FoldSettingProvider.SETTING_VALUE_SELECTIVE_STAY_AWAKE; @@ -1158,6 +1160,29 @@ public class LogicalDisplayMapperTest { mLogicalDisplayMapper.getDisplayLocked(device2).getDevicePositionLocked()); } + @Test + public void updateAndGetMaskForDisplayPropertyChanges_getsPropertyChangedFlags() { + // Change the display state + DisplayInfo newDisplayInfo = new DisplayInfo(); + newDisplayInfo.state = STATE_OFF; + assertEquals(LOGICAL_DISPLAY_EVENT_STATE_CHANGED, + mLogicalDisplayMapper.updateAndGetMaskForDisplayPropertyChanges(newDisplayInfo)); + + // Change the refresh rate override + newDisplayInfo = new DisplayInfo(); + newDisplayInfo.refreshRateOverride = 30; + assertEquals(LOGICAL_DISPLAY_EVENT_REFRESH_RATE_CHANGED, + mLogicalDisplayMapper.updateAndGetMaskForDisplayPropertyChanges(newDisplayInfo)); + + // Change multiple properties + newDisplayInfo = new DisplayInfo(); + newDisplayInfo.refreshRateOverride = 30; + newDisplayInfo.state = STATE_OFF; + assertEquals(LOGICAL_DISPLAY_EVENT_REFRESH_RATE_CHANGED + | LOGICAL_DISPLAY_EVENT_STATE_CHANGED, + mLogicalDisplayMapper.updateAndGetMaskForDisplayPropertyChanges(newDisplayInfo)); + } + ///////////////// // Helper Methods ///////////////// diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp index 95acd75f32cc..993569fb17fe 100644 --- a/services/tests/mockingservicestests/Android.bp +++ b/services/tests/mockingservicestests/Android.bp @@ -78,7 +78,7 @@ android_test { "am_flags_lib", "device_policy_aconfig_flags_lib", ] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), { - "true": ["service-crashrecovery.impl"], + "true": ["service-crashrecovery-pre-jarjar"], default: [], }), diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java index a1a8b0ec7d2f..c1e71d2882b1 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java @@ -186,9 +186,9 @@ public abstract class BaseBroadcastQueueTest { doReturn(mAppStartInfoTracker).when(mProcessList).getAppStartInfoTracker(); doReturn(true).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastFilter.CHANGE_RESTRICT_PRIORITY_VALUES), anyInt()); + eq(BroadcastFilter.RESTRICT_PRIORITY_VALUES), anyInt()); doReturn(true).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), anyInt()); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), anyInt()); } public void tearDown() throws Exception { diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastFilterTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastFilterTest.java index e977a7d46f30..353dc2d24adf 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastFilterTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastFilterTest.java @@ -59,7 +59,7 @@ public class BroadcastFilterTest { @EnableFlags(Flags.FLAG_RESTRICT_PRIORITY_VALUES) public void testCalculateAdjustedPriority() { doReturn(true).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastFilter.CHANGE_RESTRICT_PRIORITY_VALUES), anyInt()); + eq(BroadcastFilter.RESTRICT_PRIORITY_VALUES), anyInt()); { // Pairs of {initial-priority, expected-adjusted-priority} @@ -96,7 +96,7 @@ public class BroadcastFilterTest { @EnableFlags(Flags.FLAG_RESTRICT_PRIORITY_VALUES) public void testCalculateAdjustedPriority_withChangeIdDisabled() { doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastFilter.CHANGE_RESTRICT_PRIORITY_VALUES), anyInt()); + eq(BroadcastFilter.RESTRICT_PRIORITY_VALUES), anyInt()); { // Pairs of {initial-priority, expected-adjusted-priority} @@ -133,7 +133,7 @@ public class BroadcastFilterTest { @DisableFlags(Flags.FLAG_RESTRICT_PRIORITY_VALUES) public void testCalculateAdjustedPriority_withFlagDisabled() { doReturn(true).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastFilter.CHANGE_RESTRICT_PRIORITY_VALUES), anyInt()); + eq(BroadcastFilter.RESTRICT_PRIORITY_VALUES), anyInt()); { // Pairs of {initial-priority, expected-adjusted-priority} @@ -170,7 +170,7 @@ public class BroadcastFilterTest { @DisableFlags(Flags.FLAG_RESTRICT_PRIORITY_VALUES) public void testCalculateAdjustedPriority_withFlagDisabled_withChangeIdDisabled() { doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastFilter.CHANGE_RESTRICT_PRIORITY_VALUES), anyInt()); + eq(BroadcastFilter.RESTRICT_PRIORITY_VALUES), anyInt()); { // Pairs of {initial-priority, expected-adjusted-priority} diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java index 1481085c5f71..88caaa61eacf 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java @@ -717,7 +717,7 @@ public final class BroadcastQueueModernImplTest extends BaseBroadcastQueueTest { @Test public void testRunnableAt_Cached_Prioritized_NonDeferrable_changeIdDisabled() { doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getUidForPackage(PACKAGE_GREEN))); final List receivers = List.of( withPriority(makeManifestReceiver(PACKAGE_RED, PACKAGE_RED), 10), @@ -1289,7 +1289,7 @@ public final class BroadcastQueueModernImplTest extends BaseBroadcastQueueTest { @Test public void testDeliveryGroupPolicy_prioritized_diffReceivers_changeIdDisabled() { doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getUidForPackage(PACKAGE_GREEN))); final Intent screenOn = new Intent(Intent.ACTION_SCREEN_ON); @@ -1824,7 +1824,7 @@ public final class BroadcastQueueModernImplTest extends BaseBroadcastQueueTest { @Test public void testDeliveryDeferredForCached_changeIdDisabled() throws Exception { doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getUidForPackage(PACKAGE_GREEN))); final ProcessRecord greenProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_GREEN)); @@ -2028,7 +2028,7 @@ public final class BroadcastQueueModernImplTest extends BaseBroadcastQueueTest { public void testDeliveryDeferredForCached_withInfiniteDeferred_changeIdDisabled() throws Exception { doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getUidForPackage(PACKAGE_GREEN))); final ProcessRecord greenProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_GREEN)); final ProcessRecord redProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_RED)); diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java index 9d92d5fe4f60..a38ef78f8c64 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java @@ -1660,7 +1660,7 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest { final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW); doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), eq(receiverBlueApp.uid)); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(receiverBlueApp.uid)); // Enqueue a normal broadcast that will go to several processes, and // then enqueue a foreground broadcast that risks reordering @@ -2472,7 +2472,7 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest { final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), eq(receiverBlueApp.uid)); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(receiverBlueApp.uid)); mUidObserver.onUidStateChanged(receiverGreenApp.info.uid, ActivityManager.PROCESS_STATE_TOP, 0, ActivityManager.PROCESS_CAPABILITY_NONE); diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java index a424bfdb8df4..f9f3790cae10 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastRecordTest.java @@ -19,7 +19,7 @@ package com.android.server.am; import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.server.am.BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE; +import static com.android.server.am.BroadcastRecord.LIMIT_PRIORITY_SCOPE; import static com.android.server.am.BroadcastRecord.DELIVERY_DEFERRED; import static com.android.server.am.BroadcastRecord.DELIVERY_DELIVERED; import static com.android.server.am.BroadcastRecord.DELIVERY_PENDING; @@ -109,7 +109,7 @@ public class BroadcastRecordTest { MockitoAnnotations.initMocks(this); doReturn(true).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), anyInt()); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), anyInt()); } @Test @@ -223,7 +223,7 @@ public class BroadcastRecordTest { @Test public void testIsPrioritized_withDifferentPriorities_withFirstUidChangeIdDisabled() { doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), eq(getAppId(1))); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getAppId(1))); assertTrue(isPrioritized(List.of( createResolveInfo(PACKAGE1, getAppId(1), 10), @@ -257,7 +257,7 @@ public class BroadcastRecordTest { @Test public void testIsPrioritized_withDifferentPriorities_withLastUidChangeIdDisabled() { doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), eq(getAppId(3))); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getAppId(3))); assertTrue(isPrioritized(List.of( createResolveInfo(PACKAGE1, getAppId(1), 10), @@ -295,7 +295,7 @@ public class BroadcastRecordTest { @Test public void testIsPrioritized_withDifferentPriorities_withUidChangeIdDisabled() { doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), eq(getAppId(2))); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getAppId(2))); assertTrue(isPrioritized(List.of( createResolveInfo(PACKAGE1, getAppId(1), 10), @@ -329,9 +329,9 @@ public class BroadcastRecordTest { @Test public void testIsPrioritized_withDifferentPriorities_withMultipleUidChangeIdDisabled() { doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), eq(getAppId(1))); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getAppId(1))); doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), eq(getAppId(2))); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getAppId(2))); assertTrue(isPrioritized(List.of( createResolveInfo(PACKAGE1, getAppId(1), 10), @@ -593,7 +593,7 @@ public class BroadcastRecordTest { @Test public void testSetDeliveryState_DeferUntilActive_changeIdDisabled() { doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), eq(getAppId(1))); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getAppId(1))); final BroadcastRecord r = createBroadcastRecord( new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED), List.of( createResolveInfo(PACKAGE1, getAppId(1), 10), @@ -961,7 +961,7 @@ public class BroadcastRecordTest { createResolveInfo(PACKAGE3, getAppId(3))))); doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), eq(getAppId(1))); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getAppId(1))); assertArrayEquals(new boolean[] {false, true, true}, calculateChangeState( List.of(createResolveInfo(PACKAGE1, getAppId(1)), createResolveInfo(PACKAGE2, getAppId(2)), @@ -973,7 +973,7 @@ public class BroadcastRecordTest { createResolveInfo(PACKAGE3, getAppId(3))))); doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), eq(getAppId(2))); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getAppId(2))); assertArrayEquals(new boolean[] {false, false, true}, calculateChangeState( List.of(createResolveInfo(PACKAGE1, getAppId(1)), createResolveInfo(PACKAGE2, getAppId(2)), @@ -988,7 +988,7 @@ public class BroadcastRecordTest { createResolveInfo(PACKAGE3, getAppId(3))))); doReturn(false).when(mPlatformCompat).isChangeEnabledByUidInternalNoLogging( - eq(BroadcastRecord.CHANGE_LIMIT_PRIORITY_SCOPE), eq(getAppId(3))); + eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), eq(getAppId(3))); assertArrayEquals(new boolean[] {false, false, false}, calculateChangeState( List.of(createResolveInfo(PACKAGE1, getAppId(1)), createResolveInfo(PACKAGE2, getAppId(2)), @@ -1005,7 +1005,7 @@ public class BroadcastRecordTest { private boolean[] calculateChangeState(List<Object> receivers) { return BroadcastRecord.calculateChangeStateForReceivers(receivers, - CHANGE_LIMIT_PRIORITY_SCOPE, mPlatformCompat); + LIMIT_PRIORITY_SCOPE, mPlatformCompat); } private static void cleanupDisabledPackageReceivers(BroadcastRecord record, diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java index 4a1315583ad4..f82a86092064 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -109,6 +109,7 @@ import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.util.ArrayMap; import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.util.SparseIntArray; import com.android.server.LocalServices; @@ -175,6 +176,7 @@ public class MockingOomAdjusterTests { private ActiveUids mActiveUids; private PackageManagerInternal mPackageManagerInternal; private ActivityManagerService mService; + private TestCachedAppOptimizer mTestCachedAppOptimizer; private OomAdjusterInjector mInjector = new OomAdjusterInjector(); private int mUiTierSize; @@ -242,9 +244,11 @@ public class MockingOomAdjusterTests { doNothing().when(pr).enqueueProcessChangeItemLocked(anyInt(), anyInt(), anyInt(), anyBoolean()); mActiveUids = new ActiveUids(mService, false); + mTestCachedAppOptimizer = new TestCachedAppOptimizer(mService); mProcessStateController = new ProcessStateController.Builder(mService, mService.mProcessList, mActiveUids) .useModernOomAdjuster(mService.mConstants.ENABLE_NEW_OOMADJ) + .setCachedAppOptimizer(mTestCachedAppOptimizer) .setOomAdjusterInjector(mInjector) .build(); mService.mProcessStateController = mProcessStateController; @@ -3110,13 +3114,13 @@ public class MockingOomAdjusterTests { mProcessStateController.setUidTempAllowlistStateLSP(MOCKAPP_UID, true); assertEquals(true, app.getUidRecord().isSetAllowListed()); - assertEquals(true, app.mOptRecord.shouldNotFreeze()); - assertEquals(true, app2.mOptRecord.shouldNotFreeze()); + assertFreezeState(app, false); + assertFreezeState(app2, false); mProcessStateController.setUidTempAllowlistStateLSP(MOCKAPP_UID, false); assertEquals(false, app.getUidRecord().isSetAllowListed()); - assertEquals(false, app.mOptRecord.shouldNotFreeze()); - assertEquals(false, app2.mOptRecord.shouldNotFreeze()); + assertFreezeState(app, true); + assertFreezeState(app2, true); } @SuppressWarnings("GuardedBy") @@ -3138,25 +3142,25 @@ public class MockingOomAdjusterTests { assertEquals(true, app.getUidRecord().isSetAllowListed()); assertEquals(true, app2.getUidRecord().isSetAllowListed()); - assertEquals(true, app.mOptRecord.shouldNotFreeze()); - assertEquals(true, app2.mOptRecord.shouldNotFreeze()); - assertEquals(true, app3.mOptRecord.shouldNotFreeze()); + assertFreezeState(app, false); + assertFreezeState(app2, false); + assertFreezeState(app3, false); // Remove app1 from allowlist. mProcessStateController.setUidTempAllowlistStateLSP(MOCKAPP_UID, false); assertEquals(false, app.getUidRecord().isSetAllowListed()); assertEquals(true, app2.getUidRecord().isSetAllowListed()); - assertEquals(false, app.mOptRecord.shouldNotFreeze()); - assertEquals(true, app2.mOptRecord.shouldNotFreeze()); - assertEquals(true, app3.mOptRecord.shouldNotFreeze()); + assertFreezeState(app, true); + assertFreezeState(app2, false); + assertFreezeState(app3, false); // Now remove app2 from allowlist. mProcessStateController.setUidTempAllowlistStateLSP(MOCKAPP2_UID, false); assertEquals(false, app.getUidRecord().isSetAllowListed()); assertEquals(false, app2.getUidRecord().isSetAllowListed()); - assertEquals(false, app.mOptRecord.shouldNotFreeze()); - assertEquals(false, app2.mOptRecord.shouldNotFreeze()); - assertEquals(false, app3.mOptRecord.shouldNotFreeze()); + assertFreezeState(app, true); + assertFreezeState(app2, true); + assertFreezeState(app3, true); } @SuppressWarnings("GuardedBy") @@ -3370,6 +3374,14 @@ public class MockingOomAdjusterTests { assertEquals(expectedCached, state.isCached()); } + @SuppressWarnings("GuardedBy") + private void assertFreezeState(ProcessRecord app, boolean expectedFreezeState) { + boolean actualFreezeState = mTestCachedAppOptimizer.mLastSetFreezeState.get(app.getPid(), + false); + assertEquals("Unexcepted freeze state for " + app.processName, expectedFreezeState, + actualFreezeState); + } + private class ProcessRecordBuilder { @SuppressWarnings("UnusedVariable") int mPid; @@ -3513,6 +3525,39 @@ public class MockingOomAdjusterTests { return app; } } + private static final class TestProcessDependencies + implements CachedAppOptimizer.ProcessDependencies { + @Override + public long[] getRss(int pid) { + return new long[]{/*totalRSS*/ 0, /*fileRSS*/ 0, /*anonRSS*/ 0, /*swap*/ 0}; + } + + @Override + public void performCompaction(CachedAppOptimizer.CompactProfile action, int pid) {} + } + + private static class TestCachedAppOptimizer extends CachedAppOptimizer { + private SparseBooleanArray mLastSetFreezeState = new SparseBooleanArray(); + + TestCachedAppOptimizer(ActivityManagerService ams) { + super(ams, null, new TestProcessDependencies()); + } + + @Override + public boolean useFreezer() { + return true; + } + + @Override + public void freezeAppAsyncLSP(ProcessRecord app) { + mLastSetFreezeState.put(app.getPid(), true); + } + + @Override + public void unfreezeAppLSP(ProcessRecord app, @UnfreezeReason int reason) { + mLastSetFreezeState.put(app.getPid(), false); + } + } static class OomAdjusterInjector extends OomAdjuster.Injector { // Jump ahead in time by this offset amount. @@ -3524,7 +3569,6 @@ public class MockingOomAdjusterTests { mLastSetOomAdj.clear(); } - void jumpUptimeAheadTo(long uptimeMillis) { final long jumpMs = uptimeMillis - getUptimeMillis(); if (jumpMs <= 0) return; diff --git a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp index 1f88c29e2abc..8eae9c7d71fa 100644 --- a/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp +++ b/services/tests/mockingservicestests/src/com/android/server/crashrecovery/Android.bp @@ -37,7 +37,7 @@ android_test { "truth", "flag-junit", ] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), { - "true": ["service-crashrecovery.impl"], + "true": ["service-crashrecovery-pre-jarjar"], default: [], }), diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp b/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp index 2f23e02f5737..5a802d9de2ff 100644 --- a/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp +++ b/services/tests/mockingservicestests/src/com/android/server/rollback/Android.bp @@ -35,7 +35,7 @@ android_test { "truth", "flag-junit", ] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), { - "true": ["service-crashrecovery.impl"], + "true": ["service-crashrecovery-pre-jarjar"], default: [], }), diff --git a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java index 58489f398775..0881b4cf9bcf 100644 --- a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java +++ b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java @@ -18,6 +18,7 @@ package com.android.server.power.hint; import static com.android.server.power.hint.HintManagerService.CLEAN_UP_UID_DELAY_MILLIS; +import static com.android.server.power.hint.HintManagerService.DEFAULT_HEADROOM_PID; import static com.google.common.truth.Truth.assertThat; @@ -51,11 +52,15 @@ import android.content.pm.PackageManager; import android.hardware.common.fmq.MQDescriptor; import android.hardware.power.ChannelConfig; import android.hardware.power.ChannelMessage; +import android.hardware.power.CpuHeadroomParams; +import android.hardware.power.GpuHeadroomParams; import android.hardware.power.IPower; import android.hardware.power.SessionConfig; import android.hardware.power.SessionTag; import android.hardware.power.WorkDuration; import android.os.Binder; +import android.os.CpuHeadroomParamsInternal; +import android.os.GpuHeadroomParamsInternal; import android.os.IBinder; import android.os.IHintSession; import android.os.PerformanceHintManager; @@ -128,11 +133,11 @@ public class HintManagerServiceTest { private static final long[] TIMESTAMPS_ZERO = new long[] {}; private static final long[] TIMESTAMPS_TWO = new long[] {1L, 2L}; private static final WorkDuration[] WORK_DURATIONS_FIVE = new WorkDuration[] { - makeWorkDuration(1L, 11L, 1L, 8L, 4L), - makeWorkDuration(2L, 13L, 2L, 8L, 6L), - makeWorkDuration(3L, 333333333L, 3L, 8L, 333333333L), - makeWorkDuration(2L, 13L, 2L, 0L, 6L), - makeWorkDuration(2L, 13L, 2L, 8L, 0L), + makeWorkDuration(1L, 11L, 1L, 8L, 4L), + makeWorkDuration(2L, 13L, 2L, 8L, 6L), + makeWorkDuration(3L, 333333333L, 3L, 8L, 333333333L), + makeWorkDuration(2L, 13L, 2L, 0L, 6L), + makeWorkDuration(2L, 13L, 2L, 8L, 0L), }; private static final String TEST_APP_NAME = "com.android.test.app"; @@ -187,17 +192,17 @@ public class HintManagerServiceTest { when(mNativeWrapperMock.halCreateHintSessionWithConfig(eq(TGID), eq(UID), eq(SESSION_TIDS_A), eq(DEFAULT_TARGET_DURATION), anyInt(), any(SessionConfig.class))).thenAnswer(fakeCreateWithConfig(SESSION_PTRS[0], - SESSION_IDS[0])); + SESSION_IDS[0])); when(mNativeWrapperMock.halCreateHintSessionWithConfig(eq(TGID), eq(UID), eq(SESSION_TIDS_B), eq(DOUBLED_TARGET_DURATION), anyInt(), any(SessionConfig.class))).thenAnswer(fakeCreateWithConfig(SESSION_PTRS[1], - SESSION_IDS[1])); + SESSION_IDS[1])); when(mNativeWrapperMock.halCreateHintSessionWithConfig(eq(TGID), eq(UID), eq(SESSION_TIDS_C), eq(0L), anyInt(), any(SessionConfig.class))).thenAnswer(fakeCreateWithConfig(SESSION_PTRS[2], - SESSION_IDS[2])); + SESSION_IDS[2])); - when(mIPowerMock.getInterfaceVersion()).thenReturn(5); + when(mIPowerMock.getInterfaceVersion()).thenReturn(6); when(mIPowerMock.getSessionChannel(anyInt(), anyInt())).thenReturn(mConfig); LocalServices.removeServiceForTest(ActivityManagerInternal.class); LocalServices.addService(ActivityManagerInternal.class, mAmInternalMock); @@ -217,8 +222,8 @@ public class HintManagerServiceTest { when(mNativeWrapperMock.halCreateHintSession(eq(TGID), eq(UID), eq(SESSION_TIDS_C), eq(0L))).thenReturn(SESSION_PTRS[2]); when(mNativeWrapperMock.halCreateHintSessionWithConfig(anyInt(), anyInt(), - any(int[].class), anyLong(), anyInt(), - any(SessionConfig.class))).thenThrow(new UnsupportedOperationException()); + any(int[].class), anyLong(), anyInt(), + any(SessionConfig.class))).thenThrow(new UnsupportedOperationException()); } static class NativeWrapperFake extends NativeWrapper { @@ -337,7 +342,7 @@ public class HintManagerServiceTest { SESSION_TIDS_C, 0L, SessionTag.OTHER, new SessionConfig()); assertNotNull(c); verify(mNativeWrapperMock, times(3)).halCreateHintSession(anyInt(), anyInt(), - any(int[].class), anyLong()); + any(int[].class), anyLong()); } @Test @@ -487,7 +492,7 @@ public class HintManagerServiceTest { AppHintSession a = (AppHintSession) service.getBinderServiceInstance() .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION, - SessionTag.OTHER, new SessionConfig()); + SessionTag.OTHER, new SessionConfig()); a.sendHint(PerformanceHintManager.Session.CPU_LOAD_RESET); verify(mNativeWrapperMock, times(1)).halSendHint(anyLong(), @@ -514,7 +519,7 @@ public class HintManagerServiceTest { AppHintSession a = (AppHintSession) service.getBinderServiceInstance() .createHintSessionWithConfig(token, SESSION_TIDS_A, DEFAULT_TARGET_DURATION, - SessionTag.OTHER, new SessionConfig()); + SessionTag.OTHER, new SessionConfig()); service.mUidObserver.onUidStateChanged( a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND, 0, 0); @@ -1096,4 +1101,157 @@ public class HintManagerServiceTest { verify(mIPowerMock, times(1)).getSessionChannel(eq(TGID), eq(UID)); assertTrue(service.hasChannel(TGID, UID)); } + + @Test + public void testHeadroomPowerHalNotSupported() throws Exception { + when(mIPowerMock.getInterfaceVersion()).thenReturn(5); + HintManagerService service = createService(); + assertThrows(UnsupportedOperationException.class, () -> { + service.getBinderServiceInstance().getCpuHeadroom(null); + }); + assertThrows(UnsupportedOperationException.class, () -> { + service.getBinderServiceInstance().getGpuHeadroom(null); + }); + assertThrows(UnsupportedOperationException.class, () -> { + service.getBinderServiceInstance().getCpuHeadroomMinIntervalMillis(); + }); + assertThrows(UnsupportedOperationException.class, () -> { + service.getBinderServiceInstance().getGpuHeadroomMinIntervalMillis(); + }); + } + + @Test + public void testCpuHeadroomCache() throws Exception { + when(mIPowerMock.getCpuHeadroomMinIntervalMillis()).thenReturn(2000L); + CpuHeadroomParamsInternal params1 = new CpuHeadroomParamsInternal(); + CpuHeadroomParams halParams1 = new CpuHeadroomParams(); + halParams1.calculationType = CpuHeadroomParams.CalculationType.MIN; + halParams1.selectionType = CpuHeadroomParams.SelectionType.ALL; + halParams1.pid = Process.myPid(); + + CpuHeadroomParamsInternal params2 = new CpuHeadroomParamsInternal(); + params2.usesDeviceHeadroom = true; + params2.calculationType = CpuHeadroomParams.CalculationType.AVERAGE; + params2.selectionType = CpuHeadroomParams.SelectionType.PER_CORE; + CpuHeadroomParams halParams2 = new CpuHeadroomParams(); + halParams2.calculationType = CpuHeadroomParams.CalculationType.AVERAGE; + halParams2.selectionType = CpuHeadroomParams.SelectionType.PER_CORE; + halParams2.pid = DEFAULT_HEADROOM_PID; + + float[] headroom1 = new float[] {0.1f}; + when(mIPowerMock.getCpuHeadroom(eq(halParams1))).thenReturn(headroom1); + float[] headroom2 = new float[] {0.1f, 0.5f}; + when(mIPowerMock.getCpuHeadroom(eq(halParams2))).thenReturn(headroom2); + + HintManagerService service = createService(); + clearInvocations(mIPowerMock); + + service.getBinderServiceInstance().getCpuHeadroomMinIntervalMillis(); + verify(mIPowerMock, times(0)).getCpuHeadroomMinIntervalMillis(); + service.getBinderServiceInstance().getCpuHeadroom(params1); + verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams1)); + service.getBinderServiceInstance().getCpuHeadroom(params2); + verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams2)); + + // verify cache is working + clearInvocations(mIPowerMock); + assertArrayEquals(headroom1, service.getBinderServiceInstance().getCpuHeadroom(params1), + 0.01f); + assertArrayEquals(headroom2, service.getBinderServiceInstance().getCpuHeadroom(params2), + 0.01f); + verify(mIPowerMock, times(0)).getCpuHeadroom(any()); + + // after 1 more second it should be served with cache still + Thread.sleep(1000); + clearInvocations(mIPowerMock); + assertArrayEquals(headroom1, service.getBinderServiceInstance().getCpuHeadroom(params1), + 0.01f); + assertArrayEquals(headroom2, service.getBinderServiceInstance().getCpuHeadroom(params2), + 0.01f); + verify(mIPowerMock, times(0)).getCpuHeadroom(any()); + + // after 1.5 more second it should be served with cache still as timer reset + Thread.sleep(1500); + clearInvocations(mIPowerMock); + assertArrayEquals(headroom1, service.getBinderServiceInstance().getCpuHeadroom(params1), + 0.01f); + assertArrayEquals(headroom2, service.getBinderServiceInstance().getCpuHeadroom(params2), + 0.01f); + verify(mIPowerMock, times(0)).getCpuHeadroom(any()); + + // after 2+ seconds it should be served from HAL as it exceeds 2000 millis interval + Thread.sleep(2100); + clearInvocations(mIPowerMock); + assertArrayEquals(headroom1, service.getBinderServiceInstance().getCpuHeadroom(params1), + 0.01f); + assertArrayEquals(headroom2, service.getBinderServiceInstance().getCpuHeadroom(params2), + 0.01f); + verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams1)); + verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams2)); + } + + @Test + public void testGpuHeadroomCache() throws Exception { + when(mIPowerMock.getGpuHeadroomMinIntervalMillis()).thenReturn(2000L); + GpuHeadroomParamsInternal params1 = new GpuHeadroomParamsInternal(); + GpuHeadroomParams halParams1 = new GpuHeadroomParams(); + halParams1.calculationType = GpuHeadroomParams.CalculationType.MIN; + + GpuHeadroomParamsInternal params2 = new GpuHeadroomParamsInternal(); + GpuHeadroomParams halParams2 = new GpuHeadroomParams(); + params2.calculationType = + halParams2.calculationType = GpuHeadroomParams.CalculationType.AVERAGE; + + float headroom1 = 0.1f; + when(mIPowerMock.getGpuHeadroom(eq(halParams1))).thenReturn(headroom1); + float headroom2 = 0.2f; + when(mIPowerMock.getGpuHeadroom(eq(halParams2))).thenReturn(headroom2); + HintManagerService service = createService(); + clearInvocations(mIPowerMock); + + service.getBinderServiceInstance().getGpuHeadroomMinIntervalMillis(); + verify(mIPowerMock, times(0)).getGpuHeadroomMinIntervalMillis(); + assertEquals(headroom1, service.getBinderServiceInstance().getGpuHeadroom(params1), + 0.01f); + assertEquals(headroom2, service.getBinderServiceInstance().getGpuHeadroom(params2), + 0.01f); + verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams1)); + verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams2)); + + // verify cache is working + clearInvocations(mIPowerMock); + assertEquals(headroom1, service.getBinderServiceInstance().getGpuHeadroom(params1), + 0.01f); + assertEquals(headroom2, service.getBinderServiceInstance().getGpuHeadroom(params2), + 0.01f); + verify(mIPowerMock, times(0)).getGpuHeadroom(any()); + + // after 1 more second it should be served with cache still + Thread.sleep(1000); + clearInvocations(mIPowerMock); + assertEquals(headroom1, service.getBinderServiceInstance().getGpuHeadroom(params1), + 0.01f); + assertEquals(headroom2, service.getBinderServiceInstance().getGpuHeadroom(params2), + 0.01f); + verify(mIPowerMock, times(0)).getGpuHeadroom(any()); + + // after 1.5 more second it should be served with cache still as timer reset + Thread.sleep(1500); + clearInvocations(mIPowerMock); + assertEquals(headroom1, service.getBinderServiceInstance().getGpuHeadroom(params1), + 0.01f); + assertEquals(headroom2, service.getBinderServiceInstance().getGpuHeadroom(params2), + 0.01f); + verify(mIPowerMock, times(0)).getGpuHeadroom(any()); + + // after 2+ seconds it should be served from HAL as it exceeds 2000 millis interval + Thread.sleep(2100); + clearInvocations(mIPowerMock); + assertEquals(headroom1, service.getBinderServiceInstance().getGpuHeadroom(params1), + 0.01f); + assertEquals(headroom2, service.getBinderServiceInstance().getGpuHeadroom(params2), + 0.01f); + verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams1)); + verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams2)); + } } diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index f1656678d3bd..0c058df35195 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -97,7 +97,7 @@ android_test { "com_android_server_accessibility_flags_lib", "locksettings_flags_lib", ] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), { - "true": ["service-crashrecovery.impl"], + "true": ["service-crashrecovery-pre-jarjar"], default: [], }), diff --git a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java index cf628add705a..b81bf3c6e712 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java @@ -332,6 +332,28 @@ public class PreAuthInfoTest { assertThat(preAuthInfo.callingUserId).isEqualTo(USER_ID); } + @Test + @RequiresFlagsEnabled(Flags.FLAG_EFFECTIVE_USER_BP) + public void testCredentialOwnerIdAsUserId_forMandatoryBiometrics() throws Exception { + when(mUserManager.getCredentialOwnerProfile(USER_ID)).thenReturn(OWNER_ID); + when(mSettingObserver.getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser( + OWNER_ID)).thenReturn(true); + when(mSettingObserver.getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser( + USER_ID)).thenReturn(false); + when(mTrustManager.isInSignificantPlace()).thenReturn(false); + + final BiometricSensor sensor = getFaceSensor(); + final PromptInfo promptInfo = new PromptInfo(); + promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK); + promptInfo.setNegativeButtonText(TEST_PACKAGE_NAME); + final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, + mSettingObserver, List.of(sensor), USER_ID , promptInfo, TEST_PACKAGE_NAME, + false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, + mUserManager); + + assertThat(preAuthInfo.getIsMandatoryBiometricsAuthentication()).isTrue(); + } + private BiometricSensor getFingerprintSensor() { BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FINGERPRINT, TYPE_FINGERPRINT, BiometricManager.Authenticators.BIOMETRIC_STRONG, diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java index 93aa10b9112f..fd221185bacf 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java @@ -68,7 +68,6 @@ import androidx.test.InstrumentationRegistry; import com.android.internal.R; import com.android.server.compat.PlatformCompat; -import com.android.server.integrity.model.IntegrityCheckResult; import com.android.server.testutils.TestUtils; import org.junit.After; diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/ByteTrackedOutputStreamTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/ByteTrackedOutputStreamTest.java deleted file mode 100644 index 57274bf13499..000000000000 --- a/services/tests/servicestests/src/com/android/server/integrity/model/ByteTrackedOutputStreamTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.model; - -import static com.google.common.truth.Truth.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.io.ByteArrayOutputStream; - -@RunWith(JUnit4.class) -public class ByteTrackedOutputStreamTest { - - @Test - public void testConstructorStartsWithZeroBytesWritten() { - ByteTrackedOutputStream byteTrackedOutputStream = - new ByteTrackedOutputStream(new ByteArrayOutputStream()); - - assertThat(byteTrackedOutputStream.getWrittenBytesCount()).isEqualTo(0); - } - - @Test - public void testSuccessfulWriteAndValidateWrittenBytesCount_directFromByteArray() - throws Exception { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - ByteTrackedOutputStream byteTrackedOutputStream = new ByteTrackedOutputStream(outputStream); - - byte[] outputContent = "This is going to be outputed for tests.".getBytes(); - byteTrackedOutputStream.write(outputContent); - - assertThat(byteTrackedOutputStream.getWrittenBytesCount()).isEqualTo(outputContent.length); - assertThat(outputStream.toByteArray().length).isEqualTo(outputContent.length); - } - - @Test - public void testSuccessfulWriteAndValidateWrittenBytesCount_fromBitStream() throws Exception { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - ByteTrackedOutputStream byteTrackedOutputStream = new ByteTrackedOutputStream(outputStream); - - BitOutputStream bitOutputStream = new BitOutputStream(byteTrackedOutputStream); - bitOutputStream.setNext(/* numOfBits= */5, /* value= */1); - bitOutputStream.flush(); - - // Even though we wrote 5 bits, this will complete to 1 byte. - assertThat(byteTrackedOutputStream.getWrittenBytesCount()).isEqualTo(1); - - // Add a bit less than 2 bytes (10 bits). - bitOutputStream.setNext(/* numOfBits= */10, /* value= */1); - bitOutputStream.flush(); - assertThat(byteTrackedOutputStream.getWrittenBytesCount()).isEqualTo(3); - - assertThat(outputStream.toByteArray().length).isEqualTo(3); - } -} diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/IntegrityCheckResultTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/IntegrityCheckResultTest.java deleted file mode 100644 index d31ed689a7da..000000000000 --- a/services/tests/servicestests/src/com/android/server/integrity/model/IntegrityCheckResultTest.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.integrity.model; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.integrity.AtomicFormula; -import android.content.integrity.CompoundFormula; -import android.content.integrity.Rule; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.util.Arrays; -import java.util.Collections; - -@RunWith(JUnit4.class) -public class IntegrityCheckResultTest { - - @Test - public void createAllowResult() { - IntegrityCheckResult allowResult = IntegrityCheckResult.allow(); - - assertThat(allowResult.getEffect()).isEqualTo(IntegrityCheckResult.Effect.ALLOW); - assertThat(allowResult.getMatchedRules()).isEmpty(); - } - - @Test - public void createAllowResultWithRule() { - String packageName = "com.test.deny"; - Rule forceAllowRule = - new Rule( - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, - packageName), - Rule.FORCE_ALLOW); - - IntegrityCheckResult allowResult = - IntegrityCheckResult.allow(Collections.singletonList(forceAllowRule)); - - assertThat(allowResult.getEffect()).isEqualTo(IntegrityCheckResult.Effect.ALLOW); - assertThat(allowResult.getMatchedRules()).containsExactly(forceAllowRule); - } - - @Test - public void createDenyResultWithRule() { - String packageName = "com.test.deny"; - Rule failedRule = - new Rule( - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, - packageName), - Rule.DENY); - - IntegrityCheckResult denyResult = - IntegrityCheckResult.deny(Collections.singletonList(failedRule)); - - assertThat(denyResult.getEffect()).isEqualTo(IntegrityCheckResult.Effect.DENY); - assertThat(denyResult.getMatchedRules()).containsExactly(failedRule); - } - - @Test - public void isDenyCausedByAppCertificate() { - String packageName = "com.test.deny"; - String appCert = "app-cert"; - Rule failedRule = - new Rule( - new CompoundFormula( - CompoundFormula.AND, - Arrays.asList( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, packageName), - new AtomicFormula.StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE, appCert))), - Rule.DENY); - Rule otherFailedRule = - new Rule( - new AtomicFormula.LongAtomicFormula(AtomicFormula.VERSION_CODE, - AtomicFormula.EQ, 12), - Rule.DENY); - - IntegrityCheckResult denyResult = - IntegrityCheckResult.deny(Arrays.asList(failedRule, otherFailedRule)); - - assertThat(denyResult.isCausedByAppCertRule()).isTrue(); - assertThat(denyResult.isCausedByInstallerRule()).isFalse(); - } - - @Test - public void isDenyCausedByInstaller() { - String packageName = "com.test.deny"; - String appCert = "app-cert"; - Rule failedRule = - new Rule( - new CompoundFormula( - CompoundFormula.AND, - Arrays.asList( - new AtomicFormula.StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, packageName), - new AtomicFormula.StringAtomicFormula( - AtomicFormula.INSTALLER_CERTIFICATE, appCert))), - Rule.DENY); - Rule otherFailedRule = - new Rule( - new AtomicFormula.LongAtomicFormula(AtomicFormula.VERSION_CODE, - AtomicFormula.EQ, 12), - Rule.DENY); - - IntegrityCheckResult denyResult = - IntegrityCheckResult.deny(Arrays.asList(failedRule, otherFailedRule)); - - assertThat(denyResult.isCausedByAppCertRule()).isFalse(); - assertThat(denyResult.isCausedByInstallerRule()).isTrue(); - } -} diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java index cc0286508cdc..632c3e6d8fb0 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java @@ -2298,6 +2298,7 @@ public class GroupHelperTest extends UiServiceTestCase { final String pkg = "package"; final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg, AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier()); + final int numNotifications = 2 * AUTOGROUP_AT_COUNT; int numNotificationChannel1 = 0; final NotificationChannel channel1 = new NotificationChannel("TEST_CHANNEL_ID1", "TEST_CHANNEL_ID1", IMPORTANCE_DEFAULT); @@ -2307,7 +2308,7 @@ public class GroupHelperTest extends UiServiceTestCase { final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>(); // Post notifications with different channels that autogroup within the same section NotificationRecord r; - for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) { + for (int i = 0; i < numNotifications; i++) { if (i % 2 == 0) { r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "testGrp " + i, false, channel1); @@ -2324,12 +2325,12 @@ public class GroupHelperTest extends UiServiceTestCase { "TEST_CHANNEL_ID1"); verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), eq(expectedGroupKey_alerting), anyInt(), eq(expectedSummaryAttr)); - verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), + verify(mCallback, times(numNotifications)).addAutoGroup(anyString(), eq(expectedGroupKey_alerting), eq(true)); verify(mCallback, never()).removeAutoGroup(anyString()); verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString()); - verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(), - any()); + verify(mCallback, times(numNotifications - AUTOGROUP_AT_COUNT)).updateAutogroupSummary( + anyInt(), anyString(), anyString(), any()); Mockito.reset(mCallback); // Update channel1's importance @@ -2375,7 +2376,7 @@ public class GroupHelperTest extends UiServiceTestCase { final List<NotificationRecord> notificationList = new ArrayList<>(); final String pkg = "package"; final int summaryId = 0; - final int numChildNotif = 4; + final int numChildNotif = 2 * AUTOGROUP_AT_COUNT; // Create an app-provided group: summary + child notifications final NotificationChannel channel1 = new NotificationChannel("TEST_CHANNEL_ID1", @@ -2435,8 +2436,8 @@ public class GroupHelperTest extends UiServiceTestCase { eq(expectedGroupKey_social), eq(true)); verify(mCallback, never()).removeAutoGroup(anyString()); verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString()); - verify(mCallback, times(numChildNotif / 2)).updateAutogroupSummary(anyInt(), anyString(), - anyString(), any()); + verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(), + any()); verify(mCallback, times(numChildNotif)).removeAppProvidedSummaryOnClassification( anyString(), eq(originalAppGroupKey)); } @@ -2513,9 +2514,10 @@ public class GroupHelperTest extends UiServiceTestCase { final List<NotificationRecord> notificationList = new ArrayList<>(); final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>(); final String pkg = "package"; + final int numChildNotifications = AUTOGROUP_AT_COUNT; // Post singleton groups, above forced group limit - for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) { + for (int i = 0; i < numChildNotifications; i++) { NotificationRecord summary = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "testGrp " + i, true); notificationList.add(summary); @@ -2545,13 +2547,13 @@ public class GroupHelperTest extends UiServiceTestCase { // Check that notifications are forced grouped and app-provided summaries are canceled verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), eq(expectedGroupKey_social), anyInt(), eq(expectedSummaryAttr_social)); - verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).addAutoGroup(anyString(), + verify(mCallback, times(numChildNotifications)).addAutoGroup(anyString(), eq(expectedGroupKey_social), eq(true)); verify(mCallback, never()).removeAutoGroup(anyString()); verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString()); - verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(), + verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(), any()); - verify(mCallback, times(2)).removeAppProvidedSummaryOnClassification( + verify(mCallback, times(numChildNotifications)).removeAppProvidedSummaryOnClassification( anyString(), anyString()); // Adjust group key and cancel summaries @@ -2593,14 +2595,16 @@ public class GroupHelperTest extends UiServiceTestCase { AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier()); String expectedTriggeringKey = null; // Post singleton groups, above forced group limit - for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) { + for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) { NotificationRecord summary = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "testGrp " + i, true); notificationList.add(summary); NotificationRecord child = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp " + i, false); notificationList.add(child); - expectedTriggeringKey = child.getKey(); + if (i == AUTOGROUP_SINGLETONS_AT_COUNT - 1) { + expectedTriggeringKey = child.getKey(); + } summaryByGroup.put(summary.getGroupKey(), summary); mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup); summary.isCanceled = true; // simulate removing the app summary @@ -2611,14 +2615,8 @@ public class GroupHelperTest extends UiServiceTestCase { verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), eq(expectedTriggeringKey), eq(expectedGroupKey_alerting), anyInt(), eq(getNotificationAttributes(BASE_FLAGS))); - verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).addAutoGroup(anyString(), - eq(expectedGroupKey_alerting), eq(true)); verify(mCallback, never()).removeAutoGroup(anyString()); verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString()); - verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(), - any()); - verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).removeAppProvidedSummary( - anyString()); assertThat(mGroupHelper.findCanceledSummary(pkg, String.valueOf(0), 0, UserHandle.SYSTEM.getIdentifier())).isNotNull(); assertThat(mGroupHelper.findCanceledSummary(pkg, String.valueOf(1), 1, @@ -2645,12 +2643,12 @@ public class GroupHelperTest extends UiServiceTestCase { // Check that all notifications are moved to the social section group verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), eq(expectedGroupKey_social), anyInt(), eq(expectedSummaryAttr_social)); - verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).addAutoGroup(anyString(), + verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(expectedGroupKey_social), eq(true)); // Check that the alerting section group is removed verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg), eq(expectedGroupKey_alerting)); - verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).updateAutogroupSummary(anyInt(), + verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).updateAutogroupSummary(anyInt(), anyString(), anyString(), any()); } @@ -2666,7 +2664,7 @@ public class GroupHelperTest extends UiServiceTestCase { final String pkg = "package"; final int summaryId = 0; - final int numChildren = 3; + final int numChildren = AUTOGROUP_AT_COUNT; // Post a regular/valid group: summary + notifications NotificationRecord summary = getNotificationRecord(pkg, summaryId, String.valueOf(summaryId), UserHandle.SYSTEM, "testGrp", true); @@ -2706,13 +2704,211 @@ public class GroupHelperTest extends UiServiceTestCase { eq(true)); verify(mCallback, never()).removeAutoGroup(anyString()); verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString()); - verify(mCallback, times(numChildren - 1)).updateAutogroupSummary(anyInt(), anyString(), - anyString(), any()); + verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(), + any()); verify(mCallback, times(numChildren)).removeAppProvidedSummaryOnClassification(anyString(), anyString()); } @Test + @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, + FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION, + FLAG_NOTIFICATION_CLASSIFICATION}) + public void testUnbundleNotification_originalSummaryMissing_autogroupInNewSection() { + // Check that unbundled notifications are moved to the original section and aggregated + // with existing autogrouped notifications + final List<NotificationRecord> notificationList = new ArrayList<>(); + final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>(); + final String pkg = "package"; + + final int summaryId = 0; + final int numChildren = AUTOGROUP_AT_COUNT - 1; + // Post a regular/valid group: summary + notifications (one less than autogroup limit) + NotificationRecord summary = getNotificationRecord(pkg, summaryId, + String.valueOf(summaryId), UserHandle.SYSTEM, "testGrp", true); + notificationList.add(summary); + summaryByGroup.put(summary.getGroupKey(), summary); + final String originalAppGroupKey = summary.getGroupKey(); + final NotificationChannel originalChannel = summary.getChannel(); + for (int i = 0; i < numChildren; i++) { + NotificationRecord child = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42), + UserHandle.SYSTEM, "testGrp", false); + notificationList.add(child); + mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup); + } + + // Classify/bundle all child notifications: original group & summary is removed + final NotificationChannel socialChannel = new NotificationChannel( + NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID, + IMPORTANCE_DEFAULT); + for (NotificationRecord record: notificationList) { + if (record.getOriginalGroupKey().contains("testGrp") + && record.getNotification().isGroupChild()) { + record.updateNotificationChannel(socialChannel); + mGroupHelper.onChannelUpdated(record); + } + } + + // Check that no autogroup summaries were created for the social section + verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(), + anyString(), anyInt(), any()); + verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean()); + verify(mCallback, never()).removeAutoGroup(anyString()); + verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString()); + verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(), + any()); + verify(mCallback, times(numChildren)).removeAppProvidedSummaryOnClassification( + anyString(), eq(originalAppGroupKey)); + + // Cancel summary + summary.isCanceled = true; + summaryByGroup.clear(); + notificationList.remove(summary); + + // Add 1 ungrouped notification in the original section + NotificationRecord ungroupedNotification = getNotificationRecord(pkg, 4242, + String.valueOf(4242), UserHandle.SYSTEM); + notificationList.add(ungroupedNotification); + mGroupHelper.onNotificationPosted(ungroupedNotification, false); + + // Unbundle the bundled notifications => notifications are moved back to the original group + // and an aggregate group is created because autogroup limit is reached + reset(mCallback); + for (NotificationRecord record: notificationList) { + if (record.getNotification().isGroupChild() + && record.getOriginalGroupKey().contains("testGrp") + && NotificationChannel.SYSTEM_RESERVED_IDS.contains( + record.getChannel().getId())) { + record.updateNotificationChannel(originalChannel); + mGroupHelper.onNotificationUnbundled(record, false); + } + } + + // Check that a new aggregate group is created + final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg, + AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier()); + verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), + eq(expectedGroupKey_alerting), anyInt(), any()); + verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), + eq(expectedGroupKey_alerting), eq(true)); + verify(mCallback, never()).removeAutoGroup(anyString()); + verify(mCallback, times(numChildren)).removeAutoGroupSummary(anyInt(), anyString(), + anyString()); + verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(), + any()); + } + + @Test + @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, + FLAG_NOTIFICATION_REGROUP_ON_CLASSIFICATION, + FLAG_NOTIFICATION_CLASSIFICATION}) + public void testUnbundleNotification_originalSummaryExists() { + // Check that unbundled notifications are moved to the original section and original group + // when the original summary is still present + final List<NotificationRecord> notificationList = new ArrayList<>(); + final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>(); + final String pkg = "package"; + + final int summaryId = 0; + final int numChildren = AUTOGROUP_AT_COUNT + 1; + // Post a regular/valid group: summary + notifications + NotificationRecord summary = getNotificationRecord(pkg, summaryId, + String.valueOf(summaryId), UserHandle.SYSTEM, "testGrp", true); + notificationList.add(summary); + summaryByGroup.put(summary.getGroupKey(), summary); + final String originalAppGroupKey = summary.getGroupKey(); + final NotificationChannel originalChannel = summary.getChannel(); + for (int i = 0; i < numChildren; i++) { + NotificationRecord child = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42), + UserHandle.SYSTEM, "testGrp", false); + notificationList.add(child); + mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup); + } + + // Classify/bundle child notifications: all except one, to keep the original group + final NotificationChannel socialChannel = new NotificationChannel( + NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID, + IMPORTANCE_DEFAULT); + final String expectedGroupKey_social = GroupHelper.getFullAggregateGroupKey(pkg, + AGGREGATE_GROUP_KEY + "SocialSection", UserHandle.SYSTEM.getIdentifier()); + final NotificationAttributes expectedSummaryAttr_social = new NotificationAttributes( + BASE_FLAGS, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, + NotificationChannel.SOCIAL_MEDIA_ID); + int numChildrenBundled = 0; + for (NotificationRecord record: notificationList) { + if (record.getOriginalGroupKey().contains("testGrp") + && record.getNotification().isGroupChild()) { + record.updateNotificationChannel(socialChannel); + mGroupHelper.onChannelUpdated(record); + numChildrenBundled++; + if (numChildrenBundled == AUTOGROUP_AT_COUNT) { + break; + } + } + } + + // Check that 1 autogroup summaries were created for the social section + verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), + eq(expectedGroupKey_social), anyInt(), eq(expectedSummaryAttr_social)); + verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), + eq(expectedGroupKey_social), eq(true)); + verify(mCallback, never()).removeAutoGroup(anyString()); + verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString()); + verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(), + any()); + verify(mCallback, times(AUTOGROUP_AT_COUNT)).removeAppProvidedSummaryOnClassification( + anyString(), eq(originalAppGroupKey)); + + // Adjust group key and cancel summaries + for (NotificationRecord record: notificationList) { + if (record.getNotification().isGroupSummary()) { + record.isCanceled = true; + } else if (record.getOriginalGroupKey().contains("testGrp") + && NotificationChannel.SYSTEM_RESERVED_IDS.contains( + record.getChannel().getId())) { + record.setOverrideGroupKey(expectedGroupKey_social); + } + } + + // Add 1 ungrouped notification in the original section + NotificationRecord ungroupedNotification = getNotificationRecord(pkg, 4242, + String.valueOf(4242), UserHandle.SYSTEM); + notificationList.add(ungroupedNotification); + mGroupHelper.onNotificationPosted(ungroupedNotification, false); + + // Unbundle the bundled notifications => social section summary is destroyed + // and notifications are moved back to the original group + reset(mCallback); + for (NotificationRecord record: notificationList) { + if (record.getNotification().isGroupChild() + && record.getOriginalGroupKey().contains("testGrp") + && NotificationChannel.SYSTEM_RESERVED_IDS.contains( + record.getChannel().getId())) { + record.updateNotificationChannel(originalChannel); + mGroupHelper.onNotificationUnbundled(record, true); + } + } + + // Check that the autogroup summary for the social section was removed + // and that no new autogroup summaries were created + verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(), + anyString(), anyInt(), any()); + verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean()); + verify(mCallback, never()).removeAutoGroup(anyString()); + verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg), + eq(expectedGroupKey_social)); + verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).updateAutogroupSummary(anyInt(), eq(pkg), + eq(expectedGroupKey_social), any()); + + for (NotificationRecord record: notificationList) { + if (record.getNotification().isGroupChild() + && record.getOriginalGroupKey().contains("testGrp")) { + assertThat(record.getSbn().getOverrideGroupKey()).isNull(); + } + } + } + + @Test @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING) public void testMoveAggregateGroups_updateChannel_groupsUngrouped() { final String pkg = "package"; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java index 6eb2f718a0e9..9eddcc94e650 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java @@ -720,6 +720,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase { } @Test + @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION) public void testDefaultAllowedKeyAdjustments_readWriteXml() throws Exception { mAssistants.loadDefaultsFromConfig(true); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index eae587bc0187..704c1b858b8d 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -210,6 +210,7 @@ import android.app.Person; import android.app.RemoteInput; import android.app.RemoteInputHistoryItem; import android.app.StatsManager; +import android.app.ZenBypassingApp; import android.app.admin.DevicePolicyManagerInternal; import android.app.backup.BackupRestoreEventLogger; import android.app.job.JobScheduler; @@ -360,6 +361,9 @@ import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import platform.test.runner.parameterized.ParameterizedAndroidJunit4; +import platform.test.runner.parameterized.Parameters; + import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; @@ -374,9 +378,6 @@ import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.function.Consumer; -import platform.test.runner.parameterized.ParameterizedAndroidJunit4; -import platform.test.runner.parameterized.Parameters; - @SmallTest @RunWith(ParameterizedAndroidJunit4.class) @RunWithLooper @@ -489,7 +490,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private final NotificationChannel mParentChannel = new NotificationChannel(PARENT_CHANNEL_ID, "parentName", IMPORTANCE_DEFAULT); private final NotificationChannel mConversationChannel = - new NotificationChannel(CONVERSATION_CHANNEL_ID, "conversationName", IMPORTANCE_DEFAULT); + new NotificationChannel( + CONVERSATION_CHANNEL_ID, "conversationName", IMPORTANCE_DEFAULT); private static final String PARENT_CHANNEL_ID = "parentChannelId"; private static final String CONVERSATION_CHANNEL_ID = "conversationChannelId"; @@ -4296,8 +4298,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { new NotificationChannel("foo", "foo", IMPORTANCE_HIGH)); Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo"); - mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testTvExtenderChannelOverride_onTv", 0, - generateNotificationRecord(null, tv).getNotification(), mUserId); + mBinderService.enqueueNotificationWithTag( + mPkg, + mPkg, + "testTvExtenderChannelOverride_onTv", + 0, + generateNotificationRecord(null, tv).getNotification(), + mUserId); verify(mPreferencesHelper, times(1)).getConversationNotificationChannel( anyString(), anyInt(), eq("foo"), eq(null), anyBoolean(), anyBoolean()); } @@ -4311,8 +4318,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mTestNotificationChannel); Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo"); - mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testTvExtenderChannelOverride_notOnTv", - 0, generateNotificationRecord(null, tv).getNotification(), mUserId); + mBinderService.enqueueNotificationWithTag( + mPkg, + mPkg, + "testTvExtenderChannelOverride_notOnTv", + 0, + generateNotificationRecord(null, tv).getNotification(), + mUserId); verify(mPreferencesHelper, times(1)).getConversationNotificationChannel( anyString(), anyInt(), eq(mTestNotificationChannel.getId()), eq(null), anyBoolean(), anyBoolean()); @@ -7745,9 +7757,21 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .setContentTitle("foo") .setSmallIcon(android.R.drawable.sym_def_app_icon) .setStyle(new Notification.MessagingStyle("").addMessage(message2)); - NotificationRecord recordB = new NotificationRecord(mContext, new StatusBarNotification(mPkg, - mPkg, 0, "tag", mUid, 0, nbB.build(), UserHandle.getUserHandleForUid(mUid), null, 0), - c); + NotificationRecord recordB = + new NotificationRecord( + mContext, + new StatusBarNotification( + mPkg, + mPkg, + 0, + "tag", + mUid, + 0, + nbB.build(), + UserHandle.getUserHandleForUid(mUid), + null, + 0), + c); // Update means we drop access to first reset(mUgmInternal); @@ -13174,6 +13198,37 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void getPackagesBypassingDnd_blocked() + throws RemoteException, PackageManager.NameNotFoundException { + + NotificationChannel channel1 = new NotificationChannel("id1", "name1", + NotificationManager.IMPORTANCE_MAX); + NotificationChannel channel2 = new NotificationChannel("id3", "name3", + NotificationManager.IMPORTANCE_MAX); + NotificationChannel channel3 = new NotificationChannel("id4", "name3", + NotificationManager.IMPORTANCE_MAX); + channel1.setBypassDnd(true); + channel2.setBypassDnd(true); + channel3.setBypassDnd(false); + // has DND access, so can set bypassDnd attribute + mService.mPreferencesHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, + /*has DND access*/ true, UID_N_MR1, false); + mService.mPreferencesHelper.createNotificationChannel(PKG_P, UID_P, channel2, true, true, + UID_P, false); + mService.mPreferencesHelper.createNotificationChannel(PKG_P, UID_P, channel3, true, true, + UID_P, false); + + when(mPackageManager.getPackageUid(eq(PKG_P), anyLong(), anyInt())).thenReturn(UID_P); + when(mPackageManager.getPackageUid(eq(PKG_N_MR1), anyLong(), anyInt())) + .thenReturn(UID_N_MR1); + when(mPermissionHelper.hasPermission(UID_N_MR1)).thenReturn(false); + when(mPermissionHelper.hasPermission(UID_P)).thenReturn(true); + + assertThat(mBinderService.getPackagesBypassingDnd(UserHandle.getUserId(UID_P)).getList()) + .containsExactly(new ZenBypassingApp(PKG_P, false)); + } + + @Test public void testGetNotificationChannelsBypassingDnd_blocked() throws RemoteException { mService.setPreferencesHelper(mPreferencesHelper); @@ -13187,125 +13242,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testGetPackagesBypassingDnd_empty() throws RemoteException { mService.setPreferencesHelper(mPreferencesHelper); - List<String> result = mBinderService.getPackagesBypassingDnd(mUserId, true); + List<String> result = mBinderService.getPackagesBypassingDnd(mUserId).getList(); assertThat(result).isEmpty(); } @Test - public void testGetPackagesBypassingDnd_excludeConversationChannels() throws RemoteException { - mService.setPreferencesHelper(mPreferencesHelper); - - // Set packages - PackageInfo pkg0 = new PackageInfo(); - pkg0.packageName = "pkg0"; - pkg0.applicationInfo = new ApplicationInfo(); - pkg0.applicationInfo.uid = mUid; - PackageInfo pkg1 = new PackageInfo(); - pkg1.packageName = "pkg1"; - pkg1.applicationInfo = new ApplicationInfo(); - pkg1.applicationInfo.uid = mUid; - PackageInfo pkg2 = new PackageInfo(); - pkg2.packageName = "pkg2"; - pkg2.applicationInfo = new ApplicationInfo(); - pkg2.applicationInfo.uid = mUid; - - when(mPackageManagerClient.getInstalledPackagesAsUser(0, mUserId)) - .thenReturn(List.of(pkg0, pkg1, pkg2)); - - // Conversation channels - NotificationChannel nc0 = new NotificationChannel("id0", "id0", - NotificationManager.IMPORTANCE_HIGH); - nc0.setConversationId("parentChannel", "conversationId"); - - // Demoted conversation channel - NotificationChannel nc1 = new NotificationChannel("id1", "id1", - NotificationManager.IMPORTANCE_HIGH); - nc1.setConversationId("parentChannel", "conversationId"); - nc1.setDemoted(true); - - // Non-conversation channels - NotificationChannel nc2 = new NotificationChannel("id2", "id2", - NotificationManager.IMPORTANCE_HIGH); - NotificationChannel nc3 = new NotificationChannel("id3", "id3", - NotificationManager.IMPORTANCE_HIGH); - - ParceledListSlice<NotificationChannel> pls0 = - new ParceledListSlice(ImmutableList.of(nc0)); - ParceledListSlice<NotificationChannel> pls1 = - new ParceledListSlice(ImmutableList.of(nc1)); - ParceledListSlice<NotificationChannel> pls2 = - new ParceledListSlice(ImmutableList.of(nc2, nc3)); - - when(mPreferencesHelper.getNotificationChannelsBypassingDnd("pkg0", mUid)) - .thenReturn(pls0); - when(mPreferencesHelper.getNotificationChannelsBypassingDnd("pkg1", mUid)) - .thenReturn(pls1); - when(mPreferencesHelper.getNotificationChannelsBypassingDnd("pkg2", mUid)) - .thenReturn(pls2); - - List<String> result = mBinderService.getPackagesBypassingDnd(mUserId, false); - - assertThat(result).containsExactly("pkg1", "pkg2"); - } - - @Test - public void testGetPackagesBypassingDnd_includeConversationChannels() throws RemoteException { - mService.setPreferencesHelper(mPreferencesHelper); - - // Set packages - PackageInfo pkg0 = new PackageInfo(); - pkg0.packageName = "pkg0"; - pkg0.applicationInfo = new ApplicationInfo(); - pkg0.applicationInfo.uid = mUid; - PackageInfo pkg1 = new PackageInfo(); - pkg1.packageName = "pkg1"; - pkg1.applicationInfo = new ApplicationInfo(); - pkg1.applicationInfo.uid = mUid; - PackageInfo pkg2 = new PackageInfo(); - pkg2.packageName = "pkg2"; - pkg2.applicationInfo = new ApplicationInfo(); - pkg2.applicationInfo.uid = mUid; - - when(mPackageManagerClient.getInstalledPackagesAsUser(0, mUserId)) - .thenReturn(List.of(pkg0, pkg1, pkg2)); - - // Conversation channels - NotificationChannel nc0 = new NotificationChannel("id0", "id0", - NotificationManager.IMPORTANCE_HIGH); - nc0.setConversationId("parentChannel", "conversationId"); - - // Demoted conversation channel - NotificationChannel nc1 = new NotificationChannel("id1", "id1", - NotificationManager.IMPORTANCE_HIGH); - nc1.setConversationId("parentChannel", "conversationId"); - nc1.setDemoted(true); - - // Non-conversation channels - NotificationChannel nc2 = new NotificationChannel("id2", "id2", - NotificationManager.IMPORTANCE_HIGH); - NotificationChannel nc3 = new NotificationChannel("id3", "id3", - NotificationManager.IMPORTANCE_HIGH); - - ParceledListSlice<NotificationChannel> pls0 = - new ParceledListSlice(ImmutableList.of(nc0)); - ParceledListSlice<NotificationChannel> pls1 = - new ParceledListSlice(ImmutableList.of(nc1)); - ParceledListSlice<NotificationChannel> pls2 = - new ParceledListSlice(ImmutableList.of(nc2, nc3)); - - when(mPreferencesHelper.getNotificationChannelsBypassingDnd("pkg0", mUid)) - .thenReturn(pls0); - when(mPreferencesHelper.getNotificationChannelsBypassingDnd("pkg1", mUid)) - .thenReturn(pls1); - when(mPreferencesHelper.getNotificationChannelsBypassingDnd("pkg2", mUid)) - .thenReturn(pls2); - - List<String> result = mBinderService.getPackagesBypassingDnd(mUserId, true); - - assertThat(result).containsExactly("pkg0", "pkg1", "pkg2"); - } - - @Test public void testMatchesCallFilter_noPermissionShouldThrow() throws Exception { // set the testable NMS to not system uid/appid mService.isSystemUid = false; @@ -15482,8 +15423,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) { StatusBarNotification sbn = generateNotificationRecord(mTestNotificationChannel, i, null, false).getSbn(); - mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testCannotPostNonUijWhenOverLimit", - sbn.getId(), sbn.getNotification(), sbn.getUserId()); + mBinderService.enqueueNotificationWithTag( + mPkg, + mPkg, + "testCannotPostNonUijWhenOverLimit", + sbn.getId(), + sbn.getNotification(), + sbn.getUserId()); waitForIdle(); } @@ -16213,6 +16159,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { initNMS(SystemService.PHASE_SYSTEM_SERVICES_READY); mInternalService.setDeviceEffectsApplier(mock(DeviceEffectsApplier.class)); + + mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START, mMainLooper); // No exception! } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index e1b478cd1a1b..dda060d5d586 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -108,6 +108,7 @@ import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.app.NotificationManager; +import android.app.ZenBypassingApp; import android.content.AttributionSource; import android.content.ContentProvider; import android.content.ContentResolver; @@ -2620,6 +2621,72 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test + public void getPackagesBypassingDnd_noChannelsBypassing() throws Exception { + assertThat(mHelper.getPackagesBypassingDnd(UserHandle.getUserId(UID_N_MR1))).isEmpty(); + } + + @Test + public void getPackagesBypassingDnd_oneChannelBypassing_deleted() { + NotificationChannel channel1 = new NotificationChannel("id1", "name1", + NotificationManager.IMPORTANCE_MAX); + channel1.setBypassDnd(true); + channel1.setDeleted(true); + // has DND access, so can set bypassDnd attribute + mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, + /*has DND access*/ true, UID_N_MR1, false); + + assertThat(mHelper.getPackagesBypassingDnd(UserHandle.getUserId(UID_N_MR1))).isEmpty(); + } + + @Test + public void getPackagesBypassingDnd_oneChannelBypassing_groupBlocked() { + int uid = UID_N_MR1; + NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1"); + NotificationChannel channel1 = new NotificationChannel("id1", "name1", + NotificationManager.IMPORTANCE_MAX); + channel1.setBypassDnd(true); + channel1.setGroup(ncg.getId()); + mHelper.createNotificationChannelGroup(PKG_N_MR1, uid, ncg, /* fromTargetApp */ true, + uid, false); + mHelper.createNotificationChannel(PKG_N_MR1, uid, channel1, true, /*has DND access*/ true, + uid, false); + ncg.setBlocked(true); + + assertThat(mHelper.getPackagesBypassingDnd(UserHandle.getUserId(uid))).isEmpty(); + } + + @Test + public void getPackagesBypassingDnd_multipleApps() { + List<ZenBypassingApp> expected = ImmutableList.of( + new ZenBypassingApp(PKG_O, true), new ZenBypassingApp(PKG_P, false)); + + NotificationChannel channel1 = new NotificationChannel("id1", "name1", + NotificationManager.IMPORTANCE_MAX); + NotificationChannel channel2 = new NotificationChannel("id2", "name2", + NotificationManager.IMPORTANCE_MAX); + NotificationChannel channel3 = new NotificationChannel("id3", "name3", + NotificationManager.IMPORTANCE_MAX); + NotificationChannel channel4 = new NotificationChannel("id4", "name3", + NotificationManager.IMPORTANCE_MAX); + channel1.setBypassDnd(false); + channel2.setBypassDnd(true); + channel3.setBypassDnd(true); + channel4.setBypassDnd(false); + // has DND access, so can set bypassDnd attribute + mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, + /*has DND access*/ true, UID_N_MR1, false); + mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, true, + UID_O, false); + mHelper.createNotificationChannel(PKG_P, UID_P, channel3, true, true, + UID_P, false); + mHelper.createNotificationChannel(PKG_P, UID_P, channel4, true, true, + UID_P, false); + + assertThat(mHelper.getPackagesBypassingDnd(UserHandle.getUserId(UID_O))) + .containsExactlyElementsIn(expected); + } + + @Test public void testCreateAndDeleteCanChannelsBypassDnd_localSettings() { int uid = UserManager.isHeadlessSystemUserMode() ? UID_HEADLESS : UID_N_MR1; when(mPermissionHelper.hasPermission(uid)).thenReturn(true); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index 4b94e103b9f4..020670dc0f0a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -49,6 +49,8 @@ import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS; import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED; import static android.app.NotificationManager.Policy.STATE_PRIORITY_CHANNELS_BLOCKED; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE; +import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_CONFIG; +import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_RULES; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Process.SYSTEM_UID; import static android.provider.Settings.Global.ZEN_MODE_ALARMS; @@ -84,8 +86,6 @@ import static com.android.os.dnd.DNDProtoEnums.PEOPLE_STARRED; import static com.android.os.dnd.DNDProtoEnums.ROOT_CONFIG; import static com.android.os.dnd.DNDProtoEnums.STATE_ALLOW; import static com.android.os.dnd.DNDProtoEnums.STATE_DISALLOW; -import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_CONFIG; -import static android.app.backup.NotificationLoggingConstants.DATA_TYPE_ZEN_RULES; import static com.android.server.notification.ZenModeEventLogger.ACTIVE_RULE_TYPE_MANUAL; import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE; @@ -102,6 +102,7 @@ import static junit.framework.TestCase.fail; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; @@ -200,6 +201,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.xmlpull.v1.XmlPullParserException; +import platform.test.runner.parameterized.ParameterizedAndroidJunit4; +import platform.test.runner.parameterized.Parameters; + import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; @@ -219,9 +223,6 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import platform.test.runner.parameterized.ParameterizedAndroidJunit4; -import platform.test.runner.parameterized.Parameters; - @SmallTest @SuppressLint("GuardedBy") // It's ok for this test to access guarded methods from the service. @RunWith(ParameterizedAndroidJunit4.class) @@ -5348,6 +5349,22 @@ public class ZenModeHelperTest extends UiServiceTestCase { mTestableLooper.processAllMessages(); verify(mDeviceEffectsApplier).apply(eq(effects), eq(ORIGIN_APP)); + assertTrue(mZenModeHelper.hasDeviceEffectsApplier()); + } + + @Test + public void testHasDeviceEffectsApplier_returnsFalseIfNotSet() { + assertFalse(mZenModeHelper.hasDeviceEffectsApplier()); + } + + @Test + @EnableFlags(FLAG_MODES_API) + public void testSettingDeviceEffects_throwsExceptionIfAlreadySet() { + mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier); + + assertThrows( + IllegalStateException.class, + () -> mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier)); } @Test diff --git a/services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java b/services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java index 88ed61588153..81026fdf4749 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/DeviceAdapterTest.java @@ -16,6 +16,16 @@ package com.android.server.vibrator; +import static android.os.VibrationEffect.Composition.DELAY_TYPE_PAUSE; +import static android.os.VibrationEffect.Composition.DELAY_TYPE_RELATIVE_START_OFFSET; +import static android.os.VibrationEffect.Composition.PRIMITIVE_CLICK; +import static android.os.VibrationEffect.Composition.PRIMITIVE_QUICK_FALL; +import static android.os.VibrationEffect.Composition.PRIMITIVE_QUICK_RISE; +import static android.os.VibrationEffect.Composition.PRIMITIVE_SLOW_RISE; +import static android.os.VibrationEffect.Composition.PRIMITIVE_SPIN; +import static android.os.VibrationEffect.Composition.PRIMITIVE_THUD; +import static android.os.VibrationEffect.Composition.PRIMITIVE_TICK; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; @@ -38,7 +48,7 @@ import android.os.vibrator.StepSegment; import android.os.vibrator.VibrationConfig; import android.os.vibrator.VibrationEffectSegment; import android.platform.test.annotations.DisableFlags; -import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.util.SparseArray; @@ -60,6 +70,7 @@ public class DeviceAdapterTest { private static final int PWLE_VIBRATOR_ID = 2; private static final int PWLE_WITHOUT_FREQUENCIES_VIBRATOR_ID = 3; private static final int PWLE_V2_VIBRATOR_ID = 4; + private static final int BASIC_VIBRATOR_ID = 5; private static final float TEST_MIN_FREQUENCY = 50; private static final float TEST_RESONANT_FREQUENCY = 150; private static final float TEST_FREQUENCY_RESOLUTION = 25; @@ -73,6 +84,7 @@ public class DeviceAdapterTest { private static final float PWLE_V2_MIN_FREQUENCY = TEST_FREQUENCIES_HZ[0]; private static final float PWLE_V2_MAX_FREQUENCY = TEST_FREQUENCIES_HZ[TEST_FREQUENCIES_HZ.length - 1]; + private static final int TEST_PRIMITIVE_DURATION = 20; @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule(); @@ -104,6 +116,7 @@ public class DeviceAdapterTest { vibrators.put(PWLE_WITHOUT_FREQUENCIES_VIBRATOR_ID, createPwleWithoutFrequenciesVibratorController( PWLE_WITHOUT_FREQUENCIES_VIBRATOR_ID)); + vibrators.put(BASIC_VIBRATOR_ID, createBasicVibratorController(BASIC_VIBRATOR_ID)); mAdapter = new DeviceAdapter(mVibrationSettings, vibrators); } @@ -118,12 +131,12 @@ public class DeviceAdapterTest { new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.5f, 100)), /* repeatIndex= */ -1); - assertThat(mAdapter.adaptToVibrator(EMPTY_VIBRATOR_ID, effect)).isEqualTo(effect); + assertThat(mAdapter.adaptToVibrator(BASIC_VIBRATOR_ID, effect)).isEqualTo(effect); assertThat(mAdapter.adaptToVibrator(PWLE_VIBRATOR_ID, effect)).isEqualTo(effect); } @Test - @RequiresFlagsEnabled(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS) + @EnableFlags(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS) public void testVendorEffect_returnsOriginalSegment() { PersistableBundle vendorData = new PersistableBundle(); vendorData.putInt("key", 1); @@ -236,10 +249,10 @@ public class DeviceAdapterTest { VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList( new PrebakedSegment( VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_LIGHT), - new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_TICK, 1, 10), + new StepSegment(1, 0, 10), new PrebakedSegment( VibrationEffect.EFFECT_THUD, true, VibrationEffect.EFFECT_STRENGTH_STRONG), - new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.5f, 100)), + new StepSegment(1, 0, 10)), /* repeatIndex= */ -1); CombinedVibration expected = CombinedVibration.createParallel(effect); @@ -262,6 +275,11 @@ public class DeviceAdapterTest { new StepSegment(1, 175, 10), new StepSegment(1, 0, 50)), /* repeatIndex= */ 1)) + .addVibrator(BASIC_VIBRATOR_ID, new VibrationEffect.Composed(Arrays.asList( + // Step(amplitude, frequencyHz, duration) + new StepSegment(1, 175, 10), + new StepSegment(1, 0, 50)), + /* repeatIndex= */ 1)) .addVibrator(PWLE_VIBRATOR_ID, new VibrationEffect.Composed(Arrays.asList( // Ramp(startAmplitude, endAmplitude, startFrequencyHz, endFrequencyHz, duration) new RampSegment(0.72f, 0.72f, 175, 175, 10), @@ -308,7 +326,7 @@ public class DeviceAdapterTest { } @Test - @RequiresFlagsEnabled(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) + @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void testPwleSegment_withoutPwleV2Capability_returnsNull() { VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList( new PrimitiveSegment(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.5f, 100), @@ -318,12 +336,12 @@ public class DeviceAdapterTest { /* repeatIndex= */ 1); VibrationEffect.Composed adaptedEffect = - (VibrationEffect.Composed) mAdapter.adaptToVibrator(EMPTY_VIBRATOR_ID, effect); + (VibrationEffect.Composed) mAdapter.adaptToVibrator(BASIC_VIBRATOR_ID, effect); assertThat(adaptedEffect).isNull(); } @Test - @RequiresFlagsEnabled(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) + @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void testPwleSegment_withPwleV2Capability_returnsAdaptedSegments() { VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList( new PwleSegment(1, 0.2f, 30, 60, 20), @@ -345,7 +363,7 @@ public class DeviceAdapterTest { } @Test - @RequiresFlagsEnabled(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) + @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void testPwleSegment_withFrequenciesBelowSupportedRange_returnsNull() { float frequencyBelowSupportedRange = PWLE_V2_MIN_FREQUENCY - 1f; VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList( @@ -362,7 +380,7 @@ public class DeviceAdapterTest { } @Test - @RequiresFlagsEnabled(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) + @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void testPwleSegment_withFrequenciesAboveSupportedRange_returnsNull() { float frequencyAboveSupportedRange = PWLE_V2_MAX_FREQUENCY + 1f; VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList( @@ -378,22 +396,79 @@ public class DeviceAdapterTest { assertThat(adapter.adaptToVibrator(PWLE_V2_VIBRATOR_ID, effect)).isNull(); } + @Test + @DisableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + public void testPrimitiveWithRelativeDelay_withoutFlag_returnsNull() { + VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList( + new PrimitiveSegment(PRIMITIVE_TICK, 1, 10, DELAY_TYPE_RELATIVE_START_OFFSET), + new PrimitiveSegment(PRIMITIVE_TICK, 0.5f, 10, DELAY_TYPE_RELATIVE_START_OFFSET), + new PrimitiveSegment(PRIMITIVE_CLICK, 1, 100, DELAY_TYPE_RELATIVE_START_OFFSET)), + /* repeatIndex= */ -1); + + assertThat(mAdapter.adaptToVibrator(EMPTY_VIBRATOR_ID, effect)).isNull(); + assertThat(mAdapter.adaptToVibrator(BASIC_VIBRATOR_ID, effect)).isNull(); + } + + @Test + @EnableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + public void testUnsupportedPrimitives_withFlag_returnsNull() { + VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList( + new PrimitiveSegment(PRIMITIVE_TICK, 1, 10), + new PrimitiveSegment(PRIMITIVE_TICK, 0.5f, 10), + new PrimitiveSegment(PRIMITIVE_CLICK, 1, 100)), + /* repeatIndex= */ -1); + + assertThat(mAdapter.adaptToVibrator(EMPTY_VIBRATOR_ID, effect)).isNull(); + } + + @Test + @EnableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + public void testPrimitiveWithRelativeDelay_returnsPrimitiveWithPauseDelays() { + int expectedPause = 50; + int relativeDelay = 50 + TEST_PRIMITIVE_DURATION - 1; + VibrationEffect.Composed effect = new VibrationEffect.Composed(Arrays.asList( + // Originally requested (overlapping): + // tick @ 10ms / tick @ 11ms / click @ 69ms + 20ms pause + click + // Actually played: + // 10ms pause + tick + 50ms pause + click + 20ms pause + click + new PrimitiveSegment(PRIMITIVE_TICK, 1, 10, DELAY_TYPE_RELATIVE_START_OFFSET), + new PrimitiveSegment(PRIMITIVE_TICK, 0.5f, 1, DELAY_TYPE_RELATIVE_START_OFFSET), + new PrimitiveSegment(PRIMITIVE_CLICK, 1, relativeDelay, + DELAY_TYPE_RELATIVE_START_OFFSET), + new PrimitiveSegment(PRIMITIVE_CLICK, 0.5f, 20, DELAY_TYPE_PAUSE)), + /* repeatIndex= */ -1); + + // Delay based on primitive duration + VibrationEffect.Composed expected = new VibrationEffect.Composed(Arrays.asList( + new PrimitiveSegment(PRIMITIVE_TICK, 1, 10, DELAY_TYPE_PAUSE), + new PrimitiveSegment(PRIMITIVE_CLICK, 1, expectedPause, DELAY_TYPE_PAUSE), + new PrimitiveSegment(PRIMITIVE_CLICK, 0.5f, 20, DELAY_TYPE_PAUSE)), + /* repeatIndex= */ -1); + + assertThat(mAdapter.adaptToVibrator(EMPTY_VIBRATOR_ID, effect)).isNull(); + assertThat(mAdapter.adaptToVibrator(BASIC_VIBRATOR_ID, effect)).isEqualTo(expected); + } + private VibratorController createEmptyVibratorController(int vibratorId) { return new FakeVibratorControllerProvider(mTestLooper.getLooper()) .newVibratorController(vibratorId, (id, vibrationId) -> {}); } + private VibratorController createBasicVibratorController(int vibratorId) { + FakeVibratorControllerProvider provider = createVibratorProviderWithEffects( + IVibrator.CAP_COMPOSE_EFFECTS); + return provider.newVibratorController(vibratorId, (id, vibrationId) -> {}); + } + private VibratorController createPwleWithoutFrequenciesVibratorController(int vibratorId) { - FakeVibratorControllerProvider provider = new FakeVibratorControllerProvider( - mTestLooper.getLooper()); - provider.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS); + FakeVibratorControllerProvider provider = createVibratorProviderWithEffects( + IVibrator.CAP_COMPOSE_EFFECTS, IVibrator.CAP_COMPOSE_PWLE_EFFECTS); return provider.newVibratorController(vibratorId, (id, vibrationId) -> {}); } private VibratorController createPwleVibratorController(int vibratorId) { - FakeVibratorControllerProvider provider = new FakeVibratorControllerProvider( - mTestLooper.getLooper()); - provider.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS); + FakeVibratorControllerProvider provider = createVibratorProviderWithEffects( + IVibrator.CAP_COMPOSE_EFFECTS, IVibrator.CAP_COMPOSE_PWLE_EFFECTS); provider.setResonantFrequency(TEST_RESONANT_FREQUENCY); provider.setMinFrequency(TEST_MIN_FREQUENCY); provider.setFrequencyResolution(TEST_FREQUENCY_RESOLUTION); @@ -402,9 +477,8 @@ public class DeviceAdapterTest { } private VibratorController createPwleV2VibratorController(int vibratorId) { - FakeVibratorControllerProvider provider = new FakeVibratorControllerProvider( - mTestLooper.getLooper()); - provider.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2); + FakeVibratorControllerProvider provider = createVibratorProviderWithEffects( + IVibrator.CAP_COMPOSE_EFFECTS, IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2); provider.setResonantFrequency(TEST_RESONANT_FREQUENCY); provider.setFrequenciesHz(TEST_FREQUENCIES_HZ); provider.setOutputAccelerationsGs(TEST_OUTPUT_ACCELERATIONS_GS); @@ -414,4 +488,15 @@ public class DeviceAdapterTest { return provider.newVibratorController(vibratorId, (id, vibrationId) -> {}); } + + private FakeVibratorControllerProvider createVibratorProviderWithEffects(int... capabilities) { + FakeVibratorControllerProvider provider = new FakeVibratorControllerProvider( + mTestLooper.getLooper()); + provider.setCapabilities(capabilities); + provider.setSupportedPrimitives(PRIMITIVE_CLICK, PRIMITIVE_TICK, PRIMITIVE_THUD, + PRIMITIVE_SPIN, PRIMITIVE_QUICK_RISE, PRIMITIVE_QUICK_FALL, PRIMITIVE_SLOW_RISE); + provider.setSupportedEffects(VibrationEffect.EFFECT_CLICK, VibrationEffect.EFFECT_TICK); + provider.setPrimitiveDuration(TEST_PRIMITIVE_DURATION); + return provider; + } } diff --git a/services/tests/vibrator/src/com/android/server/vibrator/PrimitiveDelayAdapterTest.java b/services/tests/vibrator/src/com/android/server/vibrator/PrimitiveDelayAdapterTest.java new file mode 100644 index 000000000000..f4a6f82fba47 --- /dev/null +++ b/services/tests/vibrator/src/com/android/server/vibrator/PrimitiveDelayAdapterTest.java @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.vibrator; + +import static android.os.VibrationEffect.Composition.DELAY_TYPE_PAUSE; +import static android.os.VibrationEffect.Composition.DELAY_TYPE_RELATIVE_START_OFFSET; +import static android.os.VibrationEffect.Composition.PRIMITIVE_CLICK; +import static android.os.VibrationEffect.Composition.PRIMITIVE_TICK; + +import static org.junit.Assert.assertEquals; + +import android.hardware.vibrator.IVibrator; +import android.os.VibrationEffect; +import android.os.VibratorInfo; +import android.os.vibrator.Flags; +import android.os.vibrator.PrebakedSegment; +import android.os.vibrator.PrimitiveSegment; +import android.os.vibrator.RampSegment; +import android.os.vibrator.StepSegment; +import android.os.vibrator.VibrationEffectSegment; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class PrimitiveDelayAdapterTest { + private static final VibratorInfo EMPTY_VIBRATOR_INFO = new VibratorInfo.Builder(0).build(); + private static final VibratorInfo BASIC_VIBRATOR_INFO = createVibratorInfoWithPrimitives( + new int[] { PRIMITIVE_CLICK, PRIMITIVE_TICK }, + new int[] { 20, 10 }); + + private PrimitiveDelayAdapter mAdapter; + + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + @Before + public void setUp() throws Exception { + mAdapter = new PrimitiveDelayAdapter(); + } + + @Test + @DisableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + public void testPrimitiveSegments_flagDisabled_keepsListUnchanged() { + List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( + new PrimitiveSegment(PRIMITIVE_CLICK, 1f, 100, DELAY_TYPE_RELATIVE_START_OFFSET), + new PrimitiveSegment(PRIMITIVE_TICK, 0.5f, 10, DELAY_TYPE_PAUSE))); + List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments); + + assertEquals(-1, mAdapter.adaptToVibrator(EMPTY_VIBRATOR_INFO, segments, -1)); + assertEquals(1, mAdapter.adaptToVibrator(BASIC_VIBRATOR_INFO, segments, 1)); + + assertEquals(originalSegments, segments); + } + + @Test + @EnableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + public void testNonPrimitiveSegments_keepsListUnchanged() { + List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( + new StepSegment(/* amplitude= */ 0, /* frequencyHz= */ 1, /* duration= */ 10), + new RampSegment(/* startAmplitude= */ 0.8f, /* endAmplitude= */ 0.2f, + /* startFrequencyHz= */ 100, /* endFrequencyHz= */ 1, /* duration= */ 20), + new PrebakedSegment(VibrationEffect.EFFECT_CLICK, false, + VibrationEffect.EFFECT_STRENGTH_LIGHT))); + List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments); + + assertEquals(-1, mAdapter.adaptToVibrator(EMPTY_VIBRATOR_INFO, segments, -1)); + assertEquals(1, mAdapter.adaptToVibrator(BASIC_VIBRATOR_INFO, segments, 1)); + + assertEquals(originalSegments, segments); + } + + @Test + @EnableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + public void testPrimitiveWithPause_keepsListUnchanged() { + List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( + new PrimitiveSegment(PRIMITIVE_CLICK, 1f, 100, DELAY_TYPE_PAUSE), + new PrimitiveSegment(PRIMITIVE_TICK, 0.5f, 10, DELAY_TYPE_PAUSE))); + List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments); + + assertEquals(-1, mAdapter.adaptToVibrator(EMPTY_VIBRATOR_INFO, segments, -1)); + assertEquals(1, mAdapter.adaptToVibrator(BASIC_VIBRATOR_INFO, segments, 1)); + + assertEquals(originalSegments, segments); + } + + @Test + @EnableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + public void testPrimitiveWithRelativeDelay_afterPrimitive_usesPrimitiveStartTimeForDelay() { + VibratorInfo info = createVibratorInfoWithPrimitives( + new int[] { PRIMITIVE_CLICK }, new int[] { 20 }); + + List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( + new PrimitiveSegment(PRIMITIVE_CLICK, 0.1f, 100, DELAY_TYPE_RELATIVE_START_OFFSET), + new PrimitiveSegment(PRIMITIVE_CLICK, 0.2f, 10, DELAY_TYPE_RELATIVE_START_OFFSET), + new PrimitiveSegment(PRIMITIVE_CLICK, 0.3f, 0, DELAY_TYPE_RELATIVE_START_OFFSET), + new PrimitiveSegment(PRIMITIVE_CLICK, 0.4f, 10, DELAY_TYPE_RELATIVE_START_OFFSET))); + + List<VibrationEffectSegment> expectedSegments = new ArrayList<>(Arrays.asList( + new PrimitiveSegment(PRIMITIVE_CLICK, 0.1f, 100, DELAY_TYPE_PAUSE), + new PrimitiveSegment(PRIMITIVE_CLICK, 0.4f, 0, DELAY_TYPE_PAUSE))); + + // Repeat index is fixed after removals + assertEquals(-1, mAdapter.adaptToVibrator(info, segments, -1)); + + assertEquals(expectedSegments, segments); + } + + @Test + @EnableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + public void testPrimitiveWithRelativeDelay_afterRepeatIndex_usesPauseAsFirstDelay() { + VibratorInfo info = createVibratorInfoWithPrimitives( + new int[] { PRIMITIVE_CLICK }, new int[] { 20 }); + + List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( + new PrimitiveSegment(PRIMITIVE_CLICK, 0.1f, 100, DELAY_TYPE_RELATIVE_START_OFFSET), + new PrimitiveSegment(PRIMITIVE_CLICK, 0.2f, 10, DELAY_TYPE_RELATIVE_START_OFFSET), + new PrimitiveSegment(PRIMITIVE_CLICK, 0.3f, 10, DELAY_TYPE_RELATIVE_START_OFFSET), + new PrimitiveSegment(PRIMITIVE_CLICK, 0.4f, 10, DELAY_TYPE_RELATIVE_START_OFFSET))); + + List<VibrationEffectSegment> expectedSegments = new ArrayList<>(Arrays.asList( + new PrimitiveSegment(PRIMITIVE_CLICK, 0.1f, 100, DELAY_TYPE_PAUSE), + new PrimitiveSegment(PRIMITIVE_CLICK, 0.3f, 10, DELAY_TYPE_PAUSE))); + + // Relative offset reset after repeat index. + assertEquals(1, mAdapter.adaptToVibrator(info, segments, 2)); + + assertEquals(expectedSegments, segments); + } + + @Test + @EnableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + public void testPrimitiveWithRelativeDelayAfter_afterStep_usesSegmentStartTimeForDelay() { + List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( + new StepSegment(/* amplitude= */ 0, /* frequencyHz= */ 1, /* duration= */ 10), + new PrimitiveSegment(PRIMITIVE_CLICK, 1f, 10, DELAY_TYPE_RELATIVE_START_OFFSET))); + + List<VibrationEffectSegment> expectedSegments = new ArrayList<>(Arrays.asList( + new StepSegment(/* amplitude= */ 0, /* frequencyHz= */ 1, /* duration= */ 10), + new PrimitiveSegment(PRIMITIVE_CLICK, 1f, 0, DELAY_TYPE_PAUSE))); + + assertEquals(-1, mAdapter.adaptToVibrator(BASIC_VIBRATOR_INFO, segments, -1)); + assertEquals(expectedSegments, segments); + } + + @Test + @EnableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY) + public void testPrimitiveWithRelativeDelayAfter_afterUnknownDuration_usesZeroAsDuration() { + List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( + new PrebakedSegment(VibrationEffect.EFFECT_POP, false, + VibrationEffect.EFFECT_STRENGTH_STRONG), + new PrimitiveSegment(PRIMITIVE_CLICK, 1f, 10, DELAY_TYPE_RELATIVE_START_OFFSET))); + + assertEquals(-1, mAdapter.adaptToVibrator(BASIC_VIBRATOR_INFO, segments, -1)); + + List<VibrationEffectSegment> expectedSegments = new ArrayList<>(Arrays.asList( + new PrebakedSegment(VibrationEffect.EFFECT_POP, false, + VibrationEffect.EFFECT_STRENGTH_STRONG), + new PrimitiveSegment(PRIMITIVE_CLICK, 1f, 10, DELAY_TYPE_PAUSE))); + + assertEquals(expectedSegments, segments); + } + + private static VibratorInfo createVibratorInfoWithPrimitives(int[] ids, int[] durations) { + VibratorInfo.Builder builder = new VibratorInfo.Builder(0) + .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); + + for (int i = 0; i < ids.length; i++) { + builder.setSupportedPrimitive(ids[i], durations[i]); + } + + return builder.build(); + } +} diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java index 093359042a3e..3c2f9616bec5 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java @@ -754,7 +754,7 @@ public class VibrationThreadTest { HalVibration vibration = startThreadAndDispatcher(effect); waitForCompletion(); - verify(mManagerHooks).noteVibratorOn(eq(UID), eq(0L)); + verify(mManagerHooks, never()).noteVibratorOn(eq(UID), anyLong()); verify(mManagerHooks, never()).noteVibratorOff(eq(UID)); verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibration.id)); verifyCallbacksTriggered(vibration, Status.IGNORED_UNSUPPORTED); @@ -1913,6 +1913,55 @@ public class VibrationThreadTest { fakeVibrator.getEffectSegments(vibration5.id)); } + @Test + public void vibrate_multipleVibratorsSequentialInSession_runsInOrderWithoutDelaysAndNoOffs() { + mockVibrators(1, 2, 3); + mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL); + mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); + mVibratorProviders.get(2).setSupportedPrimitives( + VibrationEffect.Composition.PRIMITIVE_CLICK); + mVibratorProviders.get(3).setSupportedEffects(VibrationEffect.EFFECT_CLICK); + + CombinedVibration effect = CombinedVibration.startSequential() + .addNext(3, + VibrationEffect.get(VibrationEffect.EFFECT_CLICK), + /* delay= */ TEST_TIMEOUT_MILLIS) + .addNext(1, + VibrationEffect.createWaveform( + new long[] {TEST_TIMEOUT_MILLIS, TEST_TIMEOUT_MILLIS}, + /* repeat= */ -1), + /* delay= */ TEST_TIMEOUT_MILLIS) + .addNext(2, + VibrationEffect.startComposition() + .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, + /* delay= */ TEST_TIMEOUT_MILLIS) + .compose(), + /* delay= */ TEST_TIMEOUT_MILLIS) + .combine(); + HalVibration vibration = startThreadAndDispatcher(effect, /* isInSession= */ true); + + // Should not timeout as delays will not affect in session playback time. + waitForCompletion(); + + // Vibrating state remains ON until session resets it. + verifyCallbacksTriggered(vibration, Status.FINISHED); + assertTrue(mControllers.get(1).isVibrating()); + assertTrue(mControllers.get(2).isVibrating()); + assertTrue(mControllers.get(3).isVibrating()); + + assertEquals(0, mVibratorProviders.get(1).getOffCount()); + assertEquals(0, mVibratorProviders.get(2).getOffCount()); + assertEquals(0, mVibratorProviders.get(3).getOffCount()); + assertEquals(Arrays.asList(expectedOneShot(TEST_TIMEOUT_MILLIS)), + mVibratorProviders.get(1).getEffectSegments(vibration.id)); + assertEquals(expectedAmplitudes(255), mVibratorProviders.get(1).getAmplitudes()); + assertEquals(Arrays.asList(expectedPrimitive( + VibrationEffect.Composition.PRIMITIVE_CLICK, 1, TEST_TIMEOUT_MILLIS)), + mVibratorProviders.get(2).getEffectSegments(vibration.id)); + assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)), + mVibratorProviders.get(3).getEffectSegments(vibration.id)); + } + private void mockVibrators(int... vibratorIds) { for (int vibratorId : vibratorIds) { mVibratorProviders.put(vibratorId, @@ -1935,8 +1984,14 @@ public class VibrationThreadTest { return startThreadAndDispatcher(createVibration(effect)); } + private HalVibration startThreadAndDispatcher(CombinedVibration effect, boolean isInSession) { + return startThreadAndDispatcher(createVibration(effect), isInSession, + /* requestVibrationParamsFuture= */ null); + } + private HalVibration startThreadAndDispatcher(HalVibration vib) { - return startThreadAndDispatcher(vib, /* requestVibrationParamsFuture= */ null); + return startThreadAndDispatcher(vib, /* isInSession= */ false, + /* requestVibrationParamsFuture= */ null); } private HalVibration startThreadAndDispatcher(VibrationEffect effect, @@ -1947,15 +2002,17 @@ public class VibrationThreadTest { HalVibration vib = new HalVibration( new CallerInfo(attrs, UID, DEVICE_ID, PACKAGE_NAME, "reason"), CombinedVibration.createParallel(effect)); - return startThreadAndDispatcher(vib, requestVibrationParamsFuture); + return startThreadAndDispatcher(vib, /* isInSession= */ false, + requestVibrationParamsFuture); } - private HalVibration startThreadAndDispatcher(HalVibration vib, + private HalVibration startThreadAndDispatcher(HalVibration vib, boolean isInSession, CompletableFuture<Void> requestVibrationParamsFuture) { mControllers = createVibratorControllers(); DeviceAdapter deviceAdapter = new DeviceAdapter(mVibrationSettings, mControllers); - mVibrationConductor = new VibrationStepConductor(vib, mVibrationSettings, deviceAdapter, - mVibrationScaler, mStatsLoggerMock, requestVibrationParamsFuture, mManagerHooks); + mVibrationConductor = new VibrationStepConductor(vib, isInSession, mVibrationSettings, + deviceAdapter, mVibrationScaler, mStatsLoggerMock, requestVibrationParamsFuture, + mManagerHooks); assertTrue(mThread.runVibrationOnVibrationThread(mVibrationConductor)); return mVibrationConductor.getVibration(); } diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java index 88ba9e3af6df..5f76d6815cb8 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java @@ -1531,6 +1531,8 @@ public class VibratorManagerServiceTest { FakeVibratorControllerProvider fakeVibrator1 = mVibratorProviders.get(1); fakeVibrator1.setSupportedEffects(VibrationEffect.EFFECT_CLICK); mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); + mVibratorProviders.get(2).setSupportedPrimitives( + VibrationEffect.Composition.PRIMITIVE_CLICK); VibratorManagerService service = createSystemReadyService(); CombinedVibration effect = CombinedVibration.startParallel() @@ -2115,7 +2117,8 @@ public class VibratorManagerServiceTest { mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK); mVibratorProviders.get(1).setSupportedPrimitives( - VibrationEffect.Composition.PRIMITIVE_CLICK); + VibrationEffect.Composition.PRIMITIVE_CLICK, + VibrationEffect.Composition.PRIMITIVE_TICK); VibratorManagerService service = createSystemReadyService(); vibrateAndWaitUntilFinished(service, @@ -2132,9 +2135,10 @@ public class VibratorManagerServiceTest { assertTrue(segments.size() > 2); // 0: Supported effect played assertTrue(segments.get(0) instanceof PrebakedSegment); - // 1: No segment for unsupported primitive + // 1: Supported primitive played + assertTrue(segments.get(1) instanceof PrimitiveSegment); // 2: One or more intermediate step segments as fallback for unsupported effect - for (int i = 1; i < segments.size() - 1; i++) { + for (int i = 2; i < segments.size() - 1; i++) { assertTrue(segments.get(i) instanceof StepSegment); } // 3: Supported primitive played @@ -3277,7 +3281,8 @@ public class VibratorManagerServiceTest { mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK); mVibratorProviders.get(1).setSupportedPrimitives( - VibrationEffect.Composition.PRIMITIVE_TICK); + VibrationEffect.Composition.PRIMITIVE_TICK, + VibrationEffect.Composition.PRIMITIVE_CLICK); VibratorManagerService service = createSystemReadyService(); vibrateAndWaitUntilFinished(service, @@ -3320,10 +3325,12 @@ public class VibratorManagerServiceTest { assertEquals(3, metrics.halPerformCount); // CLICK, TICK, then CLICK assertEquals(4, metrics.halCompositionSize); // 2*TICK + 2*CLICK // No repetitions in reported effect/primitive IDs. - assertArrayEquals(new int[] {VibrationEffect.Composition.PRIMITIVE_TICK}, + assertArrayEquals( + new int[] { + VibrationEffect.Composition.PRIMITIVE_CLICK, + VibrationEffect.Composition.PRIMITIVE_TICK, + }, metrics.halSupportedCompositionPrimitivesUsed); - assertArrayEquals(new int[] {VibrationEffect.Composition.PRIMITIVE_CLICK}, - metrics.halUnsupportedCompositionPrimitivesUsed); assertArrayEquals(new int[] {VibrationEffect.EFFECT_CLICK}, metrics.halSupportedEffectsUsed); assertArrayEquals(new int[] {VibrationEffect.EFFECT_TICK}, diff --git a/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorControllerProvider.java b/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorControllerProvider.java index 4dc59c20c431..3f3476716831 100644 --- a/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorControllerProvider.java +++ b/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorControllerProvider.java @@ -236,7 +236,7 @@ public final class FakeVibratorControllerProvider { infoBuilder.setSupportedEffects(mSupportedEffects); if (mSupportedPrimitives != null) { for (int primitive : mSupportedPrimitives) { - infoBuilder.setSupportedPrimitive(primitive, EFFECT_DURATION); + infoBuilder.setSupportedPrimitive(primitive, (int) mPrimitiveDuration); } } infoBuilder.setCompositionSizeMax(mCompositionSizeMax); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 42e31de295d6..69fe7c91ac82 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -82,6 +82,7 @@ import android.graphics.Rect; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; +import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.util.ArrayMap; @@ -1299,6 +1300,7 @@ public class WindowOrganizerTests extends WindowTestsBase { } @Test + @DisableFlags(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2) public void testEnterPipParams() { final StubOrganizer o = new StubOrganizer(); mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(o); @@ -1314,6 +1316,7 @@ public class WindowOrganizerTests extends WindowTestsBase { } @Test + @DisableFlags(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2) public void testChangePipParams() { class ChangeSavingOrganizer extends StubOrganizer { RunningTaskInfo mChangedInfo; diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 1750a14e0561..b737d35c1534 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -353,6 +353,29 @@ public class WindowStateTests extends WindowTestsBase { } @Test + public void testDestroySurface() { + final WindowState win = createWindow(null, TYPE_APPLICATION, "win"); + win.mHasSurface = win.mAnimatingExit = true; + win.mWinAnimator.mSurfaceControl = mock(SurfaceControl.class); + win.onExitAnimationDone(); + + assertFalse("Case 1 destroySurface no-op", + win.destroySurface(false /* cleanupOnResume */, false /* appStopped */)); + assertTrue(win.mHasSurface); + assertTrue(win.mDestroying); + + assertFalse("Case 2 destroySurface no-op", + win.destroySurface(true /* cleanupOnResume */, false /* appStopped */)); + assertTrue(win.mHasSurface); + assertTrue(win.mDestroying); + + assertTrue("Case 3 destroySurface destroys surface", + win.destroySurface(false /* cleanupOnResume */, true /* appStopped */)); + assertFalse(win.mDestroying); + assertFalse(win.mHasSurface); + } + + @Test public void testPrepareWindowToDisplayDuringRelayout() { // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON before // calling setCurrentLaunchCanTurnScreenOn for windows with flag in the same activity. diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 129494517cd6..15c8b135d2c4 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -185,6 +185,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser private static final int MSG_INCREASE_SENDSTRING_COUNT = 21; private static final int MSG_UPDATE_USB_SPEED = 22; private static final int MSG_UPDATE_HAL_VERSION = 23; + private static final int MSG_USER_UNLOCKED_AFTER_BOOT = 24; // Delay for debouncing USB disconnects. // We often get rapid connect/disconnect events when enabling USB functions, @@ -414,6 +415,17 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } }; + if (Flags.checkUserActionUnlocked()) { + BroadcastReceiver userUnlockedAfterBootReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + mHandler.sendEmptyMessage(MSG_USER_UNLOCKED_AFTER_BOOT); + } + }; + mContext.registerReceiver(userUnlockedAfterBootReceiver, + new IntentFilter(Intent.ACTION_USER_UNLOCKED)); + } + mContext.registerReceiver(portReceiver, new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED)); mContext.registerReceiver(chargingReceiver, @@ -474,6 +486,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser mHandler.sendEmptyMessage(MSG_SYSTEM_READY); } + // Same as ACTION_LOCKED_BOOT_COMPLETED. public void bootCompleted() { if (DEBUG) Slog.d(TAG, "boot completed"); mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED); @@ -632,7 +645,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser protected int mUsbSpeed; protected int mCurrentGadgetHalVersion; protected boolean mPendingBootAccessoryHandshakeBroadcast; - + protected boolean mUserUnlockedAfterBoot; /** * The persistent property which stores whether adb is enabled or not. * May also contain vendor-specific default functions for testing purposes. @@ -837,6 +850,12 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser return !userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER); } + private void attachAccessory() { + mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory); + removeMessages(MSG_ACCESSORY_HANDSHAKE_TIMEOUT); + broadcastUsbAccessoryHandshake(); + } + private void updateCurrentAccessory() { // We are entering accessory mode if we have received a request from the host // and the request has not timed out yet. @@ -863,10 +882,13 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory); // defer accessoryAttached if system is not ready - if (mBootCompleted) { - mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory); - removeMessages(MSG_ACCESSORY_HANDSHAKE_TIMEOUT); - broadcastUsbAccessoryHandshake(); + if (!Flags.checkUserActionUnlocked() && mBootCompleted) { + attachAccessory(); + } + // Defer accessoryAttached till user unlocks after boot. + // When no pin pattern is set, ACTION_USER_UNLOCKED would fire anyways + if (Flags.checkUserActionUnlocked() && mUserUnlockedAfterBoot) { + attachAccessory(); } // else handle in boot completed } else { Slog.e(TAG, "nativeGetAccessoryStrings failed"); @@ -887,7 +909,10 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); if (mCurrentAccessory != null) { - if (mBootCompleted) { + if (!Flags.checkUserActionUnlocked() && mBootCompleted) { + mPermissionManager.usbAccessoryRemoved(mCurrentAccessory); + } + if (Flags.checkUserActionUnlocked() && mUserUnlockedAfterBoot) { mPermissionManager.usbAccessoryRemoved(mCurrentAccessory); } mCurrentAccessory = null; @@ -1377,6 +1402,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser case MSG_BOOT_COMPLETED: operationId = sUsbOperationCount.incrementAndGet(); mBootCompleted = true; + if (DEBUG) Slog.d(TAG, "MSG_BOOT_COMPLETED"); finishBoot(operationId); break; case MSG_USER_SWITCHED: { @@ -1423,14 +1449,38 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } case MSG_INCREASE_SENDSTRING_COUNT: { mSendStringCount = mSendStringCount + 1; + break; + } + case MSG_USER_UNLOCKED_AFTER_BOOT: { + if (DEBUG) Slog.d(TAG, "MSG_USER_UNLOCKED_AFTER_BOOT"); + if (mUserUnlockedAfterBoot) { + break; + } + mUserUnlockedAfterBoot = true; + if (mCurrentUsbFunctionsReceived && mUserUnlockedAfterBoot) { + attachAccessoryAfterBoot(); + } + break; } } } + private void attachAccessoryAfterBoot() { + if (mCurrentAccessory != null) { + Slog.i(TAG, "AccessoryAttached"); + mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory); + broadcastUsbAccessoryHandshake(); + } else if (mPendingBootAccessoryHandshakeBroadcast) { + broadcastUsbAccessoryHandshake(); + } + mPendingBootAccessoryHandshakeBroadcast = false; + } + public abstract void handlerInitDone(int operationId); protected void finishBoot(int operationId) { if (mBootCompleted && mCurrentUsbFunctionsReceived && mSystemReady) { + if (DEBUG) Slog.d(TAG, "finishBoot all flags true"); if (mPendingBootBroadcast) { updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions)); mPendingBootBroadcast = false; @@ -1441,14 +1491,12 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } else { setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId); } - if (mCurrentAccessory != null) { - mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory); - broadcastUsbAccessoryHandshake(); - } else if (mPendingBootAccessoryHandshakeBroadcast) { - broadcastUsbAccessoryHandshake(); + if (!Flags.checkUserActionUnlocked()) { + attachAccessoryAfterBoot(); + } + if (Flags.checkUserActionUnlocked() && mUserUnlockedAfterBoot) { + attachAccessoryAfterBoot(); } - - mPendingBootAccessoryHandshakeBroadcast = false; updateUsbNotification(false); updateAdbNotification(false); updateUsbFunctions(); diff --git a/services/usb/java/com/android/server/usb/flags/usb_flags.aconfig b/services/usb/java/com/android/server/usb/flags/usb_flags.aconfig index cd96d76a1c93..a2d0efd1d063 100644 --- a/services/usb/java/com/android/server/usb/flags/usb_flags.aconfig +++ b/services/usb/java/com/android/server/usb/flags/usb_flags.aconfig @@ -14,3 +14,10 @@ flag { description: "This flag enables binding to MtpService when in mtp/ptp modes" bug: "332256525" } + +flag { + name: "check_user_action_unlocked" + namespace: "usb" + description: "This flag checks if phone is unlocked after boot" + bug: "73654179" +} diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt index ea61ad9d4481..9f5e6d18dc03 100644 --- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt +++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt @@ -347,6 +347,14 @@ open class DesktopModeAppHelper(private val innerHelper: IStandardAppHelper) : waitForTransitionToFullscreen(wmHelper) } + /** Maximize an app by dragging the app handle to the top drag zone. */ + fun maximizeAppWithDragToTopDragZone( + wmHelper: WindowManagerStateHelper, + device: UiDevice, + ) { + dragAppWindowToTopDragZone(wmHelper, device) + } + private fun dragAppWindowToTopDragZone(wmHelper: WindowManagerStateHelper, device: UiDevice) { val windowRect = wmHelper.getWindowRegion(innerHelper).bounds val displayRect = getDisplayRect(wmHelper) diff --git a/tests/Input/src/com/android/server/input/KeyboardBacklightControllerTests.kt b/tests/Input/src/com/android/server/input/KeyboardBacklightControllerTests.kt index 58fb4e1ed103..938e2f8a3611 100644 --- a/tests/Input/src/com/android/server/input/KeyboardBacklightControllerTests.kt +++ b/tests/Input/src/com/android/server/input/KeyboardBacklightControllerTests.kt @@ -19,6 +19,7 @@ package com.android.server.input import android.animation.ValueAnimator import android.content.Context import android.content.ContextWrapper +import android.content.res.Resources import android.graphics.Color import android.hardware.input.IKeyboardBacklightListener import android.hardware.input.IKeyboardBacklightState @@ -28,11 +29,12 @@ import android.os.UEventObserver import android.os.test.TestLooper import android.platform.test.annotations.Presubmit import android.view.InputDevice +import android.util.TypedValue import androidx.test.annotation.UiThreadTest import androidx.test.core.app.ApplicationProvider +import com.android.internal.R import com.android.server.input.KeyboardBacklightController.DEFAULT_BRIGHTNESS_VALUE_FOR_LEVEL import com.android.server.input.KeyboardBacklightController.MAX_BRIGHTNESS_CHANGE_STEPS -import com.android.server.input.KeyboardBacklightController.USER_INACTIVITY_THRESHOLD_MILLIS import com.android.test.input.MockInputManagerRule import java.io.FileNotFoundException import java.io.FileOutputStream @@ -49,6 +51,7 @@ import org.junit.Rule import org.junit.Test import org.mockito.Mock import org.mockito.Mockito.any +import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.anyInt import org.mockito.Mockito.eq import org.mockito.Mockito.spy @@ -94,6 +97,7 @@ class KeyboardBacklightControllerTests { const val LIGHT_ID = 2 const val SECOND_LIGHT_ID = 3 const val MAX_BRIGHTNESS = 255 + const val USER_INACTIVITY_THRESHOLD_MILLIS = 30000 } @get:Rule @@ -105,6 +109,8 @@ class KeyboardBacklightControllerTests { private lateinit var native: NativeInputManagerService @Mock private lateinit var uEventManager: UEventManager + @Mock + private lateinit var resources: Resources private lateinit var keyboardBacklightController: KeyboardBacklightController private lateinit var context: Context private lateinit var dataStore: PersistentDataStore @@ -117,6 +123,7 @@ class KeyboardBacklightControllerTests { @Before fun setup() { context = spy(ContextWrapper(ApplicationProvider.getApplicationContext())) + `when`(context.resources).thenReturn(resources) dataStore = PersistentDataStore(object : PersistentDataStore.Injector() { override fun openRead(): InputStream? { throw FileNotFoundException() @@ -129,6 +136,7 @@ class KeyboardBacklightControllerTests { override fun finishWrite(fos: FileOutputStream?, success: Boolean) {} }) testLooper = TestLooper() + setupConfig() keyboardBacklightController = KeyboardBacklightController(context, native, dataStore, testLooper.looper, FakeAnimatorFactory(), uEventManager) val inputManager = InputManager(context) @@ -147,7 +155,31 @@ class KeyboardBacklightControllerTests { sysfsNodeChanges++ } } - + private fun setupConfig() { + val brightnessValues = intArrayOf(100, 200, 0) + val decreaseThresholds = intArrayOf(-1, 900, 1900) + val increaseThresholds = intArrayOf(1000, 2000, -1) + `when`(resources.getIntArray(R.array.config_autoKeyboardBacklightBrightnessValues)) + .thenReturn(brightnessValues) + `when`(resources.getIntArray(R.array.config_autoKeyboardBacklightDecreaseLuxThreshold)) + .thenReturn(decreaseThresholds) + `when`(resources.getIntArray(R.array.config_autoKeyboardBacklightIncreaseLuxThreshold)) + .thenReturn(increaseThresholds) + `when`(resources.getInteger(R.integer.config_keyboardBacklightTimeoutMs)) + .thenReturn(USER_INACTIVITY_THRESHOLD_MILLIS) + `when`( + resources.getValue( + eq(R.dimen.config_autoKeyboardBrightnessSmoothingConstant), + any(TypedValue::class.java), + anyBoolean() + ) + ).then { + val args = it.arguments + val outValue = args[1] as TypedValue + outValue.data = java.lang.Float.floatToRawIntBits(1.0f) + Unit + } + } @Test fun testKeyboardBacklightIncrementDecrement() { KeyboardBacklightFlags( @@ -365,7 +397,7 @@ class KeyboardBacklightControllerTests { lightColorMap[LIGHT_ID] ) - testLooper.moveTimeForward(USER_INACTIVITY_THRESHOLD_MILLIS + 1000) + testLooper.moveTimeForward((USER_INACTIVITY_THRESHOLD_MILLIS + 1000).toLong()) testLooper.dispatchNext() assertEquals( "Keyboard backlight level should be turned off after inactivity", diff --git a/tests/PackageWatchdog/Android.bp b/tests/PackageWatchdog/Android.bp index 91483eb41387..8be74eaccd20 100644 --- a/tests/PackageWatchdog/Android.bp +++ b/tests/PackageWatchdog/Android.bp @@ -37,7 +37,7 @@ android_test { "truth", ] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), { "true": [ - "service-crashrecovery.impl", + "service-crashrecovery-pre-jarjar", "framework-crashrecovery.impl", ], default: [], diff --git a/tests/broadcasts/OWNERS b/tests/broadcasts/OWNERS deleted file mode 100644 index d2e1f815e8dc..000000000000 --- a/tests/broadcasts/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# Bug component: 316181 -include platform/frameworks/base:/BROADCASTS_OWNERS diff --git a/tests/broadcasts/unit/Android.bp b/tests/broadcasts/unit/Android.bp deleted file mode 100644 index 47166a713580..000000000000 --- a/tests/broadcasts/unit/Android.bp +++ /dev/null @@ -1,45 +0,0 @@ -// -// Copyright (C) 2024 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], - default_team: "trendy_team_framework_backstage_power", -} - -android_test { - name: "BroadcastUnitTests", - srcs: ["src/**/*.java"], - defaults: [ - "modules-utils-extended-mockito-rule-defaults", - ], - static_libs: [ - "androidx.test.runner", - "androidx.test.rules", - "androidx.test.ext.junit", - "mockito-target-extended-minus-junit4", - "truth", - "flag-junit", - "android.app.flags-aconfig-java", - ], - certificate: "platform", - platform_apis: true, - test_suites: ["device-tests"], -} diff --git a/tests/broadcasts/unit/AndroidManifest.xml b/tests/broadcasts/unit/AndroidManifest.xml deleted file mode 100644 index e9c5248e4d98..000000000000 --- a/tests/broadcasts/unit/AndroidManifest.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2024 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.broadcasts.unit" > - - <application android:debuggable="true"> - <uses-library android:name="android.test.runner" /> - </application> - - <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.broadcasts.unit" - android:label="Broadcasts Unit Tests"/> -</manifest>
\ No newline at end of file diff --git a/tests/broadcasts/unit/AndroidTest.xml b/tests/broadcasts/unit/AndroidTest.xml deleted file mode 100644 index b91e4783b69e..000000000000 --- a/tests/broadcasts/unit/AndroidTest.xml +++ /dev/null @@ -1,29 +0,0 @@ -<!-- Copyright (C) 2024 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<configuration description="Runs Broadcasts tests"> - <option name="test-suite-tag" value="apct" /> - <option name="test-tag" value="BroadcastUnitTests" /> - - <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> - <option name="cleanup-apks" value="true" /> - <option name="test-file-name" value="BroadcastUnitTests.apk" /> - </target_preparer> - - <test class="com.android.tradefed.testtype.AndroidJUnitTest" > - <option name="package" value="com.android.broadcasts.unit" /> - <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> - <option name="hidden-api-checks" value="false"/> - </test> -</configuration>
\ No newline at end of file diff --git a/tests/broadcasts/unit/TEST_MAPPING b/tests/broadcasts/unit/TEST_MAPPING deleted file mode 100644 index 8919fdcd7a3f..000000000000 --- a/tests/broadcasts/unit/TEST_MAPPING +++ /dev/null @@ -1,15 +0,0 @@ -{ - "presubmit": [ - { - "name": "BroadcastUnitTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] - } - ] -} diff --git a/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java b/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java deleted file mode 100644 index b7c412dea999..000000000000 --- a/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.app; - -import static android.content.Intent.ACTION_BATTERY_CHANGED; -import static android.content.Intent.ACTION_DEVICE_STORAGE_LOW; - -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; - -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; - -import android.content.Intent; -import android.content.IntentFilter; -import android.os.BatteryManager; -import android.os.Bundle; -import android.os.SystemProperties; -import android.platform.test.annotations.EnableFlags; -import android.platform.test.flag.junit.SetFlagsRule; -import android.util.ArrayMap; - -import androidx.annotation.GuardedBy; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.modules.utils.testing.ExtendedMockitoRule; - -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; - -@EnableFlags(Flags.FLAG_USE_STICKY_BCAST_CACHE) -@RunWith(AndroidJUnit4.class) -@SmallTest -public class BroadcastStickyCacheTest { - @ClassRule - public static final SetFlagsRule.ClassRule mClassRule = new SetFlagsRule.ClassRule(); - @Rule - public final SetFlagsRule mSetFlagsRule = mClassRule.createSetFlagsRule(); - - @Rule - public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this) - .mockStatic(SystemProperties.class) - .build(); - - private static final String PROP_KEY_BATTERY_CHANGED = BroadcastStickyCache.getKey( - ACTION_BATTERY_CHANGED); - - private final TestSystemProps mTestSystemProps = new TestSystemProps(); - - @Before - public void setUp() { - doAnswer(invocation -> { - final String name = invocation.getArgument(0); - final long value = Long.parseLong(invocation.getArgument(1)); - mTestSystemProps.add(name, value); - return null; - }).when(() -> SystemProperties.set(anyString(), anyString())); - doAnswer(invocation -> { - final String name = invocation.getArgument(0); - final TestSystemProps.Handle testHandle = mTestSystemProps.query(name); - if (testHandle == null) { - return null; - } - final SystemProperties.Handle handle = Mockito.mock(SystemProperties.Handle.class); - doAnswer(handleInvocation -> testHandle.getLong(-1)).when(handle).getLong(anyLong()); - return handle; - }).when(() -> SystemProperties.find(anyString())); - } - - @After - public void tearDown() { - mTestSystemProps.clear(); - BroadcastStickyCache.clearForTest(); - } - - @Test - public void testUseCache_nullFilter() { - assertThat(BroadcastStickyCache.useCache(null)).isEqualTo(false); - } - - @Test - public void testUseCache_noActions() { - final IntentFilter filter = new IntentFilter(); - assertThat(BroadcastStickyCache.useCache(filter)).isEqualTo(false); - } - - @Test - public void testUseCache_multipleActions() { - final IntentFilter filter = new IntentFilter(); - filter.addAction(ACTION_DEVICE_STORAGE_LOW); - filter.addAction(ACTION_BATTERY_CHANGED); - assertThat(BroadcastStickyCache.useCache(filter)).isEqualTo(false); - } - - @Test - public void testUseCache_valueNotSet() { - final IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED); - assertThat(BroadcastStickyCache.useCache(filter)).isEqualTo(false); - } - - @Test - public void testUseCache() { - final IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED); - final Intent intent = new Intent(ACTION_BATTERY_CHANGED) - .putExtra(BatteryManager.EXTRA_LEVEL, 90); - BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED); - BroadcastStickyCache.add(filter, intent); - assertThat(BroadcastStickyCache.useCache(filter)).isEqualTo(true); - } - - @Test - public void testUseCache_versionMismatch() { - final IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED); - final Intent intent = new Intent(ACTION_BATTERY_CHANGED) - .putExtra(BatteryManager.EXTRA_LEVEL, 90); - BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED); - BroadcastStickyCache.add(filter, intent); - BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED); - - assertThat(BroadcastStickyCache.useCache(filter)).isEqualTo(false); - } - - @Test - public void testAdd() { - final IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED); - Intent intent = new Intent(ACTION_BATTERY_CHANGED) - .putExtra(BatteryManager.EXTRA_LEVEL, 90); - BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED); - BroadcastStickyCache.add(filter, intent); - assertThat(BroadcastStickyCache.useCache(filter)).isEqualTo(true); - Intent actualIntent = BroadcastStickyCache.getIntentUnchecked(filter); - assertThat(actualIntent).isNotNull(); - assertEquals(actualIntent, intent); - - intent = new Intent(ACTION_BATTERY_CHANGED) - .putExtra(BatteryManager.EXTRA_LEVEL, 99); - BroadcastStickyCache.add(filter, intent); - actualIntent = BroadcastStickyCache.getIntentUnchecked(filter); - assertThat(actualIntent).isNotNull(); - assertEquals(actualIntent, intent); - } - - @Test - public void testIncrementVersion_propExists() { - SystemProperties.set(PROP_KEY_BATTERY_CHANGED, String.valueOf(100)); - - BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED); - assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(101); - BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED); - assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(102); - } - - @Test - public void testIncrementVersion_propNotExists() { - // Verify that the property doesn't exist - assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(-1); - - BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED); - assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(1); - BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED); - assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(2); - } - - @Test - public void testIncrementVersionIfExists_propExists() { - BroadcastStickyCache.incrementVersion(ACTION_BATTERY_CHANGED); - - BroadcastStickyCache.incrementVersionIfExists(ACTION_BATTERY_CHANGED); - assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(2); - BroadcastStickyCache.incrementVersionIfExists(ACTION_BATTERY_CHANGED); - assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(3); - } - - @Test - public void testIncrementVersionIfExists_propNotExists() { - // Verify that the property doesn't exist - assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(-1); - - BroadcastStickyCache.incrementVersionIfExists(ACTION_BATTERY_CHANGED); - assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(-1); - // Verify that property is not added as part of the querying. - BroadcastStickyCache.incrementVersionIfExists(ACTION_BATTERY_CHANGED); - assertThat(mTestSystemProps.get(PROP_KEY_BATTERY_CHANGED, -1 /* def */)).isEqualTo(-1); - } - - private void assertEquals(Intent actualIntent, Intent expectedIntent) { - assertThat(actualIntent.getAction()).isEqualTo(expectedIntent.getAction()); - assertEquals(actualIntent.getExtras(), expectedIntent.getExtras()); - } - - private void assertEquals(Bundle actualExtras, Bundle expectedExtras) { - assertWithMessage("Extras expected=%s, actual=%s", expectedExtras, actualExtras) - .that(actualExtras.kindofEquals(expectedExtras)).isTrue(); - } - - private static final class TestSystemProps { - @GuardedBy("mSysProps") - private final ArrayMap<String, Long> mSysProps = new ArrayMap<>(); - - public void add(String name, long value) { - synchronized (mSysProps) { - mSysProps.put(name, value); - } - } - - public long get(String name, long defaultValue) { - synchronized (mSysProps) { - final int idx = mSysProps.indexOfKey(name); - return idx >= 0 ? mSysProps.valueAt(idx) : defaultValue; - } - } - - public Handle query(String name) { - synchronized (mSysProps) { - return mSysProps.containsKey(name) ? new Handle(name) : null; - } - } - - public void clear() { - synchronized (mSysProps) { - mSysProps.clear(); - } - } - - public class Handle { - private final String mName; - - Handle(String name) { - mName = name; - } - - public long getLong(long defaultValue) { - return get(mName, defaultValue); - } - } - } -} diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp index 1bef5f8b17f6..1d4adc4a57d8 100644 --- a/tools/aapt2/link/TableMerger.cpp +++ b/tools/aapt2/link/TableMerger.cpp @@ -207,14 +207,13 @@ static ResourceTable::CollisionResult MergeConfigValue( Value* dst_value = dst_config_value->value.get(); Value* src_value = src_config_value->value.get(); - CollisionResult collision_result; - if (overlay) { - collision_result = - ResolveMergeCollision(override_styles_instead_of_overlaying, dst_value, src_value, pool); - } else { - collision_result = - ResourceTable::ResolveFlagCollision(dst_value->GetFlagStatus(), src_value->GetFlagStatus()); - if (collision_result == CollisionResult::kConflict) { + CollisionResult collision_result = + ResourceTable::ResolveFlagCollision(dst_value->GetFlagStatus(), src_value->GetFlagStatus()); + if (collision_result == CollisionResult::kConflict) { + if (overlay) { + collision_result = + ResolveMergeCollision(override_styles_instead_of_overlaying, dst_value, src_value, pool); + } else { collision_result = ResourceTable::ResolveValueCollision(dst_value, src_value); } } |