Merge "Init ProtoLog in SystemServicesTestRule" into main
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index fe80d1b..8fad79a 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -5926,9 +5926,6 @@
pw.print(Flags.FLAG_DO_NOT_FORCE_RUSH_EXECUTION_AT_BOOT,
Flags.doNotForceRushExecutionAtBoot());
pw.println();
- pw.print(android.app.job.Flags.FLAG_BACKUP_JOBS_EXEMPTION,
- android.app.job.Flags.backupJobsExemption());
- pw.println();
pw.print(android.app.job.Flags.FLAG_IGNORE_IMPORTANT_WHILE_FOREGROUND,
android.app.job.Flags.ignoreImportantWhileForeground());
pw.println();
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
index f3bc9c7..42c8250 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
@@ -433,9 +433,6 @@
case com.android.server.job.Flags.FLAG_DO_NOT_FORCE_RUSH_EXECUTION_AT_BOOT:
pw.println(com.android.server.job.Flags.doNotForceRushExecutionAtBoot());
break;
- case android.app.job.Flags.FLAG_BACKUP_JOBS_EXEMPTION:
- pw.println(android.app.job.Flags.backupJobsExemption());
- break;
case android.app.job.Flags.FLAG_IGNORE_IMPORTANT_WHILE_FOREGROUND:
pw.println(android.app.job.Flags.ignoreImportantWhileForeground());
break;
diff --git a/core/api/current.txt b/core/api/current.txt
index d0a2439..5efa747 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -27170,6 +27170,15 @@
package android.media.quality {
+ @FlaggedApi("android.media.tv.flags.media_quality_fw") public final class ActiveProcessingPicture implements android.os.Parcelable {
+ ctor public ActiveProcessingPicture(int, @NonNull String);
+ method public int describeContents();
+ method public int getId();
+ method @NonNull public String getProfileId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.media.quality.ActiveProcessingPicture> CREATOR;
+ }
+
@FlaggedApi("android.media.tv.flags.media_quality_fw") public final class AmbientBacklightEvent implements android.os.Parcelable {
ctor public AmbientBacklightEvent(int, @Nullable android.media.quality.AmbientBacklightMetadata);
method public int describeContents();
@@ -27256,13 +27265,14 @@
}
@FlaggedApi("android.media.tv.flags.media_quality_fw") public final class MediaQualityManager {
+ method public void addActiveProcessingPictureListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.ActiveProcessingPictureListener);
method public void createPictureProfile(@NonNull android.media.quality.PictureProfile);
method public void createSoundProfile(@NonNull android.media.quality.SoundProfile);
- method @NonNull public java.util.List<android.media.quality.PictureProfile> getAvailablePictureProfiles();
- method @NonNull public java.util.List<android.media.quality.SoundProfile> getAvailableSoundProfiles();
+ method @NonNull public java.util.List<android.media.quality.PictureProfile> getAvailablePictureProfiles(boolean);
+ method @NonNull public java.util.List<android.media.quality.SoundProfile> getAvailableSoundProfiles(boolean);
method @NonNull public java.util.List<android.media.quality.ParamCapability> getParamCapabilities(@NonNull java.util.List<java.lang.String>);
- method @Nullable public android.media.quality.PictureProfile getPictureProfile(int, @NonNull String);
- method @Nullable public android.media.quality.SoundProfile getSoundProfile(int, @NonNull String);
+ method @Nullable public android.media.quality.PictureProfile getPictureProfile(int, @NonNull String, boolean);
+ method @Nullable public android.media.quality.SoundProfile getSoundProfile(int, @NonNull String, boolean);
method public boolean isAmbientBacklightEnabled();
method public boolean isAutoPictureQualityEnabled();
method public boolean isAutoSoundQualityEnabled();
@@ -27270,6 +27280,7 @@
method public void registerAmbientBacklightCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.AmbientBacklightCallback);
method public void registerPictureProfileCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.PictureProfileCallback);
method public void registerSoundProfileCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.SoundProfileCallback);
+ method public void removeActiveProcessingPictureListener(@NonNull android.media.quality.MediaQualityManager.ActiveProcessingPictureListener);
method public void removePictureProfile(@NonNull String);
method public void removeSoundProfile(@NonNull String);
method public void setAmbientBacklightEnabled(boolean);
@@ -27281,6 +27292,10 @@
method public void updateSoundProfile(@NonNull String, @NonNull android.media.quality.SoundProfile);
}
+ public static interface MediaQualityManager.ActiveProcessingPictureListener {
+ method public void onActiveProcessingPicturesChanged(@NonNull java.util.List<android.media.quality.ActiveProcessingPicture>);
+ }
+
public abstract static class MediaQualityManager.AmbientBacklightCallback {
ctor public MediaQualityManager.AmbientBacklightCallback();
method public void onAmbientBacklightEvent(@NonNull android.media.quality.AmbientBacklightEvent);
@@ -27288,7 +27303,7 @@
public abstract static class MediaQualityManager.PictureProfileCallback {
ctor public MediaQualityManager.PictureProfileCallback();
- method public void onError(int);
+ method public void onError(@Nullable String, int);
method public void onParamCapabilitiesChanged(@Nullable String, @NonNull java.util.List<android.media.quality.ParamCapability>);
method public void onPictureProfileAdded(@NonNull String, @NonNull android.media.quality.PictureProfile);
method public void onPictureProfileRemoved(@NonNull String, @NonNull android.media.quality.PictureProfile);
@@ -27297,7 +27312,7 @@
public abstract static class MediaQualityManager.SoundProfileCallback {
ctor public MediaQualityManager.SoundProfileCallback();
- method public void onError(int);
+ method public void onError(@Nullable String, int);
method public void onParamCapabilitiesChanged(@Nullable String, @NonNull java.util.List<android.media.quality.ParamCapability>);
method public void onSoundProfileAdded(@NonNull String, @NonNull android.media.quality.SoundProfile);
method public void onSoundProfileRemoved(@NonNull String, @NonNull android.media.quality.SoundProfile);
@@ -34750,7 +34765,10 @@
method public android.os.MessageQueue getMessageQueue();
method public boolean hasMessages(android.os.Handler, Object, int);
method public boolean hasMessages(android.os.Handler, Object, Runnable);
+ method @FlaggedApi("android.os.message_queue_testability") public boolean isBlockedOnSyncBarrier();
method public android.os.Message next();
+ method @FlaggedApi("android.os.message_queue_testability") @Nullable public Long peekWhen();
+ method @FlaggedApi("android.os.message_queue_testability") @Nullable public android.os.Message poll();
method public void recycle(android.os.Message);
method public void release();
}
@@ -41030,7 +41048,7 @@
field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
field public static final int TYPE_VIEW_REQUESTED_AUTOFILL = 6; // 0x6
- field @FlaggedApi("android.service.autofill.autofill_w_metrics") public static final int UI_TYPE_CREDMAN = 4; // 0x4
+ field @FlaggedApi("android.service.autofill.autofill_w_metrics") public static final int UI_TYPE_CREDENTIAL_MANAGER = 4; // 0x4
field public static final int UI_TYPE_DIALOG = 3; // 0x3
field public static final int UI_TYPE_INLINE = 2; // 0x2
field public static final int UI_TYPE_MENU = 1; // 0x1
@@ -44870,11 +44888,11 @@
field public static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY = "carrier_vvm_package_name_string_array";
field public static final String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
field public static final String KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL = "carrier_wfc_supports_wifi_only_bool";
- field public static final String KEY_CDMA_3WAYCALL_FLASH_DELAY_INT = "cdma_3waycall_flash_delay_int";
- field public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
- field public static final String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
- field public static final String KEY_CDMA_ROAMING_MODE_INT = "cdma_roaming_mode_int";
- field public static final String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_3WAYCALL_FLASH_DELAY_INT = "cdma_3waycall_flash_delay_int";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_ROAMING_MODE_INT = "cdma_roaming_mode_int";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
field public static final String KEY_CELLULAR_SERVICE_CAPABILITIES_INT_ARRAY = "cellular_service_capabilities_int_array";
field public static final String KEY_CELLULAR_USAGE_SETTING_INT = "cellular_usage_setting_int";
field public static final String KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL = "check_pricing_with_carrier_data_roaming_bool";
@@ -44901,7 +44919,7 @@
field public static final String KEY_DEFAULT_VM_NUMBER_ROAMING_AND_IMS_UNREGISTERED_STRING = "default_vm_number_roaming_and_ims_unregistered_string";
field public static final String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
field public static final String KEY_DIAL_STRING_REPLACE_STRING_ARRAY = "dial_string_replace_string_array";
- field public static final String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
field public static final String KEY_DISABLE_CHARGE_INDICATION_BOOL = "disable_charge_indication_bool";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL = "disable_dun_apn_while_roaming_with_preset_apn_bool";
field public static final String KEY_DISABLE_SUPPLEMENTARY_SERVICES_IN_AIRPLANE_MODE_BOOL = "disable_supplementary_services_in_airplane_mode_bool";
@@ -45052,10 +45070,10 @@
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_SUPPORTED_MSG_APPS_STRING_ARRAY = "satellite_supported_msg_apps_string_array";
field public static final String KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL = "show_4g_for_3g_data_icon_bool";
field public static final String KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL = "show_4g_for_lte_data_icon_bool";
- field public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
field public static final String KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL = "show_blocking_pay_phone_option_bool";
field public static final String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL = "show_call_blocking_disabled_notification_always_bool";
- field public static final String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
field public static final String KEY_SHOW_FORWARDED_NUMBER_BOOL = "show_forwarded_number_bool";
field public static final String KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL = "show_iccid_in_sim_status_bool";
field public static final String KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL = "show_ims_registration_status_bool";
@@ -45085,7 +45103,7 @@
field public static final String KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL = "support_enhanced_call_blocking_bool";
field public static final String KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL = "support_ims_conference_event_package_bool";
field public static final String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
- field public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
field public static final String KEY_SUPPORT_TDSCDMA_BOOL = "support_tdscdma_bool";
field public static final String KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY = "support_tdscdma_roaming_networks_string_array";
field public static final String KEY_SWITCH_DATA_TO_PRIMARY_IF_PRIMARY_IS_OOS_BOOL = "switch_data_to_primary_if_primary_is_oos_bool";
@@ -45095,7 +45113,7 @@
field public static final String KEY_USE_ACS_FOR_RCS_BOOL = "use_acs_for_rcs_bool";
field public static final String KEY_USE_HFA_FOR_PROVISIONING_BOOL = "use_hfa_for_provisioning_bool";
field public static final String KEY_USE_IP_FOR_CALLING_INDICATOR_BOOL = "use_ip_for_calling_indicator_bool";
- field public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool";
field @Deprecated public static final String KEY_USE_RCS_PRESENCE_BOOL = "use_rcs_presence_bool";
field public static final String KEY_USE_RCS_SIP_OPTIONS_BOOL = "use_rcs_sip_options_bool";
field public static final String KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL = "use_wfc_home_network_mode_in_roaming_network_bool";
@@ -45531,13 +45549,13 @@
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentity> CREATOR;
}
- public final class CellIdentityCdma extends android.telephony.CellIdentity {
- method public int getBasestationId();
- method public int getLatitude();
- method public int getLongitude();
- method public int getNetworkId();
- method public int getSystemId();
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityCdma> CREATOR;
+ @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public final class CellIdentityCdma extends android.telephony.CellIdentity {
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getBasestationId();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getLatitude();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getLongitude();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getNetworkId();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getSystemId();
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityCdma> CREATOR;
}
public final class CellIdentityGsm extends android.telephony.CellIdentity {
@@ -45629,11 +45647,11 @@
field public static final long UNAVAILABLE_LONG = 9223372036854775807L; // 0x7fffffffffffffffL
}
- public final class CellInfoCdma extends android.telephony.CellInfo implements android.os.Parcelable {
- method @NonNull public android.telephony.CellIdentityCdma getCellIdentity();
- method @NonNull public android.telephony.CellSignalStrengthCdma getCellSignalStrength();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellInfoCdma> CREATOR;
+ @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public final class CellInfoCdma extends android.telephony.CellInfo implements android.os.Parcelable {
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public android.telephony.CellIdentityCdma getCellIdentity();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public android.telephony.CellSignalStrengthCdma getCellSignalStrength();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public void writeToParcel(android.os.Parcel, int);
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellInfoCdma> CREATOR;
}
public final class CellInfoGsm extends android.telephony.CellInfo implements android.os.Parcelable {
@@ -47212,11 +47230,11 @@
method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getImei(int);
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.READ_SMS, android.Manifest.permission.READ_PHONE_NUMBERS}) public String getLine1Number();
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public String getManualNetworkSelectionPlmn();
- method @Nullable public String getManufacturerCode();
- method @Nullable public String getManufacturerCode(int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @Nullable public String getManufacturerCode();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @Nullable public String getManufacturerCode(int);
method public static long getMaximumCallComposerPictureSize();
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid();
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid(int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid(int);
method public String getMmsUAProfUrl();
method public String getMmsUserAgent();
method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getNai();
@@ -47362,10 +47380,10 @@
field public static final int CARRIER_RESTRICTION_STATUS_RESTRICTED = 2; // 0x2
field public static final int CARRIER_RESTRICTION_STATUS_RESTRICTED_TO_CALLER = 3; // 0x3
field public static final int CARRIER_RESTRICTION_STATUS_UNKNOWN = 0; // 0x0
- field public static final int CDMA_ROAMING_MODE_AFFILIATED = 1; // 0x1
- field public static final int CDMA_ROAMING_MODE_ANY = 2; // 0x2
- field public static final int CDMA_ROAMING_MODE_HOME = 0; // 0x0
- field public static final int CDMA_ROAMING_MODE_RADIO_DEFAULT = -1; // 0xffffffff
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ROAMING_MODE_AFFILIATED = 1; // 0x1
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ROAMING_MODE_ANY = 2; // 0x2
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ROAMING_MODE_HOME = 0; // 0x0
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ROAMING_MODE_RADIO_DEFAULT = -1; // 0xffffffff
field public static final int DATA_ACTIVITY_DORMANT = 4; // 0x4
field public static final int DATA_ACTIVITY_IN = 1; // 0x1
field public static final int DATA_ACTIVITY_INOUT = 3; // 0x3
@@ -47385,9 +47403,9 @@
field public static final int DATA_SUSPENDED = 3; // 0x3
field public static final int DATA_UNKNOWN = -1; // 0xffffffff
field public static final int DEFAULT_PORT_INDEX = 0; // 0x0
- field public static final int ERI_FLASH = 2; // 0x2
- field public static final int ERI_OFF = 1; // 0x1
- field public static final int ERI_ON = 0; // 0x0
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int ERI_FLASH = 2; // 0x2
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int ERI_OFF = 1; // 0x1
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int ERI_ON = 0; // 0x0
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final String EVENT_DISPLAY_EMERGENCY_MESSAGE = "android.telephony.event.DISPLAY_EMERGENCY_MESSAGE";
field public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT = "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT";
field public static final String EXTRA_APN_PROTOCOL = "android.telephony.extra.APN_PROTOCOL";
@@ -47428,11 +47446,11 @@
field public static final int NETWORK_SELECTION_MODE_AUTO = 1; // 0x1
field public static final int NETWORK_SELECTION_MODE_MANUAL = 2; // 0x2
field public static final int NETWORK_SELECTION_MODE_UNKNOWN = 0; // 0x0
- field public static final int NETWORK_TYPE_1xRTT = 7; // 0x7
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_1xRTT = 7; // 0x7
field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L
- field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L
- field public static final long NETWORK_TYPE_BITMASK_EHRPD = 8192L; // 0x2000L
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final long NETWORK_TYPE_BITMASK_EHRPD = 8192L; // 0x2000L
field public static final long NETWORK_TYPE_BITMASK_EVDO_0 = 16L; // 0x10L
field public static final long NETWORK_TYPE_BITMASK_EVDO_A = 32L; // 0x20L
field public static final long NETWORK_TYPE_BITMASK_EVDO_B = 2048L; // 0x800L
@@ -47445,16 +47463,17 @@
field public static final long NETWORK_TYPE_BITMASK_IWLAN = 131072L; // 0x20000L
field public static final long NETWORK_TYPE_BITMASK_LTE = 4096L; // 0x1000L
field @Deprecated public static final long NETWORK_TYPE_BITMASK_LTE_CA = 262144L; // 0x40000L
+ field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final long NETWORK_TYPE_BITMASK_NB_IOT_NTN = 1048576L; // 0x100000L
field public static final long NETWORK_TYPE_BITMASK_NR = 524288L; // 0x80000L
field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L
field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L
field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L
- field public static final int NETWORK_TYPE_CDMA = 4; // 0x4
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_CDMA = 4; // 0x4
field public static final int NETWORK_TYPE_EDGE = 2; // 0x2
- field public static final int NETWORK_TYPE_EHRPD = 14; // 0xe
- field public static final int NETWORK_TYPE_EVDO_0 = 5; // 0x5
- field public static final int NETWORK_TYPE_EVDO_A = 6; // 0x6
- field public static final int NETWORK_TYPE_EVDO_B = 12; // 0xc
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_EHRPD = 14; // 0xe
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_EVDO_0 = 5; // 0x5
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_EVDO_A = 6; // 0x6
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_EVDO_B = 12; // 0xc
field public static final int NETWORK_TYPE_GPRS = 1; // 0x1
field public static final int NETWORK_TYPE_GSM = 16; // 0x10
field public static final int NETWORK_TYPE_HSDPA = 8; // 0x8
@@ -47464,11 +47483,12 @@
field @Deprecated public static final int NETWORK_TYPE_IDEN = 11; // 0xb
field public static final int NETWORK_TYPE_IWLAN = 18; // 0x12
field public static final int NETWORK_TYPE_LTE = 13; // 0xd
+ field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final int NETWORK_TYPE_NB_IOT_NTN = 21; // 0x15
field public static final int NETWORK_TYPE_NR = 20; // 0x14
field public static final int NETWORK_TYPE_TD_SCDMA = 17; // 0x11
field public static final int NETWORK_TYPE_UMTS = 3; // 0x3
field public static final int NETWORK_TYPE_UNKNOWN = 0; // 0x0
- field public static final int PHONE_TYPE_CDMA = 2; // 0x2
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int PHONE_TYPE_CDMA = 2; // 0x2
field public static final int PHONE_TYPE_GSM = 1; // 0x1
field public static final int PHONE_TYPE_NONE = 0; // 0x0
field public static final int PHONE_TYPE_SIP = 3; // 0x3
@@ -55232,8 +55252,8 @@
method public abstract void setTransformation(android.graphics.Matrix);
method public abstract void setVisibility(int);
method public abstract void setWebDomain(@Nullable String);
- field @FlaggedApi("android.service.autofill.autofill_w_metrics") public static final String EXTRA_VIRTUAL_STRUCTURE_TYPE = "android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_TYPE";
- field @FlaggedApi("android.service.autofill.autofill_w_metrics") public static final String EXTRA_VIRTUAL_STRUCTURE_VERSION_NUMBER = "android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER";
+ field @FlaggedApi("android.service.autofill.autofill_w_metrics") public static final String EXTRA_VIRTUAL_STRUCTURE_TYPE = "android.view.extra.VIRTUAL_STRUCTURE_TYPE";
+ field @FlaggedApi("android.service.autofill.autofill_w_metrics") public static final String EXTRA_VIRTUAL_STRUCTURE_VERSION_NUMBER = "android.view.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER";
}
public abstract static class ViewStructure.HtmlInfo {
@@ -58346,6 +58366,7 @@
method @NonNull @WorkerThread public default android.view.textclassifier.TextSelection suggestSelection(@NonNull android.view.textclassifier.TextSelection.Request);
method @NonNull @WorkerThread public default android.view.textclassifier.TextSelection suggestSelection(@NonNull CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @Nullable android.os.LocaleList);
field public static final String EXTRA_FROM_TEXT_CLASSIFIER = "android.view.textclassifier.extra.FROM_TEXT_CLASSIFIER";
+ field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final String EXTRA_TEXT_ORIGIN_PACKAGE = "android.view.textclassifier.extra.TEXT_ORIGIN_PACKAGE";
field public static final String HINT_TEXT_IS_EDITABLE = "android.text_is_editable";
field public static final String HINT_TEXT_IS_NOT_EDITABLE = "android.text_is_not_editable";
field public static final android.view.textclassifier.TextClassifier NO_OP;
@@ -58355,6 +58376,7 @@
field public static final String TYPE_EMAIL = "email";
field public static final String TYPE_FLIGHT_NUMBER = "flight";
field public static final String TYPE_OTHER = "other";
+ field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final String TYPE_OTP = "otp";
field public static final String TYPE_PHONE = "phone";
field public static final String TYPE_UNKNOWN = "";
field public static final String TYPE_URL = "url";
diff --git a/core/api/lint-baseline.txt b/core/api/lint-baseline.txt
index ad5bd31..e71dffa 100644
--- a/core/api/lint-baseline.txt
+++ b/core/api/lint-baseline.txt
@@ -1,10 +1,4 @@
// Baseline format: 1.0
-ActionValue: android.view.ViewStructure#EXTRA_VIRTUAL_STRUCTURE_TYPE:
- Inconsistent extra value; expected `android.view.extra.VIRTUAL_STRUCTURE_TYPE`, was `android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_TYPE`
-ActionValue: android.view.ViewStructure#EXTRA_VIRTUAL_STRUCTURE_VERSION_NUMBER:
- Inconsistent extra value; expected `android.view.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER`, was `android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER`
-
-
BroadcastBehavior: android.app.AlarmManager#ACTION_NEXT_ALARM_CLOCK_CHANGED:
Field 'ACTION_NEXT_ALARM_CLOCK_CHANGED' is missing @BroadcastBehavior
BroadcastBehavior: android.app.AlarmManager#ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED:
@@ -1191,10 +1185,6 @@
New API must be flagged with @FlaggedApi: field android.R.dimen.system_corner_radius_xlarge
UnflaggedApi: android.R.dimen#system_corner_radius_xsmall:
New API must be flagged with @FlaggedApi: field android.R.dimen.system_corner_radius_xsmall
-UnflaggedApi: android.R.integer#status_bar_notification_info_maxnum:
- Changes from not deprecated to deprecated must be flagged with @FlaggedApi: field android.R.integer.status_bar_notification_info_maxnum
-UnflaggedApi: android.R.string#status_bar_notification_info_overflow:
- Changes from not deprecated to deprecated must be flagged with @FlaggedApi: field android.R.string.status_bar_notification_info_overflow
UnflaggedApi: android.accessibilityservice.AccessibilityService#OVERLAY_RESULT_INTERNAL_ERROR:
New API must be flagged with @FlaggedApi: field android.accessibilityservice.AccessibilityService.OVERLAY_RESULT_INTERNAL_ERROR
UnflaggedApi: android.accessibilityservice.AccessibilityService#OVERLAY_RESULT_INVALID:
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index b6e2b8a..9590e1a 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -10,6 +10,7 @@
field @FlaggedApi("android.app.contextualsearch.flags.enable_service") public static final String ACCESS_CONTEXTUAL_SEARCH = "android.permission.ACCESS_CONTEXTUAL_SEARCH";
field public static final String ACCESS_CONTEXT_HUB = "android.permission.ACCESS_CONTEXT_HUB";
field public static final String ACCESS_DRM_CERTIFICATES = "android.permission.ACCESS_DRM_CERTIFICATES";
+ field @FlaggedApi("android.permission.flags.fine_power_monitor_permission") public static final String ACCESS_FINE_POWER_MONITORS = "android.permission.ACCESS_FINE_POWER_MONITORS";
field @Deprecated public static final String ACCESS_FM_RADIO = "android.permission.ACCESS_FM_RADIO";
field public static final String ACCESS_FPS_COUNTER = "android.permission.ACCESS_FPS_COUNTER";
field @FlaggedApi("android.multiuser.enable_permission_to_access_hidden_profiles") public static final String ACCESS_HIDDEN_PROFILES_FULL = "android.permission.ACCESS_HIDDEN_PROFILES_FULL";
@@ -26,6 +27,7 @@
field public static final String ACCESS_SHORTCUTS = "android.permission.ACCESS_SHORTCUTS";
field @FlaggedApi("android.app.smartspace.flags.access_smartspace") public static final String ACCESS_SMARTSPACE = "android.permission.ACCESS_SMARTSPACE";
field public static final String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";
+ field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final String ACCESS_TEXT_CLASSIFIER_BY_TYPE = "android.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE";
field public static final String ACCESS_TUNED_INFO = "android.permission.ACCESS_TUNED_INFO";
field public static final String ACCESS_TV_DESCRAMBLER = "android.permission.ACCESS_TV_DESCRAMBLER";
field public static final String ACCESS_TV_SHARED_FILTER = "android.permission.ACCESS_TV_SHARED_FILTER";
@@ -7987,12 +7989,13 @@
package android.media.quality {
@FlaggedApi("android.media.tv.flags.media_quality_fw") public final class MediaQualityManager {
+ method public void addGlobalActiveProcessingPictureListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.ActiveProcessingPictureListener);
method @NonNull public java.util.List<java.lang.String> getPictureProfileAllowList();
method @NonNull public java.util.List<java.lang.String> getPictureProfilePackageNames();
- method @NonNull public java.util.List<android.media.quality.PictureProfile> getPictureProfilesByPackage(@NonNull String);
+ method @NonNull public java.util.List<android.media.quality.PictureProfile> getPictureProfilesByPackage(@NonNull String, boolean);
method @NonNull public java.util.List<java.lang.String> getSoundProfileAllowList();
method @NonNull public java.util.List<java.lang.String> getSoundProfilePackageNames();
- method @NonNull public java.util.List<android.media.quality.SoundProfile> getSoundProfilesByPackage(@NonNull String);
+ method @NonNull public java.util.List<android.media.quality.SoundProfile> getSoundProfilesByPackage(@NonNull String, boolean);
method public void setAutoPictureQualityEnabled(boolean);
method public void setAutoSoundQualityEnabled(boolean);
method public boolean setDefaultPictureProfile(@Nullable String);
@@ -12710,14 +12713,14 @@
}
@FlaggedApi("android.security.secure_lockdown") public final class DisableSecureLockDeviceParams implements android.os.Parcelable {
- ctor public DisableSecureLockDeviceParams(@NonNull String);
+ ctor public DisableSecureLockDeviceParams(@NonNull CharSequence);
method public int describeContents();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.security.authenticationpolicy.DisableSecureLockDeviceParams> CREATOR;
}
@FlaggedApi("android.security.secure_lockdown") public final class EnableSecureLockDeviceParams implements android.os.Parcelable {
- ctor public EnableSecureLockDeviceParams(@NonNull String);
+ ctor public EnableSecureLockDeviceParams(@NonNull CharSequence);
method public int describeContents();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.security.authenticationpolicy.EnableSecureLockDeviceParams> CREATOR;
@@ -14629,7 +14632,7 @@
field public static final int CALLTYPE_INCOMING = 1; // 0x1
field public static final int CALLTYPE_OUTGOING = 2; // 0x2
field public static final int CALLTYPE_UNKNOWN = 0; // 0x0
- field public static final int CDMA_PHONE = 1; // 0x1
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_PHONE = 1; // 0x1
field @NonNull public static final android.os.Parcelable.Creator<android.telecom.ParcelableCallAnalytics> CREATOR;
field public static final int GSM_PHONE = 2; // 0x2
field public static final int IMS_PHONE = 4; // 0x4
@@ -15010,7 +15013,7 @@
field public static final String KEY_GBA_UA_SECURITY_ORGANIZATION_INT = "gba_ua_security_organization_int";
field public static final String KEY_GBA_UA_SECURITY_PROTOCOL_INT = "gba_ua_security_protocol_int";
field public static final String KEY_GBA_UA_TLS_CIPHER_SUITE_INT = "gba_ua_tls_cipher_suite_int";
- field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool";
}
public static final class CarrierConfigManager.Wifi {
@@ -15097,8 +15100,8 @@
ctor public CellBroadcastService();
method @NonNull @WorkerThread public abstract CharSequence getCellBroadcastAreaInfo(int);
method @CallSuper public android.os.IBinder onBind(@Nullable android.content.Intent);
- method public abstract void onCdmaCellBroadcastSms(int, @NonNull byte[], int);
- method public abstract void onCdmaScpMessage(int, @NonNull java.util.List<android.telephony.cdma.CdmaSmsCbProgramData>, @NonNull String, @NonNull java.util.function.Consumer<android.os.Bundle>);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public void onCdmaCellBroadcastSms(int, @NonNull byte[], int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public void onCdmaScpMessage(int, @NonNull java.util.List<android.telephony.cdma.CdmaSmsCbProgramData>, @NonNull String, @NonNull java.util.function.Consumer<android.os.Bundle>);
method public abstract void onGsmCellBroadcastSms(int, @NonNull byte[]);
field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService";
}
@@ -15108,9 +15111,9 @@
method @NonNull public abstract android.telephony.CellIdentity sanitizeLocationInfo();
}
- public final class CellIdentityCdma extends android.telephony.CellIdentity {
- method @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation();
- method @NonNull public android.telephony.CellIdentityCdma sanitizeLocationInfo();
+ @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public final class CellIdentityCdma extends android.telephony.CellIdentity {
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public android.telephony.CellIdentityCdma sanitizeLocationInfo();
}
public final class CellIdentityGsm extends android.telephony.CellIdentity {
@@ -15526,16 +15529,16 @@
field public static final int BUSY = 17; // 0x11
field public static final int CALL_BARRED = 240; // 0xf0
field public static final int CALL_REJECTED = 21; // 0x15
- field public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1
- field public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee
- field public static final int CDMA_DROP = 1001; // 0x3e9
- field public static final int CDMA_INTERCEPT = 1002; // 0x3ea
- field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8
- field public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0
- field public static final int CDMA_PREEMPTED = 1007; // 0x3ef
- field public static final int CDMA_REORDER = 1003; // 0x3eb
- field public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed
- field public static final int CDMA_SO_REJECT = 1004; // 0x3ec
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_DROP = 1001; // 0x3e9
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_INTERCEPT = 1002; // 0x3ea
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_PREEMPTED = 1007; // 0x3ef
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_REORDER = 1003; // 0x3eb
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_SO_REJECT = 1004; // 0x3ec
field public static final int CHANNEL_NOT_AVAIL = 44; // 0x2c
field public static final int CHANNEL_UNACCEPTABLE = 6; // 0x6
field public static final int CONDITIONAL_IE_ERROR = 100; // 0x64
@@ -16069,14 +16072,14 @@
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getCarrierServicePackageName();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getCarrierServicePackageNameForLogicalSlot(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaEnhancedRoamingIndicatorDisplayNumber();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int);
- method public String getCdmaPrlVersion();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaRoamingMode();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaSubscriptionMode();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaEnhancedRoamingIndicatorDisplayNumber();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public String getCdmaPrlVersion();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaRoamingMode();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaSubscriptionMode();
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS) public java.util.List<android.telephony.CellBroadcastIdRange> getCellBroadcastIdRanges();
method public int getCurrentPhoneType();
method public int getCurrentPhoneType(int);
@@ -16166,7 +16169,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void resetIms(int);
method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void resetOtaEmergencyNumberDbFilePath();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int sendThermalMitigationRequest(@NonNull android.telephony.ThermalMitigationRequest);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
@@ -16175,8 +16178,8 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCallWaitingEnabled(boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaRoamingMode(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaSubscriptionMode(int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaRoamingMode(int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaSubscriptionMode(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS) public void setCellBroadcastIdRanges(@NonNull java.util.List<android.telephony.CellBroadcastIdRange>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
@@ -16240,9 +16243,9 @@
field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
- field public static final int CDMA_SUBSCRIPTION_NV = 1; // 0x1
- field public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // 0x0
- field public static final int CDMA_SUBSCRIPTION_UNKNOWN = -1; // 0xffffffff
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_SUBSCRIPTION_NV = 1; // 0x1
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // 0x0
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_SUBSCRIPTION_UNKNOWN = -1; // 0xffffffff
field public static final int CELL_BROADCAST_RESULT_FAIL_ACTIVATION = 3; // 0x3
field public static final int CELL_BROADCAST_RESULT_FAIL_CONFIG = 2; // 0x2
field public static final int CELL_BROADCAST_RESULT_SUCCESS = 0; // 0x0
@@ -16459,21 +16462,21 @@
package android.telephony.cdma {
- public final class CdmaSmsCbProgramData implements android.os.Parcelable {
- method public int describeContents();
- method public int getCategory();
- method public int getOperation();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 4099; // 0x1003
- field public static final int CATEGORY_CMAS_EXTREME_THREAT = 4097; // 0x1001
- field public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 4351; // 0x10ff
- field public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 4096; // 0x1000
- field public static final int CATEGORY_CMAS_SEVERE_THREAT = 4098; // 0x1002
- field public static final int CATEGORY_CMAS_TEST_MESSAGE = 4100; // 0x1004
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.cdma.CdmaSmsCbProgramData> CREATOR;
- field public static final int OPERATION_ADD_CATEGORY = 1; // 0x1
- field public static final int OPERATION_CLEAR_CATEGORIES = 2; // 0x2
- field public static final int OPERATION_DELETE_CATEGORY = 0; // 0x0
+ @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public final class CdmaSmsCbProgramData implements android.os.Parcelable {
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int describeContents();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getCategory();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getOperation();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public void writeToParcel(android.os.Parcel, int);
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 4099; // 0x1003
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_EXTREME_THREAT = 4097; // 0x1001
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 4351; // 0x10ff
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 4096; // 0x1000
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_SEVERE_THREAT = 4098; // 0x1002
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_TEST_MESSAGE = 4100; // 0x1004
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public static final android.os.Parcelable.Creator<android.telephony.cdma.CdmaSmsCbProgramData> CREATOR;
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int OPERATION_ADD_CATEGORY = 1; // 0x1
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int OPERATION_CLEAR_CATEGORIES = 2; // 0x2
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int OPERATION_DELETE_CATEGORY = 0; // 0x0
}
}
@@ -17801,7 +17804,7 @@
field public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 1; // 0x1
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 7; // 0x7
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 6; // 0x6
- field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 4; // 0x4
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 4; // 0x4
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 5; // 0x5
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_INTERNET_PDN = 12; // 0xc
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 9; // 0x9
@@ -19135,6 +19138,20 @@
}
+package android.view.textclassifier {
+
+ public final class TextClassificationManager {
+ method @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE) public android.view.textclassifier.TextClassifier getClassifier(int);
+ }
+
+ public interface TextClassifier {
+ field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final int CLASSIFIER_TYPE_ANDROID_DEFAULT = 2; // 0x2
+ field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final int CLASSIFIER_TYPE_DEVICE_DEFAULT = 1; // 0x1
+ field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final int CLASSIFIER_TYPE_SELF_PROVIDED = 0; // 0x0
+ }
+
+}
+
package android.view.translation {
public final class TranslationCapability implements android.os.Parcelable {
diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
index 7c43891..3b9ef959 100644
--- a/core/api/system-lint-baseline.txt
+++ b/core/api/system-lint-baseline.txt
@@ -505,6 +505,8 @@
FlaggedApiLiteral: android.Manifest.permission#ACCESS_LAST_KNOWN_CELL_ID:
@FlaggedApi contains a string literal, but should reference the field generated by aconfig (com.android.server.telecom.flags.Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES).
+FlaggedApiLiteral: android.Manifest.permission#ACCESS_TEXT_CLASSIFIER_BY_TYPE:
+ @FlaggedApi contains a string literal, but should reference the field generated by aconfig (android.permission.flags.Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED).
FlaggedApiLiteral: android.Manifest.permission#BACKUP_HEALTH_CONNECT_DATA_AND_SETTINGS:
@FlaggedApi contains a string literal, but should reference the field generated by aconfig (android.permission.flags.Flags.FLAG_HEALTH_CONNECT_BACKUP_RESTORE_PERMISSION_ENABLED).
FlaggedApiLiteral: android.Manifest.permission#BIND_VERIFICATION_AGENT:
diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt
index 9140bdf..349b4ed 100644
--- a/core/api/test-lint-baseline.txt
+++ b/core/api/test-lint-baseline.txt
@@ -1,10 +1,4 @@
// Baseline format: 1.0
-ActionValue: android.view.contentcapture.ViewNode.ViewStructureImpl#EXTRA_VIRTUAL_STRUCTURE_TYPE:
- Inconsistent extra value; expected `android.view.contentcapture.extra.VIRTUAL_STRUCTURE_TYPE`, was `android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_TYPE`
-ActionValue: android.view.contentcapture.ViewNode.ViewStructureImpl#EXTRA_VIRTUAL_STRUCTURE_VERSION_NUMBER:
- Inconsistent extra value; expected `android.view.contentcapture.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER`, was `android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER`
-
-
BannedThrow: android.os.vibrator.persistence.VibrationXmlSerializer#serialize(android.os.VibrationEffect, java.io.Writer):
Methods must not throw unchecked exceptions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 38aea64..03ef669 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1279,7 +1279,24 @@
*
* <p>This method should be utilized when an activity wants to nudge the user to switch
* to the web application in cases where the web may provide the user with a better
- * experience. Note that this method does not guarantee that the education will be shown.</p>
+ * experience. Note that this method does not guarantee that the education will be shown.
+ *
+ * <p>The number of times that the "Open in browser" education can be triggered by this method
+ * is limited per application, and, when shown, the education appears above the app's content.
+ * For these reasons, developers should use this method sparingly when it is least
+ * disruptive to the user to show the education and when it is optimal to switch the user to a
+ * browser session. Before requesting to show the education, developers should assert that they
+ * have set a link that can be used by the "Open in browser" feature through either
+ * {@link AssistContent#EXTRA_AUTHENTICATING_USER_WEB_URI} or
+ * {@link AssistContent#setWebUri} so that users are navigated to a relevant page if they choose
+ * to switch to the browser. If a URI is not set using either method, "Open in browser" will
+ * utilize a generic link if available which will direct users to the homepage of the site
+ * associated with the app. The generic link is provided for a limited number of applications by
+ * the system and cannot be edited by developers. If none of these options contains a valid URI,
+ * the user will not be provided with the option to switch to the browser and the education will
+ * not be shown if requested.
+ *
+ * @see android.app.assist.AssistContent#EXTRA_SESSION_TRANSFER_WEB_URI
*/
@FlaggedApi(com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB_EDUCATION)
public final void requestOpenInBrowserEducation() {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 33ba058..69d3e8d 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1189,6 +1189,18 @@
return procState == PROCESS_STATE_FOREGROUND_SERVICE;
}
+ /** @hide Should this process state be considered jank perceptible? */
+ public static final boolean isProcStateJankPerceptible(int procState) {
+ if (Flags.jankPerceptibleNarrow()) {
+ return procState == PROCESS_STATE_PERSISTENT_UI
+ || procState == PROCESS_STATE_TOP
+ || procState == PROCESS_STATE_IMPORTANT_FOREGROUND
+ || procState == PROCESS_STATE_TOP_SLEEPING;
+ } else {
+ return !isProcStateCached(procState);
+ }
+ }
+
/** @hide requestType for assist context: only basic information. */
public static final int ASSIST_CONTEXT_BASIC = 0;
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index eccb6ff..abdfb535 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -44,6 +44,8 @@
import android.os.PowerExemptionManager.TempAllowListType;
import android.os.TransactionTooLargeException;
import android.os.WorkSource;
+import android.os.instrumentation.IOffsetCallback;
+import android.os.instrumentation.MethodDescriptor;
import android.util.ArraySet;
import android.util.Pair;
@@ -1352,6 +1354,14 @@
String reason, int exitInfoReason);
/**
+ * Queries the offset data for a given method on a process.
+ * @hide
+ */
+ public abstract void getExecutableMethodFileOffsets(@NonNull String processName,
+ int pid, int uid, @NonNull MethodDescriptor methodDescriptor,
+ @NonNull IOffsetCallback callback);
+
+ /**
* Add a creator token for all embedded intents (stored as extra) of the given intent.
*
* @param intent The given intent
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 27661ce..48b74f2 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -165,6 +165,10 @@
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.instrumentation.ExecutableMethodFileOffsets;
+import android.os.instrumentation.IOffsetCallback;
+import android.os.instrumentation.MethodDescriptor;
+import android.os.instrumentation.MethodDescriptorParser;
import android.permission.IPermissionManager;
import android.provider.BlockedNumberContract;
import android.provider.CalendarContract;
@@ -2236,6 +2240,29 @@
args.arg6 = uiTranslationSpec;
sendMessage(H.UPDATE_UI_TRANSLATION_STATE, args);
}
+
+ @Override
+ public void getExecutableMethodFileOffsets(
+ @NonNull MethodDescriptor methodDescriptor,
+ @NonNull IOffsetCallback resultCallback) {
+ Method method = MethodDescriptorParser.parseMethodDescriptor(
+ getClass().getClassLoader(), methodDescriptor);
+ VMDebug.ExecutableMethodFileOffsets location =
+ VMDebug.getExecutableMethodFileOffsets(method);
+ try {
+ if (location == null) {
+ resultCallback.onResult(null);
+ return;
+ }
+ ExecutableMethodFileOffsets ret = new ExecutableMethodFileOffsets();
+ ret.containerPath = location.getContainerPath();
+ ret.containerOffset = location.getContainerOffset();
+ ret.methodOffset = location.getMethodOffset();
+ resultCallback.onResult(ret);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
private @NonNull SafeCancellationTransport createSafeCancellationTransport(
@@ -3918,12 +3945,7 @@
if (mLastProcessState == processState) {
return;
}
- // Do not issue a transitional GC if we are transitioning between 2 cached states.
- // Only update if the state flips between cached and uncached or vice versa
- if (ActivityManager.isProcStateCached(mLastProcessState)
- != ActivityManager.isProcStateCached(processState)) {
- updateVmProcessState(processState);
- }
+ updateVmProcessState(mLastProcessState, processState);
mLastProcessState = processState;
if (localLOGV) {
Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
@@ -3932,18 +3954,21 @@
}
}
+ /** Converts a process state to a VM process state. */
+ private static int toVmProcessState(int processState) {
+ final int state = ActivityManager.isProcStateJankPerceptible(processState)
+ ? VM_PROCESS_STATE_JANK_PERCEPTIBLE
+ : VM_PROCESS_STATE_JANK_IMPERCEPTIBLE;
+ return state;
+ }
+
/** Update VM state based on ActivityManager.PROCESS_STATE_* constants. */
- // Currently ART VM only uses state updates for Transitional GC, and thus
- // this function initiates a Transitional GC for transitions into Cached apps states.
- private void updateVmProcessState(int processState) {
- // Only a transition into Cached state should result in a Transitional GC request
- // to the ART runtime. Update VM state to JANK_IMPERCEPTIBLE in that case.
- // Note that there are 4 possible cached states currently, all of which are
- // JANK_IMPERCEPTIBLE from GC point of view.
- final int state = ActivityManager.isProcStateCached(processState)
- ? VM_PROCESS_STATE_JANK_IMPERCEPTIBLE
- : VM_PROCESS_STATE_JANK_PERCEPTIBLE;
- VMRuntime.getRuntime().updateProcessState(state);
+ private void updateVmProcessState(int lastProcessState, int newProcessState) {
+ final int state = toVmProcessState(newProcessState);
+ if (lastProcessState == PROCESS_STATE_UNKNOWN
+ || state != toVmProcessState(lastProcessState)) {
+ VMRuntime.getRuntime().updateProcessState(state);
+ }
}
@Override
diff --git a/core/java/android/app/AppOpsManager.aidl b/core/java/android/app/AppOpsManager.aidl
index 56ed290..b4dee2e 100644
--- a/core/java/android/app/AppOpsManager.aidl
+++ b/core/java/android/app/AppOpsManager.aidl
@@ -19,7 +19,6 @@
parcelable AppOpsManager.PackageOps;
parcelable AppOpsManager.NoteOpEventProxyInfo;
parcelable AppOpsManager.NoteOpEvent;
-parcelable AppOpsManager.NotedOp;
parcelable AppOpsManager.OpFeatureEntry;
parcelable AppOpsManager.OpEntry;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index c789e28..1913812 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -262,24 +262,6 @@
private static final Object sLock = new Object();
- // A map that records noted times for each op.
- private final ArrayMap<NotedOp, Integer> mPendingNotedOps = new ArrayMap<>();
- private final HandlerThread mHandlerThread;
- private final Handler mHandler;
- private static final int NOTE_OP_BATCHING_DELAY_MILLIS = 1000;
-
- private boolean isNoteOpBatchingSupported() {
- // If noteOp is called from system server no IPC is made, hence we don't need batching.
- if (Process.myUid() == Process.SYSTEM_UID) {
- return false;
- }
- return Flags.noteOpBatchingEnabled();
- }
-
- private final Object mBatchedNoteOpLock = new Object();
- @GuardedBy("mBatchedNoteOpLock")
- private boolean mIsBatchedNoteOpCallScheduled = false;
-
/** Current {@link OnOpNotedCallback}. Change via {@link #setOnOpNotedCallback} */
@GuardedBy("sLock")
private static @Nullable OnOpNotedCallback sOnOpNotedCallback;
@@ -7484,135 +7466,6 @@
}
/**
- * A NotedOp is an app op grouped in noteOp API and sent to the system server in a batch
- *
- * @hide
- */
- public static final class NotedOp implements Parcelable {
- private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp;
- private final @IntRange(from = 0) int mUid;
- private final @Nullable String mPackageName;
- private final @Nullable String mAttributionTag;
- private final int mVirtualDeviceId;
- private final @Nullable String mMessage;
- private final boolean mShouldCollectAsyncNotedOp;
- private final boolean mShouldCollectMessage;
-
- public NotedOp(int op, int uid, @Nullable String packageName,
- @Nullable String attributionTag, int virtualDeviceId, @Nullable String message,
- boolean shouldCollectAsyncNotedOp, boolean shouldCollectMessage) {
- mOp = op;
- mUid = uid;
- mPackageName = packageName;
- mAttributionTag = attributionTag;
- mVirtualDeviceId = virtualDeviceId;
- mMessage = message;
- mShouldCollectAsyncNotedOp = shouldCollectAsyncNotedOp;
- mShouldCollectMessage = shouldCollectMessage;
- }
-
- NotedOp(Parcel source) {
- mOp = source.readInt();
- mUid = source.readInt();
- mPackageName = source.readString();
- mAttributionTag = source.readString();
- mVirtualDeviceId = source.readInt();
- mMessage = source.readString();
- mShouldCollectAsyncNotedOp = source.readBoolean();
- mShouldCollectMessage = source.readBoolean();
- }
-
- public int getOp() {
- return mOp;
- }
-
- public int getUid() {
- return mUid;
- }
-
- public @Nullable String getPackageName() {
- return mPackageName;
- }
-
- public @Nullable String getAttributionTag() {
- return mAttributionTag;
- }
-
- public int getVirtualDeviceId() {
- return mVirtualDeviceId;
- }
-
- public @Nullable String getMessage() {
- return mMessage;
- }
-
- public boolean getShouldCollectAsyncNotedOp() {
- return mShouldCollectAsyncNotedOp;
- }
-
- public boolean getShouldCollectMessage() {
- return mShouldCollectMessage;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mOp);
- dest.writeInt(mUid);
- dest.writeString(mPackageName);
- dest.writeString(mAttributionTag);
- dest.writeInt(mVirtualDeviceId);
- dest.writeString(mMessage);
- dest.writeBoolean(mShouldCollectAsyncNotedOp);
- dest.writeBoolean(mShouldCollectMessage);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- NotedOp that = (NotedOp) o;
- return mOp == that.mOp && mUid == that.mUid && Objects.equals(mPackageName,
- that.mPackageName) && Objects.equals(mAttributionTag, that.mAttributionTag)
- && mVirtualDeviceId == that.mVirtualDeviceId && Objects.equals(mMessage,
- that.mMessage) && Objects.equals(mShouldCollectAsyncNotedOp,
- that.mShouldCollectAsyncNotedOp) && Objects.equals(mShouldCollectMessage,
- that.mShouldCollectMessage);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(mOp, mUid, mPackageName, mAttributionTag, mVirtualDeviceId,
- mMessage, mShouldCollectAsyncNotedOp, mShouldCollectMessage);
- }
-
- @Override
- public String toString() {
- return "NotedOp{" + "mOp=" + mOp + ", mUid=" + mUid + ", mPackageName=" + mPackageName
- + ", mAttributionTag=" + mAttributionTag + ", mVirtualDeviceId="
- + mVirtualDeviceId + ", mMessage=" + mMessage + ", mShouldCollectAsyncNotedOp="
- + mShouldCollectAsyncNotedOp + ", mShouldCollectMessage="
- + mShouldCollectMessage + "}";
- }
-
-
- public static final @NonNull Creator<NotedOp> CREATOR =
- new Creator<>() {
- @Override public NotedOp createFromParcel(Parcel source) {
- return new NotedOp(source);
- }
-
- @Override public NotedOp[] newArray(int size) {
- return new NotedOp[size];
- }
- };
- }
-
- /**
* Computes the sum of the counts for the given flags in between the begin and
* end UID states.
*
@@ -8126,9 +7979,6 @@
AppOpsManager(Context context, IAppOpsService service) {
mContext = context;
mService = service;
- mHandlerThread = new HandlerThread("AppOpsManager");
- mHandlerThread.start();
- mHandler = mHandlerThread.getThreadHandler();
if (mContext != null) {
final PackageManager pm = mContext.getPackageManager();
@@ -9465,74 +9315,15 @@
}
}
- SyncNotedAppOp syncOp = null;
- boolean skipBinderCall = false;
- if (isNoteOpBatchingSupported()) {
- int mode = sAppOpModeCache.query(
- new AppOpModeQuery(op, uid, packageName, virtualDeviceId, attributionTag,
- "noteOpNoThrow"));
- // For FOREGROUND mode, we still need to make a binder call to the system service
- // to translate it to ALLOWED or IGNORED. So no batching is needed.
- if (mode != MODE_FOREGROUND) {
- synchronized (mBatchedNoteOpLock) {
- NotedOp notedOp = new NotedOp(op, uid, packageName, attributionTag,
- virtualDeviceId, message, collectionMode == COLLECT_ASYNC,
- shouldCollectMessage);
-
- // Batch same noteOp calls and send them with their counters to the system
- // service asynchronously. The time window for batching is specified in
- // NOTE_OP_BATCHING_DELAY_MILLIS. Always allow the first noteOp call to go
- // through binder API. Accumulate subsequent same noteOp calls during the
- // time window in mPendingNotedOps.
- if (!mPendingNotedOps.containsKey(notedOp)) {
- mPendingNotedOps.put(notedOp, 0);
- } else {
- skipBinderCall = true;
- mPendingNotedOps.merge(notedOp, 1, Integer::sum);
- }
-
- if (!mIsBatchedNoteOpCallScheduled) {
- mHandler.postDelayed(() -> {
- ArrayMap<NotedOp, Integer> pendingNotedOpsCopy;
- synchronized(mBatchedNoteOpLock) {
- mIsBatchedNoteOpCallScheduled = false;
- pendingNotedOpsCopy =
- new ArrayMap<NotedOp, Integer>(mPendingNotedOps);
- mPendingNotedOps.clear();
- }
- for (int i = pendingNotedOpsCopy.size() - 1; i >= 0; i--) {
- if (pendingNotedOpsCopy.valueAt(i) == 0) {
- pendingNotedOpsCopy.removeAt(i);
- }
- }
- if (!pendingNotedOpsCopy.isEmpty()) {
- try {
- mService.noteOperationsInBatch(pendingNotedOpsCopy);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }, NOTE_OP_BATCHING_DELAY_MILLIS);
-
- mIsBatchedNoteOpCallScheduled = true;
- }
- }
-
- syncOp = new SyncNotedAppOp(mode, op, attributionTag, packageName);
- }
+ SyncNotedAppOp syncOp;
+ if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) {
+ syncOp = mService.noteOperation(op, uid, packageName, attributionTag,
+ collectionMode == COLLECT_ASYNC, message, shouldCollectMessage);
+ } else {
+ syncOp = mService.noteOperationForDevice(op, uid, packageName, attributionTag,
+ virtualDeviceId, collectionMode == COLLECT_ASYNC, message,
+ shouldCollectMessage);
}
-
- if (!skipBinderCall) {
- if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) {
- syncOp = mService.noteOperation(op, uid, packageName, attributionTag,
- collectionMode == COLLECT_ASYNC, message, shouldCollectMessage);
- } else {
- syncOp = mService.noteOperationForDevice(op, uid, packageName, attributionTag,
- virtualDeviceId, collectionMode == COLLECT_ASYNC, message,
- shouldCollectMessage);
- }
- }
-
if (syncOp.getOpMode() == MODE_ALLOWED) {
if (collectionMode == COLLECT_SELF) {
collectNotedOpForSelf(syncOp);
diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java
index 8b7ea0f..b21defb 100644
--- a/core/java/android/app/AppOpsManagerInternal.java
+++ b/core/java/android/app/AppOpsManagerInternal.java
@@ -29,7 +29,7 @@
import com.android.internal.util.function.DodecFunction;
import com.android.internal.util.function.HexConsumer;
import com.android.internal.util.function.HexFunction;
-import com.android.internal.util.function.NonaFunction;
+import com.android.internal.util.function.OctFunction;
import com.android.internal.util.function.QuadFunction;
import com.android.internal.util.function.UndecFunction;
@@ -86,9 +86,9 @@
*/
SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
@Nullable String featureId, int virtualDeviceId, boolean shouldCollectAsyncNotedOp,
- @Nullable String message, boolean shouldCollectMessage, int notedCount,
- @NonNull NonaFunction<Integer, Integer, String, String, Integer, Boolean, String,
- Boolean, Integer, SyncNotedAppOp> superImpl);
+ @Nullable String message, boolean shouldCollectMessage,
+ @NonNull OctFunction<Integer, Integer, String, String, Integer, Boolean, String,
+ Boolean, SyncNotedAppOp> superImpl);
/**
* Allows overriding note proxy operation behavior.
diff --git a/core/java/android/app/BroadcastStickyCache.java b/core/java/android/app/BroadcastStickyCache.java
index fe2e107..1f62779 100644
--- a/core/java/android/app/BroadcastStickyCache.java
+++ b/core/java/android/app/BroadcastStickyCache.java
@@ -35,6 +35,7 @@
import android.util.ArrayMap;
import android.view.WindowManagerPolicyConstants;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
@@ -71,8 +72,10 @@
@VisibleForTesting
public static final ArrayMap<String, String> sActionApiNameMap = new ArrayMap<>();
+ @GuardedBy("BroadcastStickyCache.class")
private static final ArrayMap<String, IpcDataCache.Config> sActionConfigMap = new ArrayMap<>();
+ @GuardedBy("BroadcastStickyCache.class")
private static final ArrayMap<StickyBroadcastFilter, IpcDataCache<Void, Intent>>
sFilterCacheMap = new ArrayMap<>();
@@ -154,37 +157,44 @@
@Nullable String broadcastPermission,
@UserIdInt int userId,
@RegisterReceiverFlags int flags) {
- IpcDataCache<Void, Intent> intentDataCache = findIpcDataCache(filter);
+ IpcDataCache<Void, Intent> intentDataCache;
- if (intentDataCache == null) {
- final String action = filter.getAction(0);
- final StickyBroadcastFilter stickyBroadcastFilter =
- new StickyBroadcastFilter(filter, action);
- final Config config = getConfig(action);
+ synchronized (BroadcastStickyCache.class) {
+ intentDataCache = findIpcDataCache(filter);
- intentDataCache =
- new IpcDataCache<>(config,
- (query) -> ActivityManager.getService().registerReceiverWithFeature(
- applicationThread,
- mBasePackageName,
- attributionTag,
- /* receiverId= */ "null",
- /* receiver= */ null,
- filter,
- broadcastPermission,
- userId,
- flags));
- sFilterCacheMap.put(stickyBroadcastFilter, intentDataCache);
+ if (intentDataCache == null) {
+ final String action = filter.getAction(0);
+ final StickyBroadcastFilter stickyBroadcastFilter =
+ new StickyBroadcastFilter(filter, action);
+ final Config config = getConfig(action);
+
+ intentDataCache =
+ new IpcDataCache<>(config,
+ (query) -> ActivityManager.getService().registerReceiverWithFeature(
+ applicationThread,
+ mBasePackageName,
+ attributionTag,
+ /* receiverId= */ "null",
+ /* receiver= */ null,
+ filter,
+ broadcastPermission,
+ userId,
+ flags));
+ sFilterCacheMap.put(stickyBroadcastFilter, intentDataCache);
+ }
}
return intentDataCache.query(null);
}
@VisibleForTesting
public static void clearCacheForTest() {
- sFilterCacheMap.clear();
+ synchronized (BroadcastStickyCache.class) {
+ sFilterCacheMap.clear();
+ }
}
@Nullable
+ @GuardedBy("BroadcastStickyCache.class")
private static IpcDataCache<Void, Intent> findIpcDataCache(
@NonNull IntentFilter filter) {
for (int i = sFilterCacheMap.size() - 1; i >= 0; i--) {
@@ -198,12 +208,14 @@
}
@NonNull
+ @GuardedBy("BroadcastStickyCache.class")
private static IpcDataCache.Config getConfig(@NonNull String action) {
if (!sActionConfigMap.containsKey(action)) {
// We only need 1 entry per cache but just to be on the safer side we are choosing 32
// although we don't expect more than 1.
sActionConfigMap.put(action,
- new Config(32, IpcDataCache.MODULE_SYSTEM, sActionApiNameMap.get(action)));
+ new Config(32, IpcDataCache.MODULE_SYSTEM,
+ sActionApiNameMap.get(action)).cacheNulls(true));
}
return sActionConfigMap.get(action);
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 06d01ec..063501b 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -46,6 +46,8 @@
import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.SharedMemory;
+import android.os.instrumentation.IOffsetCallback;
+import android.os.instrumentation.MethodDescriptor;
import android.view.autofill.AutofillId;
import android.view.translation.TranslationSpec;
import android.view.translation.UiTranslationSpec;
@@ -183,4 +185,6 @@
void scheduleTimeoutService(IBinder token, int startId);
void scheduleTimeoutServiceForType(IBinder token, int startId, int fgsType);
void schedulePing(in RemoteCallback pong);
+ void getExecutableMethodFileOffsets(in MethodDescriptor methodDescriptor,
+ in IOffsetCallback resultCallback);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 7e998d9..f2d6c6a 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -14839,10 +14839,7 @@
if (isColorized) {
if (rawColor == COLOR_DEFAULT) {
- int[] attrs = {R.attr.materialColorSecondary};
- try (TypedArray ta = obtainDayNightAttributes(ctx, attrs)) {
- mBackgroundColor = getColor(ta, 0, Color.WHITE);
- }
+ mBackgroundColor = ctx.getColor(R.color.materialColorSecondary);
} else {
mBackgroundColor = rawColor;
}
@@ -14874,30 +14871,25 @@
mRippleAlpha = 0x33;
} else {
int[] attrs = {
- R.attr.materialColorSurfaceContainerHigh,
- R.attr.materialColorOnSurface,
- R.attr.materialColorOnSurfaceVariant,
- R.attr.materialColorPrimary,
- R.attr.materialColorSecondary,
- R.attr.materialColorTertiary,
- R.attr.materialColorOnTertiary,
- R.attr.materialColorTertiaryFixedDim,
- R.attr.materialColorOnTertiaryFixed,
R.attr.colorError,
R.attr.colorControlHighlight
};
+
+ mBackgroundColor = ctx.getColor(R.color.materialColorSurfaceContainerHigh);
+ mPrimaryTextColor = ctx.getColor(R.color.materialColorOnSurface);
+ mSecondaryTextColor = ctx.getColor(R.color.materialColorOnSurfaceVariant);
+ mPrimaryAccentColor = ctx.getColor(R.color.materialColorPrimary);
+ mSecondaryAccentColor = ctx.getColor(R.color.materialColorSecondary);
+ mTertiaryAccentColor = ctx.getColor(R.color.materialColorTertiary);
+ mOnTertiaryAccentTextColor = ctx.getColor(R.color.materialColorOnTertiary);
+ mTertiaryFixedDimAccentColor = ctx.getColor(
+ R.color.materialColorTertiaryFixedDim);
+ mOnTertiaryFixedAccentTextColor = ctx.getColor(
+ R.color.materialColorOnTertiaryFixed);
+
try (TypedArray ta = obtainDayNightAttributes(ctx, attrs)) {
- mBackgroundColor = getColor(ta, 0, nightMode ? Color.BLACK : Color.WHITE);
- mPrimaryTextColor = getColor(ta, 1, COLOR_INVALID);
- mSecondaryTextColor = getColor(ta, 2, COLOR_INVALID);
- mPrimaryAccentColor = getColor(ta, 3, COLOR_INVALID);
- mSecondaryAccentColor = getColor(ta, 4, COLOR_INVALID);
- mTertiaryAccentColor = getColor(ta, 5, COLOR_INVALID);
- mOnTertiaryAccentTextColor = getColor(ta, 6, COLOR_INVALID);
- mTertiaryFixedDimAccentColor = getColor(ta, 7, COLOR_INVALID);
- mOnTertiaryFixedAccentTextColor = getColor(ta, 8, COLOR_INVALID);
- mErrorColor = getColor(ta, 9, COLOR_INVALID);
- mRippleAlpha = Color.alpha(getColor(ta, 10, 0x33ffffff));
+ mErrorColor = getColor(ta, 0, COLOR_INVALID);
+ mRippleAlpha = Color.alpha(getColor(ta, 1, 0x33ffffff));
}
mContrastColor = calculateContrastColor(ctx, rawColor, mPrimaryAccentColor,
mBackgroundColor, nightMode);
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 87c8619..8ed66eb 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -49,7 +49,6 @@
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
-import android.os.Handler;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -61,15 +60,18 @@
import android.provider.Settings.Global;
import android.service.notification.Adjustment;
import android.service.notification.Condition;
+import android.service.notification.RateEstimator;
import android.service.notification.StatusBarNotification;
import android.service.notification.ZenDeviceEffects;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;
import android.util.Log;
+import android.util.LruCache;
import android.util.proto.ProtoOutputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.time.InstantSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -643,9 +645,17 @@
*/
public static int MAX_SERVICE_COMPONENT_NAME_LENGTH = 500;
+ private static final float MAX_NOTIFICATION_ENQUEUE_RATE = 5f;
+
+ private final Context mContext;
private final Map<CallNotificationEventListener, CallNotificationEventCallbackStub>
mCallNotificationEventCallbacks = new HashMap<>();
+ private final InstantSource mClock;
+ private final RateEstimator mEnqueueRateEstimator = new RateEstimator();
+ private final LruCache<String, Boolean> mEnqueuedNotificationKeys = new LruCache<>(10);
+ private final Object mEnqueueThrottleLock = new Object();
+
@UnsupportedAppUsage
private static INotificationManager sService;
@@ -661,10 +671,17 @@
return sService;
}
+ /** @hide */
+ protected INotificationManager service() {
+ return getService();
+ }
+
+ /** {@hide} */
@UnsupportedAppUsage
- /*package*/ NotificationManager(Context context, Handler handler)
+ public NotificationManager(Context context, InstantSource clock)
{
mContext = context;
+ mClock = clock;
}
/** {@hide} */
@@ -736,7 +753,7 @@
*/
public void notifyAsPackage(@NonNull String targetPackage, @Nullable String tag, int id,
@NonNull Notification notification) {
- INotificationManager service = getService();
+ INotificationManager service = service();
String sender = mContext.getPackageName();
try {
@@ -752,13 +769,12 @@
* @hide
*/
@UnsupportedAppUsage
- public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
+ public void notifyAsUser(@Nullable String tag, int id, Notification notification,
+ UserHandle user)
{
- INotificationManager service = getService();
+ INotificationManager service = service();
String pkg = mContext.getPackageName();
-
- if (notificationClassification()
- && NotificationChannel.SYSTEM_RESERVED_IDS.contains(notification.getChannelId())) {
+ if (discardNotify(tag, id, notification)) {
return;
}
@@ -771,6 +787,37 @@
}
}
+ /**
+ * Determines whether a {@link #notify} call should be skipped. If the notification is not
+ * skipped, updates tracking metadata to use in future decisions.
+ */
+ private boolean discardNotify(@Nullable String tag, int id, Notification notification) {
+ if (notificationClassification()
+ && NotificationChannel.SYSTEM_RESERVED_IDS.contains(notification.getChannelId())) {
+ return true;
+ }
+
+ if (Flags.nmBinderPerfThrottleNotify()) {
+ String key = toEnqueuedNotificationKey(tag, id);
+ long now = mClock.millis();
+ synchronized (mEnqueueThrottleLock) {
+ if (mEnqueuedNotificationKeys.get(key) != null
+ && !notification.hasCompletedProgress()
+ && mEnqueueRateEstimator.getRate(now) > MAX_NOTIFICATION_ENQUEUE_RATE) {
+ return true;
+ }
+
+ mEnqueueRateEstimator.update(now);
+ mEnqueuedNotificationKeys.put(key, Boolean.TRUE);
+ }
+ }
+
+ return false;
+ }
+ private static String toEnqueuedNotificationKey(@Nullable String tag, int id) {
+ return tag + "," + id;
+ }
+
private Notification fixNotification(Notification notification) {
String pkg = mContext.getPackageName();
// Fix the notification as best we can.
@@ -852,7 +899,7 @@
* @param id An identifier for this notification.
*/
public void cancelAsPackage(@NonNull String targetPackage, @Nullable String tag, int id) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.cancelNotificationWithTag(targetPackage, mContext.getOpPackageName(),
tag, id, mContext.getUser().getIdentifier());
@@ -865,9 +912,15 @@
* @hide
*/
@UnsupportedAppUsage
- public void cancelAsUser(String tag, int id, UserHandle user)
+ public void cancelAsUser(@Nullable String tag, int id, UserHandle user)
{
- INotificationManager service = getService();
+ if (Flags.nmBinderPerfThrottleNotify()) {
+ synchronized (mEnqueueThrottleLock) {
+ mEnqueuedNotificationKeys.remove(toEnqueuedNotificationKey(tag, id));
+ }
+ }
+
+ INotificationManager service = service();
String pkg = mContext.getPackageName();
if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
try {
@@ -884,7 +937,13 @@
*/
public void cancelAll()
{
- INotificationManager service = getService();
+ if (Flags.nmBinderPerfThrottleNotify()) {
+ synchronized (mEnqueueThrottleLock) {
+ mEnqueuedNotificationKeys.evictAll();
+ }
+ }
+
+ INotificationManager service = service();
String pkg = mContext.getPackageName();
if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
try {
@@ -907,7 +966,7 @@
* @param delegate Package name of the app which can send notifications on your behalf.
*/
public void setNotificationDelegate(@Nullable String delegate) {
- INotificationManager service = getService();
+ INotificationManager service = service();
String pkg = mContext.getPackageName();
if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
try {
@@ -922,7 +981,7 @@
* your behalf, if there currently is one.
*/
public @Nullable String getNotificationDelegate() {
- INotificationManager service = getService();
+ INotificationManager service = service();
String pkg = mContext.getPackageName();
try {
return service.getNotificationDelegate(pkg);
@@ -938,7 +997,7 @@
* See {@link #setNotificationDelegate(String)}.
*/
public boolean canNotifyAsPackage(@NonNull String pkg) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.canNotifyAsPackage(mContext.getPackageName(), pkg, mContext.getUserId());
} catch (RemoteException e) {
@@ -956,7 +1015,7 @@
* {@link android.provider.Settings#ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT}.
*/
public boolean canUseFullScreenIntent() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.canUseFullScreenIntent(mContext.getAttributionSource());
} catch (RemoteException e) {
@@ -974,7 +1033,7 @@
*/
@FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
public boolean canPostPromotedNotifications() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.canBePromoted(mContext.getPackageName());
} catch (RemoteException e) {
@@ -989,7 +1048,7 @@
@TestApi
@FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
public void setCanPostPromotedNotifications(@NonNull String pkg, int uid, boolean allowed) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setCanBePromoted(pkg, uid, allowed, true);
} catch (RemoteException e) {
@@ -1024,7 +1083,7 @@
* @param groups The list of groups to create
*/
public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.createNotificationChannelGroups(mContext.getPackageName(),
new ParceledListSlice(groups));
@@ -1067,7 +1126,7 @@
* @param channels the list of channels to attempt to create.
*/
public void createNotificationChannels(@NonNull List<NotificationChannel> channels) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.createNotificationChannels(mContext.getPackageName(),
new ParceledListSlice(channels));
@@ -1085,7 +1144,7 @@
* package (see {@link Context#createPackageContext(String, int)}).</p>
*/
public NotificationChannel getNotificationChannel(String channelId) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getNotificationChannel(mContext.getOpPackageName(),
mContext.getUserId(), mContext.getPackageName(), channelId);
@@ -1105,7 +1164,7 @@
*/
public @Nullable NotificationChannel getNotificationChannel(@NonNull String channelId,
@NonNull String conversationId) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getConversationNotificationChannel(mContext.getOpPackageName(),
mContext.getUserId(), mContext.getPackageName(), channelId, true,
@@ -1124,7 +1183,7 @@
* {@link Context#createPackageContext(String, int)}).</p>
*/
public List<NotificationChannel> getNotificationChannels() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getNotificationChannels(mContext.getOpPackageName(),
mContext.getPackageName(), mContext.getUserId()).getList();
@@ -1145,7 +1204,7 @@
&& NotificationChannel.SYSTEM_RESERVED_IDS.contains(channelId)) {
return;
}
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.deleteNotificationChannel(mContext.getPackageName(), channelId);
} catch (RemoteException e) {
@@ -1159,7 +1218,7 @@
* The channel group must belong to your package, or null will be returned.
*/
public NotificationChannelGroup getNotificationChannelGroup(String channelGroupId) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getNotificationChannelGroup(mContext.getPackageName(), channelGroupId);
} catch (RemoteException e) {
@@ -1171,7 +1230,7 @@
* Returns all notification channel groups belonging to the calling app.
*/
public List<NotificationChannelGroup> getNotificationChannelGroups() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
final ParceledListSlice<NotificationChannelGroup> parceledList =
service.getNotificationChannelGroups(mContext.getPackageName());
@@ -1189,7 +1248,7 @@
* belong to it.
*/
public void deleteNotificationChannelGroup(String groupId) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId);
} catch (RemoteException e) {
@@ -1203,7 +1262,7 @@
@TestApi
public void updateNotificationChannel(@NonNull String pkg, int uid,
@NonNull NotificationChannel channel) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.updateNotificationChannelForPackage(pkg, uid, channel);
} catch (RemoteException e) {
@@ -1216,7 +1275,7 @@
*/
@TestApi
public ComponentName getEffectsSuppressor() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getEffectsSuppressor();
} catch (RemoteException e) {
@@ -1228,7 +1287,7 @@
* @hide
*/
public boolean matchesCallFilter(Bundle extras) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.matchesCallFilter(extras);
} catch (RemoteException e) {
@@ -1241,7 +1300,7 @@
*/
@TestApi
public void cleanUpCallersAfter(long timeThreshold) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.cleanUpCallersAfter(timeThreshold);
} catch (RemoteException e) {
@@ -1253,7 +1312,7 @@
* @hide
*/
public boolean isSystemConditionProviderEnabled(String path) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.isSystemConditionProviderEnabled(path);
} catch (RemoteException e) {
@@ -1271,7 +1330,7 @@
/** @hide */
public void setZenMode(int mode, Uri conditionId, String reason, boolean fromUser) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setZenMode(mode, conditionId, reason, fromUser);
} catch (RemoteException e) {
@@ -1284,7 +1343,7 @@
* @hide
*/
public int getZenMode() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getZenMode();
} catch (RemoteException e) {
@@ -1297,7 +1356,7 @@
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public ZenModeConfig getZenModeConfig() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getZenModeConfig();
} catch (RemoteException e) {
@@ -1315,7 +1374,7 @@
* </p>
*/
public @NonNull NotificationManager.Policy getConsolidatedNotificationPolicy() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getConsolidatedNotificationPolicy();
} catch (RemoteException e) {
@@ -1327,7 +1386,7 @@
* @hide
*/
public int getRuleInstanceCount(ComponentName owner) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getRuleInstanceCount(owner);
} catch (RemoteException e) {
@@ -1364,7 +1423,7 @@
* See {@link #isNotificationPolicyAccessGranted}.
*/
public Map<String, AutomaticZenRule> getAutomaticZenRules() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
if (Flags.modesApi()) {
return service.getAutomaticZenRules();
@@ -1398,7 +1457,7 @@
* doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}.
*/
public AutomaticZenRule getAutomaticZenRule(String id) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getAutomaticZenRule(id);
} catch (RemoteException e) {
@@ -1426,7 +1485,7 @@
@NonNull
public String addAutomaticZenRule(@NonNull AutomaticZenRule automaticZenRule,
boolean fromUser) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.addAutomaticZenRule(automaticZenRule,
mContext.getPackageName(), fromUser);
@@ -1461,7 +1520,7 @@
@FlaggedApi(Flags.FLAG_MODES_API)
public boolean updateAutomaticZenRule(@NonNull String id,
@NonNull AutomaticZenRule automaticZenRule, boolean fromUser) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.updateAutomaticZenRule(id, automaticZenRule, fromUser);
} catch (RemoteException e) {
@@ -1481,7 +1540,7 @@
@FlaggedApi(Flags.FLAG_MODES_API)
@Condition.State
public int getAutomaticZenRuleState(@NonNull String id) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getAutomaticZenRuleState(id);
} catch (RemoteException e) {
@@ -1527,7 +1586,7 @@
* @param condition The new state of this rule
*/
public void setAutomaticZenRuleState(@NonNull String id, @NonNull Condition condition) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setAutomaticZenRuleState(id, condition);
} catch (RemoteException e) {
@@ -1555,7 +1614,7 @@
@TestApi
@FlaggedApi(Flags.FLAG_MODES_API)
public boolean removeAutomaticZenRule(@NonNull String id, boolean fromUser) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.removeAutomaticZenRule(id, fromUser);
} catch (RemoteException e) {
@@ -1574,7 +1633,7 @@
/** @hide */
public boolean removeAutomaticZenRules(String packageName, boolean fromUser) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.removeAutomaticZenRules(packageName, fromUser);
} catch (RemoteException e) {
@@ -1587,7 +1646,7 @@
* package.
*/
public @Importance int getImportance() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getPackageImportance(mContext.getPackageName());
} catch (RemoteException e) {
@@ -1602,7 +1661,7 @@
if (Flags.nmBinderPerfPermissionCheck()) {
return mContext.checkSelfPermission(POST_NOTIFICATIONS) == PERMISSION_GRANTED;
} else {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.areNotificationsEnabled(mContext.getPackageName());
} catch (RemoteException e) {
@@ -1623,7 +1682,7 @@
*/
@Deprecated
public boolean areBubblesAllowed() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.areBubblesAllowed(mContext.getPackageName());
} catch (RemoteException e) {
@@ -1638,7 +1697,7 @@
* @see Notification.Builder#setBubbleMetadata(Notification.BubbleMetadata)
*/
public boolean areBubblesEnabled() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.areBubblesEnabled(mContext.getUser());
} catch (RemoteException e) {
@@ -1665,7 +1724,7 @@
* @return the users' bubble preference for the app.
*/
public @BubblePreference int getBubblePreference() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getBubblePreferenceForPackage(mContext.getPackageName(),
Binder.getCallingUid());
@@ -1685,7 +1744,7 @@
* @hide
*/
public void silenceNotificationSound() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.silenceNotificationSound();
} catch (RemoteException e) {
@@ -1701,7 +1760,7 @@
* PersistableBundle, SuspendDialogInfo) suspended}.
*/
public boolean areNotificationsPaused() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.isPackagePaused(mContext.getPackageName());
} catch (RemoteException e) {
@@ -1724,7 +1783,7 @@
* user grant or denial of this access.
*/
public boolean isNotificationPolicyAccessGranted() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1745,7 +1804,7 @@
* {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}.
*/
public boolean isNotificationListenerAccessGranted(ComponentName listener) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.isNotificationListenerAccessGranted(listener);
} catch (RemoteException e) {
@@ -1769,7 +1828,7 @@
*/
@SystemApi
public boolean isNotificationAssistantAccessGranted(@NonNull ComponentName assistant) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.isNotificationAssistantAccessGranted(assistant);
} catch (RemoteException e) {
@@ -1785,7 +1844,7 @@
* listeners}.
*/
public boolean shouldHideSilentStatusBarIcons() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.shouldHideSilentStatusIcons(mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1804,7 +1863,7 @@
*/
@SystemApi
public @NonNull @Adjustment.Keys List<String> getAllowedAssistantAdjustments() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getAllowedAssistantAdjustments(mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1818,7 +1877,7 @@
@TestApi
@FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
public void allowAssistantAdjustment(@NonNull String capability) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.allowAssistantAdjustment(capability);
} catch (RemoteException e) {
@@ -1832,7 +1891,7 @@
@TestApi
@FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
public void disallowAssistantAdjustment(@NonNull String capability) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.disallowAssistantAdjustment(capability);
} catch (RemoteException e) {
@@ -1843,7 +1902,7 @@
/** @hide */
@TestApi
public boolean isNotificationPolicyAccessGrantedForPackage(@NonNull String pkg) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.isNotificationPolicyAccessGrantedForPackage(pkg);
} catch (RemoteException e) {
@@ -1857,7 +1916,7 @@
@TestApi
@FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
public void setAssistantAdjustmentKeyTypeState(@Adjustment.Types int type, boolean enabled) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setAssistantAdjustmentKeyTypeState(type, enabled);
} catch (RemoteException e) {
@@ -1870,7 +1929,7 @@
*/
@FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
public void setTypeAdjustmentForPackageState(@NonNull String pkg, boolean enabled) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setTypeAdjustmentForPackageState(pkg, enabled);
} catch (RemoteException e) {
@@ -1882,7 +1941,7 @@
* @hide
*/
public List<String> getEnabledNotificationListenerPackages() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getEnabledNotificationListenerPackages();
} catch (RemoteException e) {
@@ -1899,7 +1958,7 @@
* {@link #setNotificationPolicy(Policy)}.
*/
public Policy getNotificationPolicy() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getNotificationPolicy(mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1929,7 +1988,7 @@
/** @hide */
public void setNotificationPolicy(@NonNull Policy policy, boolean fromUser) {
checkRequired("policy", policy);
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setNotificationPolicy(mContext.getOpPackageName(), policy, fromUser);
} catch (RemoteException e) {
@@ -1939,7 +1998,7 @@
/** @hide */
public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setNotificationPolicyAccessGranted(pkg, granted);
} catch (RemoteException e) {
@@ -1959,7 +2018,7 @@
@TestApi
@FlaggedApi(Flags.FLAG_MODES_API)
public @NonNull ZenPolicy getDefaultZenPolicy() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getDefaultZenPolicy();
} catch (RemoteException e) {
@@ -1971,7 +2030,7 @@
*/
@FlaggedApi(Flags.FLAG_MODES_UI)
public void setManualZenRuleDeviceEffects(@NonNull ZenDeviceEffects effects) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setManualZenRuleDeviceEffects(effects);
} catch (RemoteException e) {
@@ -2008,7 +2067,7 @@
@RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS)
public void setNotificationListenerAccessGranted(
@NonNull ComponentName listener, boolean granted, boolean userSet) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
if (CompatChanges.isChangeEnabled(SET_LISTENER_ACCESS_GRANTED_IS_USER_AWARE)) {
service.setNotificationListenerAccessGrantedForUser(listener, mContext.getUserId(),
@@ -2024,7 +2083,7 @@
/** @hide */
public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId,
boolean granted) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setNotificationListenerAccessGrantedForUser(listener, userId, granted, true);
} catch (RemoteException e) {
@@ -2045,7 +2104,7 @@
@SystemApi
public void setNotificationAssistantAccessGranted(@Nullable ComponentName assistant,
boolean granted) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setNotificationAssistantAccessGranted(assistant, granted);
} catch (RemoteException e) {
@@ -2069,7 +2128,7 @@
/** @hide */
public List<ComponentName> getEnabledNotificationListeners(int userId) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getEnabledNotificationListeners(userId);
} catch (RemoteException e) {
@@ -2080,7 +2139,7 @@
/** @hide */
@SystemApi
public @Nullable ComponentName getAllowedNotificationAssistant() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getAllowedNotificationAssistant();
} catch (RemoteException e) {
@@ -2100,16 +2159,13 @@
@SuppressLint("UserHandle")
public boolean hasEnabledNotificationListener(@NonNull String packageName,
@NonNull UserHandle userHandle) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.hasEnabledNotificationListener(packageName, userHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
-
- private Context mContext;
-
private static void checkRequired(String name, Object value) {
if (value == null) {
throw new IllegalArgumentException(name + " is required");
@@ -2125,7 +2181,7 @@
@TestApi
@RequiresPermission(android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING)
public void setToastRateLimitingEnabled(boolean enable) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setToastRateLimitingEnabled(enable);
} catch (RemoteException e) {
@@ -2917,7 +2973,7 @@
* @return An array of {@link StatusBarNotification}.
*/
public StatusBarNotification[] getActiveNotifications() {
- final INotificationManager service = getService();
+ final INotificationManager service = service();
final String pkg = mContext.getPackageName();
try {
final ParceledListSlice<StatusBarNotification> parceledList
@@ -2940,7 +2996,7 @@
* globally.
*/
public final @InterruptionFilter int getCurrentInterruptionFilter() {
- final INotificationManager service = getService();
+ final INotificationManager service = service();
try {
return zenModeToInterruptionFilter(service.getZenMode());
} catch (RemoteException e) {
@@ -2972,7 +3028,7 @@
/** @hide */
public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter,
boolean fromUser) {
- final INotificationManager service = getService();
+ final INotificationManager service = service();
try {
service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter,
fromUser);
@@ -3130,7 +3186,7 @@
checkRequired("userHandle", userHandle);
checkRequired("executor", executor);
checkRequired("listener", listener);
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
synchronized (mCallNotificationEventCallbacks) {
CallNotificationEventCallbackStub callbackStub =
@@ -3161,7 +3217,7 @@
public void unregisterCallNotificationEventListener(
@NonNull CallNotificationEventListener listener) {
checkRequired("listener", listener);
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
synchronized (mCallNotificationEventCallbacks) {
CallNotificationEventCallbackStub callbackStub =
@@ -3184,7 +3240,7 @@
@TestApi
@FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
public @NonNull Set<String> getUnsupportedAdjustmentTypes() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return new HashSet<>(service.getUnsupportedAdjustmentTypes());
} catch (RemoteException e) {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 248e0433..920b19c 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -289,6 +289,7 @@
import com.android.internal.policy.PhoneLayoutInflater;
import com.android.internal.util.Preconditions;
+import java.time.InstantSource;
import java.util.Map;
import java.util.Objects;
@@ -625,7 +626,7 @@
com.android.internal.R.style.Theme_Holo_Dialog,
com.android.internal.R.style.Theme_DeviceDefault_Dialog,
com.android.internal.R.style.Theme_DeviceDefault_Light_Dialog)),
- ctx.mMainThread.getHandler());
+ InstantSource.system());
}});
registerService(Context.PEOPLE_SERVICE, PeopleManager.class,
diff --git a/core/java/android/app/activity_manager.aconfig b/core/java/android/app/activity_manager.aconfig
index bea3010..720e045 100644
--- a/core/java/android/app/activity_manager.aconfig
+++ b/core/java/android/app/activity_manager.aconfig
@@ -156,3 +156,10 @@
bug: "362537357"
is_exported: true
}
+
+flag {
+ name: "jank_perceptible_narrow"
+ namespace: "system_performance"
+ description: "Narrow the scope of Jank Perceptible"
+ bug: "304837972"
+}
diff --git a/core/java/android/app/jank/JankDataProcessor.java b/core/java/android/app/jank/JankDataProcessor.java
index 7ceaeb3..c947259 100644
--- a/core/java/android/app/jank/JankDataProcessor.java
+++ b/core/java/android/app/jank/JankDataProcessor.java
@@ -215,7 +215,8 @@
try {
mPendingJankStats.values().forEach(stat -> {
- FrameworkStatsLog.write(FrameworkStatsLog.JANK_FRAME_COUNT_BY_WIDGET,
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.JANK_FRAME_COUNT_BY_WIDGET_REPORTED,
/*app uid*/ stat.getUid(),
/*activity name*/ stat.getActivityName(),
/*widget id*/ stat.getWidgetId(),
diff --git a/core/java/android/app/jank/JankTracker.java b/core/java/android/app/jank/JankTracker.java
index 4695216..a04f96a 100644
--- a/core/java/android/app/jank/JankTracker.java
+++ b/core/java/android/app/jank/JankTracker.java
@@ -29,6 +29,7 @@
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
+import java.util.HashMap;
/**
* This class is responsible for registering callbacks that will receive JankData batches.
@@ -174,6 +175,15 @@
}
/**
+ * Retrieve all pending jank stats before they are logged, this is intended for testing
+ * purposes only.
+ */
+ @VisibleForTesting
+ public HashMap<String, JankDataProcessor.PendingJankStat> getPendingJankStats() {
+ return mJankDataProcessor.getPendingJankStats();
+ }
+
+ /**
* Only intended to be used by tests, the runnable that registers the listeners may not run
* in time for tests to pass. This forces them to run immediately.
*/
@@ -192,7 +202,11 @@
*/
}
- private boolean shouldTrack() {
+ /**
+ * Returns whether jank tracking is enabled or not.
+ */
+ @VisibleForTesting
+ public boolean shouldTrack() {
return mTrackingEnabled && mListenersRegistered;
}
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index 7543fa9..b1db137 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -291,6 +291,13 @@
}
flag {
+ name: "nm_binder_perf_throttle_notify"
+ namespace: "systemui"
+ description: "Rate-limit calls to enqueueNotificationWithTag client-side"
+ bug: "362981561"
+}
+
+flag {
name: "no_sbnholder"
namespace: "systemui"
description: "removes sbnholder from NLS"
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 40de298..67ad459 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -37,36 +37,44 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.Intent.FilterComparison;
import android.content.IntentSender;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.graphics.Rect;
+import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.HandlerThread;
+import android.os.IBinder;
import android.os.Looper;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.util.ArrayMap;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.Pair;
import android.widget.RemoteViews;
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FunctionalUtils;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
+import java.util.function.Consumer;
/**
* Updates AppWidget state; gets information about installed AppWidget providers and other
@@ -592,6 +600,8 @@
private boolean mHasPostedLegacyLists = false;
+ private @NonNull ServiceCollectionCache mServiceCollectionCache;
+
/**
* Get the AppWidgetManager instance to use for the supplied {@link android.content.Context
* Context} object.
@@ -612,6 +622,7 @@
mPackageName = context.getOpPackageName();
mService = service;
mDisplayMetrics = context.getResources().getDisplayMetrics();
+ mServiceCollectionCache = new ServiceCollectionCache(context, /* timeout= */ 5000L);
if (mService == null) {
return;
}
@@ -649,7 +660,7 @@
final RemoteViews viewsCopy = new RemoteViews(original);
Runnable updateWidgetWithTask = () -> {
try {
- viewsCopy.collectAllIntents(mMaxBitmapMemory).get();
+ viewsCopy.collectAllIntents(mMaxBitmapMemory, mServiceCollectionCache).get();
action.acceptOrThrow(viewsCopy);
} catch (Exception e) {
Log.e(TAG, failureMsg, e);
@@ -1629,4 +1640,106 @@
thread.start();
return thread.getThreadHandler();
}
+
+ /**
+ * @hide
+ */
+ public static class ServiceCollectionCache {
+
+ private final Context mContext;
+ private final Handler mHandler;
+ private final long mTimeOut;
+
+ private final Map<FilterComparison, ConnectionTask> mActiveConnections =
+ new ArrayMap<>();
+
+ public ServiceCollectionCache(Context context, long timeOut) {
+ mContext = context;
+ mHandler = new Handler(BackgroundThread.getHandler().getLooper());
+ mTimeOut = timeOut;
+ }
+
+ /**
+ * Connect to the service indicated by the {@code Intent}, and consume the binder on the
+ * specified executor
+ */
+ public void connectAndConsume(Intent intent, Consumer<IBinder> task, Executor executor) {
+ mHandler.post(() -> connectAndConsumeInner(intent, task, executor));
+ }
+
+ private void connectAndConsumeInner(Intent intent, Consumer<IBinder> task,
+ Executor executor) {
+ ConnectionTask activeConnection = mActiveConnections.computeIfAbsent(
+ new FilterComparison(intent), ConnectionTask::new);
+ activeConnection.add(task, executor);
+ }
+
+ private class ConnectionTask implements ServiceConnection {
+
+ private final Runnable mDestroyAfterTimeout = this::onDestroyTimeout;
+ private final ArrayDeque<Pair<Consumer<IBinder>, Executor>> mTaskQueue =
+ new ArrayDeque<>();
+
+ private boolean mOnDestroyTimeout = false;
+ private IBinder mIBinder;
+
+ ConnectionTask(@NonNull FilterComparison filter) {
+ mContext.bindService(filter.getIntent(),
+ Context.BindServiceFlags.of(Context.BIND_AUTO_CREATE),
+ mHandler::post,
+ this);
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
+ mIBinder = iBinder;
+ mHandler.post(this::handleNext);
+ }
+
+ @Override
+ public void onNullBinding(ComponentName name) {
+ // Use an empty binder, follow up tasks will handle the failure
+ onServiceConnected(name, new Binder());
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName componentName) { }
+
+ void add(Consumer<IBinder> task, Executor executor) {
+ mTaskQueue.add(Pair.create(task, executor));
+ if (mOnDestroyTimeout) {
+ // If we are waiting for timeout, cancel it and execute the next task
+ handleNext();
+ }
+ }
+
+ private void handleNext() {
+ mHandler.removeCallbacks(mDestroyAfterTimeout);
+ Pair<Consumer<IBinder>, Executor> next = mTaskQueue.pollFirst();
+ if (next != null) {
+ mOnDestroyTimeout = false;
+ next.second.execute(() -> {
+ next.first.accept(mIBinder);
+ mHandler.post(this::handleNext);
+ });
+ } else {
+ // Finished all tasks, start a timeout to unbind this service
+ mOnDestroyTimeout = true;
+ mHandler.postDelayed(mDestroyAfterTimeout, mTimeOut);
+ }
+ }
+
+ /**
+ * Called after we have waited for {@link #mTimeOut} after the last task is finished
+ */
+ private void onDestroyTimeout() {
+ if (!mTaskQueue.isEmpty()) {
+ handleNext();
+ return;
+ }
+ mContext.unbindService(this);
+ mActiveConnections.values().remove(this);
+ }
+ }
+ }
}
diff --git a/core/java/android/companion/DeviceId.java b/core/java/android/companion/DeviceId.java
index f66a1ae..2f19eb4 100644
--- a/core/java/android/companion/DeviceId.java
+++ b/core/java/android/companion/DeviceId.java
@@ -22,7 +22,6 @@
import android.net.MacAddress;
import android.os.Parcel;
import android.os.Parcelable;
-import android.provider.OneTimeUseBuilder;
import java.util.Locale;
import java.util.Objects;
@@ -154,8 +153,12 @@
/**
* A builder for {@link DeviceId}
+ *
+ * <p>Calling apps must provide at least one of the following to identify
+ * the device: a custom ID using {@link #setCustomId(String)}, or a MAC address using
+ * {@link #setMacAddress(MacAddress)}.</p>
*/
- public static final class Builder extends OneTimeUseBuilder<DeviceId> {
+ public static final class Builder {
private String mCustomId;
private MacAddress mMacAddress;
@@ -171,7 +174,6 @@
*/
@NonNull
public Builder setCustomId(@Nullable String customId) {
- checkNotUsed();
if (customId != null
&& customId.length() > CUSTOM_ID_LENGTH_LIMIT) {
throw new IllegalArgumentException("Length of the custom id must be at most "
@@ -191,15 +193,12 @@
*/
@NonNull
public Builder setMacAddress(@Nullable MacAddress macAddress) {
- checkNotUsed();
mMacAddress = macAddress;
return this;
}
@NonNull
- @Override
public DeviceId build() {
- markUsed();
if (mCustomId == null && mMacAddress == null) {
throw new IllegalArgumentException("At least one device id property must be"
+ "non-null to build a DeviceId.");
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 18a45d8d..5381301 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -539,9 +539,6 @@
hasBindDeviceAdminPermission);
break;
case TAG_USES_SDK_LIBRARY:
- if (!android.content.pm.Flags.sdkDependencyInstaller()) {
- break;
- }
String usesSdkLibName = parser.getAttributeValue(
ANDROID_RES_NAMESPACE, "name");
// TODO(b/379219371): Due to a bug in bundletool, some apps can use
diff --git a/core/java/android/database/sqlite/SQLiteRawStatement.java b/core/java/android/database/sqlite/SQLiteRawStatement.java
index c59d3ce..3f3e46b 100644
--- a/core/java/android/database/sqlite/SQLiteRawStatement.java
+++ b/core/java/android/database/sqlite/SQLiteRawStatement.java
@@ -554,10 +554,16 @@
*
* @see <a href="http://sqlite.org/c3ref/column_blob.html">sqlite3_column_type</a>
*
+ * If the row has no data then a {@link SQLiteMisuseException} is thrown. This condition can
+ * occur the last call to {@link #step()} returned false or if {@link #step()} was not called
+ * before the statement was created or after the last call to {@link #reset()}. Note that
+ * {@link SQLiteMisuseException} may be thrown for other reasons.
+ *
* @param columnIndex The index of a column in the result row. It is zero-based.
* @return The type of the value in the column of the result row.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data.
* @throws SQLiteException if a native error occurs.
*/
@SQLiteDataType
@@ -580,6 +586,7 @@
* @return The name of the column in the result row.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteOutOfMemoryException if the database cannot allocate memory for the name.
*/
@NonNull
@@ -606,6 +613,7 @@
* @return The length, in bytes, of the value in the column.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
public int getColumnLength(int columnIndex) {
@@ -631,6 +639,7 @@
* @return The value of the column as a blob, or null if the column is NULL.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
@Nullable
@@ -664,6 +673,7 @@
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws IllegalArgumentException if the buffer is too small for offset+length.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
public int readColumnBlob(int columnIndex, @NonNull byte[] buffer, int offset,
@@ -691,6 +701,7 @@
* @return The value of a column as a double.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
public double getColumnDouble(int columnIndex) {
@@ -715,6 +726,7 @@
* @return The value of the column as an int.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
public int getColumnInt(int columnIndex) {
@@ -739,6 +751,7 @@
* @return The value of the column as an long.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
public long getColumnLong(int columnIndex) {
@@ -763,6 +776,7 @@
* @return The value of the column as a string.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
@NonNull
diff --git a/core/java/android/hardware/contexthub/HubEndpointSession.java b/core/java/android/hardware/contexthub/HubEndpointSession.java
index b8af398..77f937e 100644
--- a/core/java/android/hardware/contexthub/HubEndpointSession.java
+++ b/core/java/android/hardware/contexthub/HubEndpointSession.java
@@ -69,6 +69,8 @@
* @return For messages that does not require a response, the transaction will immediately
* complete. For messages that requires a response, the transaction will complete after
* receiving the response for the message.
+ * @throws SecurityException if the application doesn't have the right permissions to send this
+ * message.
*/
@NonNull
@RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
diff --git a/core/java/android/hardware/display/DisplayTopology.java b/core/java/android/hardware/display/DisplayTopology.java
index 1f7d426..211aeff 100644
--- a/core/java/android/hardware/display/DisplayTopology.java
+++ b/core/java/android/hardware/display/DisplayTopology.java
@@ -91,6 +91,15 @@
@VisibleForTesting
public DisplayTopology(TreeNode root, int primaryDisplayId) {
mRoot = root;
+ if (mRoot != null) {
+ // Set mRoot's position and offset to predictable values, just so we don't leak state
+ // from some previous arrangement the node was used in, or leak arbitrary values passed
+ // to the TreeNode constructor. The position and offset don't mean anything because
+ // mRoot doesn't have a parent.
+ mRoot.mPosition = POSITION_LEFT;
+ mRoot.mOffset = 0f;
+ }
+
mPrimaryDisplayId = primaryDisplayId;
}
@@ -422,6 +431,14 @@
}
}
}
+
+ // Sort children lists by display ID.
+ final Comparator<TreeNode> idComparator = (d1, d2) -> {
+ return Integer.compare(d1.mDisplayId, d2.mDisplayId);
+ };
+ for (TreeNode display : displays) {
+ display.mChildren.sort(idComparator);
+ }
}
/**
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index eb7b409..aaa78aa 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -189,4 +189,11 @@
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
+ }
+
+flag {
+ name: "pointer_acceleration"
+ namespace: "input"
+ description: "Allows the user to disable pointer acceleration for mouse and touchpads."
+ bug: "349006858"
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index 310e1a6..d9888ad 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -841,6 +841,7 @@
* @param endpointId The identifier of the hub endpoint.
* @param callback The callback to be invoked.
* @param executor The executor to invoke the callback on.
+ * @throws UnsupportedOperationException If the operation is not supported.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@FlaggedApi(Flags.FLAG_OFFLOAD_API)
@@ -881,6 +882,7 @@
* @param callback The callback to be invoked.
* @param executor The executor to invoke the callback on.
* @throws IllegalArgumentException if the serviceDescriptor is empty.
+ * @throws UnsupportedOperationException If the operation is not supported.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@FlaggedApi(Flags.FLAG_OFFLOAD_API)
@@ -911,6 +913,7 @@
*
* @param callback The callback previously registered.
* @throws IllegalArgumentException If the callback was not previously registered.
+ * @throws UnsupportedOperationException If the operation is not supported.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@FlaggedApi(Flags.FLAG_OFFLOAD_API)
@@ -1311,6 +1314,8 @@
* endpoint discovery results (e.g. from {@link ContextHubManager#findEndpoints(long)}).
* @param serviceDescriptor A string that describes the service associated with this session.
* The information will be sent to the destination as part of open request.
+ * @throws IllegalStateException if hubEndpoint was not successfully registered, or if there is
+ * insufficient capacity for creating a session.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@FlaggedApi(Flags.FLAG_OFFLOAD_API)
diff --git a/core/java/android/hardware/radio/ProgramSelector.java b/core/java/android/hardware/radio/ProgramSelector.java
index 42028f6..e5717ac 100644
--- a/core/java/android/hardware/radio/ProgramSelector.java
+++ b/core/java/android/hardware/radio/ProgramSelector.java
@@ -43,22 +43,20 @@
* <li>DAB channel info</li>
* </ui>
*
- * <p>The primary ID uniquely identifies a station and can be used for equality
- * check. The secondary IDs are supplementary and can speed up tuning process,
- * but the primary ID is sufficient (ie. after a full band scan).
- *
- * <p>Two selectors with different secondary IDs, but the same primary ID are
- * considered equal. In particular, secondary IDs vector may get updated for
+ * <p>Except for DAB radio, two selectors with different secondary IDs, but the same primary
+ * ID are considered equal. In particular, secondary IDs vector may get updated for
* an entry on the program list (ie. when a better frequency for a given
- * station is found).
+ * station is found). For DAB radio, two selectors with the same primary ID and the same
+ * DAB frequency and DAB ensemble secondary IDs (if exist) are considered equal.
*
* <p>The primaryId of a given programType MUST be of a specific type:
* <ui>
- * <li>AM, FM: RDS_PI if the station broadcasts RDS, AMFM_FREQUENCY otherwise;</li>
- * <li>AM_HD, FM_HD: HD_STATION_ID_EXT;</li>
- * <li>DAB: DAB_SIDECC;</li>
- * <li>DRMO: DRMO_SERVICE_ID;</li>
- * <li>SXM: SXM_SERVICE_ID;</li>
+ * <li>AM, FM: {@link #IDENTIFIER_TYPE_RDS_PI} if the station broadcasts RDS,
+ * {@link #IDENTIFIER_TYPE_AMFM_FREQUENCY} otherwise;</li>
+ * <li>AM_HD, FM_HD: {@link #IDENTIFIER_TYPE_HD_STATION_ID_EXT};</li>
+ * <li>DAB: {@link #IDENTIFIER_TYPE_DAB_SID_EXT} or
+ * {@link #IDENTIFIER_TYPE_DAB_DMB_SID_EXT};</li>
+ * <li>DRMO: {@link #IDENTIFIER_TYPE_DRMO_SERVICE_ID};</li>
* <li>VENDOR: VENDOR_PRIMARY.</li>
* </ui>
* @hide
@@ -597,9 +595,9 @@
* negatives. In particular, it may be way off for certain regions.
* The main purpose is to avoid passing improper units, ie. MHz instead of kHz.
*
- * @param isAm true, if AM, false if FM.
+ * @param isAm {@code true}, if AM, {@code false} if FM.
* @param frequencyKhz the frequency in kHz.
- * @return true, if the frequency is roughly valid.
+ * @return {@code true}, if the frequency is roughly valid.
*/
private static boolean isValidAmFmFrequency(boolean isAm, int frequencyKhz) {
if (isAm) {
@@ -785,8 +783,8 @@
* ProgramLists for category entries.
*
* @see ProgramList.Filter#areCategoriesIncluded
- * @return False if this identifier's type is not tunable (e.g. DAB ensemble or
- * vendor-specified type). True otherwise.
+ * @return {@link false} if this identifier's type is not tunable (e.g. DAB ensemble or
+ * vendor-specified type). {@link true} otherwise.
*/
public boolean isCategoryType() {
return (mType >= IDENTIFIER_TYPE_VENDOR_START && mType <= IDENTIFIER_TYPE_VENDOR_END)
diff --git a/core/java/android/net/EventLogTags.logtags b/core/java/android/net/EventLogTags.logtags
index d5ed014..32953c9 100644
--- a/core/java/android/net/EventLogTags.logtags
+++ b/core/java/android/net/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.net
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index 11b80ce..b509c7a 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -1272,7 +1272,7 @@
return true;
}
- private Message legacyPeekOrPop(boolean peek) {
+ private Message legacyPeekOrPoll(boolean peek) {
synchronized (this) {
// Try to retrieve the next message. Return if found.
final long now = SystemClock.uptimeMillis();
@@ -1331,7 +1331,7 @@
if (mUseConcurrent) {
ret = nextMessage(true);
} else {
- ret = legacyPeekOrPop(true);
+ ret = legacyPeekOrPoll(true);
}
return ret != null ? ret.when : null;
}
@@ -1344,15 +1344,78 @@
*/
@SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
@Nullable
- Message popForTest() {
+ Message pollForTest() {
throwIfNotTest();
if (mUseConcurrent) {
return nextMessage(false);
} else {
- return legacyPeekOrPop(false);
+ return legacyPeekOrPoll(false);
}
}
+ /**
+ * @return true if we are blocked on a sync barrier
+ */
+ boolean isBlockedOnSyncBarrier() {
+ throwIfNotTest();
+ if (mUseConcurrent) {
+ Iterator<MessageNode> queueIter = mPriorityQueue.iterator();
+ MessageNode queueNode = iterateNext(queueIter);
+
+ if (queueNode.isBarrier()) {
+ long now = SystemClock.uptimeMillis();
+
+ /* Look for a deliverable async node. If one exists we are not blocked. */
+ Iterator<MessageNode> asyncQueueIter = mAsyncPriorityQueue.iterator();
+ MessageNode asyncNode = iterateNext(asyncQueueIter);
+ if (asyncNode != null && now >= asyncNode.getWhen()) {
+ return false;
+ }
+ /*
+ * Look for a deliverable sync node. In this case, if one exists we are blocked
+ * since the barrier prevents delivery of the Message.
+ */
+ while (queueNode.isBarrier()) {
+ queueNode = iterateNext(queueIter);
+ }
+ if (queueNode != null && now >= queueNode.getWhen()) {
+ return true;
+ }
+
+ return false;
+ }
+ } else {
+ Message msg = mMessages;
+ if (msg != null && msg.target == null) {
+ Message iter = msg;
+ /* Look for a deliverable async node */
+ do {
+ iter = iter.next;
+ } while (iter != null && !iter.isAsynchronous());
+
+ long now = SystemClock.uptimeMillis();
+ if (iter != null && now >= iter.when) {
+ return false;
+ }
+ /*
+ * Look for a deliverable sync node. In this case, if one exists we are blocked
+ * since the barrier prevents delivery of the Message.
+ */
+ iter = msg;
+ do {
+ iter = iter.next;
+ } while (iter != null && (iter.target == null || iter.isAsynchronous()));
+
+ if (iter != null && now >= iter.when) {
+ return true;
+ }
+ return false;
+ }
+ }
+ /* No barrier was found. */
+ return false;
+ }
+
private static final class MatchHandlerWhatAndObject extends MessageCompare {
@Override
public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
diff --git a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
index 47778ed..de0259e 100644
--- a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
+++ b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
@@ -1102,11 +1102,43 @@
*/
@SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
@Nullable
- Message popForTest() {
+ Message pollForTest() {
throwIfNotTest();
return nextMessage(false);
}
+ /**
+ * @return true if we are blocked on a sync barrier
+ */
+ boolean isBlockedOnSyncBarrier() {
+ throwIfNotTest();
+ Iterator<MessageNode> queueIter = mPriorityQueue.iterator();
+ MessageNode queueNode = iterateNext(queueIter);
+
+ if (queueNode.isBarrier()) {
+ long now = SystemClock.uptimeMillis();
+
+ /* Look for a deliverable async node. If one exists we are not blocked. */
+ Iterator<MessageNode> asyncQueueIter = mAsyncPriorityQueue.iterator();
+ MessageNode asyncNode = iterateNext(asyncQueueIter);
+ if (asyncNode != null && now >= asyncNode.getWhen()) {
+ return false;
+ }
+ /*
+ * Look for a deliverable sync node. In this case, if one exists we are blocked
+ * since the barrier prevents delivery of the Message.
+ */
+ while (queueNode.isBarrier()) {
+ queueNode = iterateNext(queueIter);
+ }
+ if (queueNode != null && now >= queueNode.getWhen()) {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
private StateNode getStateNode(StackNode node) {
if (node.isMessageNode()) {
return ((MessageNode) node).mBottomOfStack;
diff --git a/core/java/android/os/IHintManager.aidl b/core/java/android/os/IHintManager.aidl
index 4a14a8d..56a089a 100644
--- a/core/java/android/os/IHintManager.aidl
+++ b/core/java/android/os/IHintManager.aidl
@@ -21,11 +21,13 @@
import android.os.GpuHeadroomParamsInternal;
import android.os.IHintSession;
import android.os.SessionCreationConfig;
-import android.hardware.power.CpuHeadroomResult;
+
import android.hardware.power.ChannelConfig;
+import android.hardware.power.CpuHeadroomResult;
import android.hardware.power.GpuHeadroomResult;
import android.hardware.power.SessionConfig;
import android.hardware.power.SessionTag;
+import android.hardware.power.SupportInfo;
/** {@hide} */
interface IHintManager {
@@ -40,11 +42,6 @@
IHintSession createHintSessionWithConfig(in IBinder token, in SessionTag tag,
in SessionCreationConfig creationConfig, out SessionConfig config);
- /**
- * Get preferred rate limit in nanoseconds.
- */
- long getHintSessionPreferredRate();
-
void setHintSessionThreads(in IHintSession hintSession, in int[] tids);
int[] getHintSessionThreadIds(in IHintSession hintSession);
@@ -61,13 +58,28 @@
long getGpuHeadroomMinIntervalMillis();
/**
- * Get Maximum number of graphics pipeline threads allowed per-app.
- */
- int getMaxGraphicsPipelineThreadsCount();
-
- /**
* Used by the JNI to pass an interface to the SessionManager;
* for internal use only.
*/
oneway void passSessionManagerBinder(in IBinder sessionManager);
+
+ parcelable HintManagerClientData {
+ int powerHalVersion;
+ int maxGraphicsPipelineThreads;
+ long preferredRateNanos;
+ SupportInfo supportInfo;
+ }
+
+ interface IHintManagerClient {
+ /**
+ * Returns FMQ channel information for the caller, which it associates to the callback binder lifespan.
+ */
+ oneway void receiveChannelConfig(in ChannelConfig config);
+ }
+
+ /**
+ * Set up an ADPF client, receiving a remote client binder interface and
+ * passing back a bundle of support and configuration information.
+ */
+ HintManagerClientData registerClient(in IHintManagerClient client);
}
diff --git a/core/java/android/os/LegacyMessageQueue/MessageQueue.java b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
index f49acd1..5e1e1fd 100644
--- a/core/java/android/os/LegacyMessageQueue/MessageQueue.java
+++ b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
@@ -740,7 +740,7 @@
return true;
}
- private Message legacyPeekOrPop(boolean peek) {
+ private Message legacyPeekOrPoll(boolean peek) {
synchronized (this) {
// Try to retrieve the next message. Return if found.
final long now = SystemClock.uptimeMillis();
@@ -795,7 +795,7 @@
@SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
Long peekWhenForTest() {
throwIfNotTest();
- Message ret = legacyPeekOrPop(true);
+ Message ret = legacyPeekOrPoll(true);
return ret != null ? ret.when : null;
}
@@ -807,9 +807,43 @@
*/
@SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
@Nullable
- Message popForTest() {
+ Message pollForTest() {
throwIfNotTest();
- return legacyPeekOrPop(false);
+ return legacyPeekOrPoll(false);
+ }
+
+ /**
+ * @return true if we are blocked on a sync barrier
+ */
+ boolean isBlockedOnSyncBarrier() {
+ throwIfNotTest();
+ Message msg = mMessages;
+ if (msg != null && msg.target == null) {
+ Message iter = msg;
+ /* Look for a deliverable async node */
+ do {
+ iter = iter.next;
+ } while (iter != null && !iter.isAsynchronous());
+
+ long now = SystemClock.uptimeMillis();
+ if (iter != null && now >= iter.when) {
+ return false;
+ }
+ /*
+ * Look for a deliverable sync node. In this case, if one exists we are blocked
+ * since the barrier prevents delivery of the Message.
+ */
+ iter = msg;
+ do {
+ iter = iter.next;
+ } while (iter != null && (iter.target == null || iter.isAsynchronous()));
+
+ if (iter != null && now >= iter.when) {
+ return true;
+ }
+ return false;
+ }
+ return false;
}
boolean hasMessages(Handler h, int what, Object object) {
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 6855d95..cf473ec 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -50,7 +50,6 @@
import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
-import dalvik.annotation.optimization.NeverInline;
import libcore.util.SneakyThrow;
@@ -588,17 +587,6 @@
return parcel;
}
- @NeverInline
- private void errorUsedWhileRecycling() {
- Log.wtf(TAG, "Parcel used while recycled. "
- + Log.getStackTraceString(new Throwable())
- + " Original recycle call (if DEBUG_RECYCLE): ", mStack);
- }
-
- private void assertNotRecycled() {
- if (mRecycled) errorUsedWhileRecycling();
- }
-
/**
* Put a Parcel object back into the pool. You must not touch
* the object after this call.
@@ -647,7 +635,6 @@
* @hide
*/
public void setReadWriteHelper(@Nullable ReadWriteHelper helper) {
- assertNotRecycled();
mReadWriteHelper = helper != null ? helper : ReadWriteHelper.DEFAULT;
}
@@ -657,7 +644,6 @@
* @hide
*/
public boolean hasReadWriteHelper() {
- assertNotRecycled();
return (mReadWriteHelper != null) && (mReadWriteHelper != ReadWriteHelper.DEFAULT);
}
@@ -684,7 +670,6 @@
* @hide
*/
public final void markSensitive() {
- assertNotRecycled();
nativeMarkSensitive(mNativePtr);
}
@@ -701,7 +686,6 @@
* @hide
*/
public final boolean isForRpc() {
- assertNotRecycled();
return nativeIsForRpc(mNativePtr);
}
@@ -709,25 +693,21 @@
@ParcelFlags
@TestApi
public int getFlags() {
- assertNotRecycled();
return mFlags;
}
/** @hide */
public void setFlags(@ParcelFlags int flags) {
- assertNotRecycled();
mFlags = flags;
}
/** @hide */
public void addFlags(@ParcelFlags int flags) {
- assertNotRecycled();
mFlags |= flags;
}
/** @hide */
private boolean hasFlags(@ParcelFlags int flags) {
- assertNotRecycled();
return (mFlags & flags) == flags;
}
@@ -740,7 +720,6 @@
// We don't really need to protect it; even if 3p / non-system apps, nothing would happen.
// This would only work when used on a reply parcel by a binder object that's allowed-blocking.
public void setPropagateAllowBlocking() {
- assertNotRecycled();
addFlags(FLAG_PROPAGATE_ALLOW_BLOCKING);
}
@@ -748,7 +727,6 @@
* Returns the total amount of data contained in the parcel.
*/
public int dataSize() {
- assertNotRecycled();
return nativeDataSize(mNativePtr);
}
@@ -757,7 +735,6 @@
* parcel. That is, {@link #dataSize}-{@link #dataPosition}.
*/
public final int dataAvail() {
- assertNotRecycled();
return nativeDataAvail(mNativePtr);
}
@@ -766,7 +743,6 @@
* more than {@link #dataSize}.
*/
public final int dataPosition() {
- assertNotRecycled();
return nativeDataPosition(mNativePtr);
}
@@ -777,7 +753,6 @@
* data buffer.
*/
public final int dataCapacity() {
- assertNotRecycled();
return nativeDataCapacity(mNativePtr);
}
@@ -789,7 +764,6 @@
* @param size The new number of bytes in the Parcel.
*/
public final void setDataSize(int size) {
- assertNotRecycled();
nativeSetDataSize(mNativePtr, size);
}
@@ -799,7 +773,6 @@
* {@link #dataSize}.
*/
public final void setDataPosition(int pos) {
- assertNotRecycled();
nativeSetDataPosition(mNativePtr, pos);
}
@@ -811,13 +784,11 @@
* with this method.
*/
public final void setDataCapacity(int size) {
- assertNotRecycled();
nativeSetDataCapacity(mNativePtr, size);
}
/** @hide */
public final boolean pushAllowFds(boolean allowFds) {
- assertNotRecycled();
return nativePushAllowFds(mNativePtr, allowFds);
}
@@ -838,7 +809,6 @@
* in different versions of the platform.
*/
public final byte[] marshall() {
- assertNotRecycled();
return nativeMarshall(mNativePtr);
}
@@ -846,18 +816,15 @@
* Fills the raw bytes of this Parcel with the supplied data.
*/
public final void unmarshall(@NonNull byte[] data, int offset, int length) {
- assertNotRecycled();
nativeUnmarshall(mNativePtr, data, offset, length);
}
public final void appendFrom(Parcel parcel, int offset, int length) {
- assertNotRecycled();
nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length);
}
/** @hide */
public int compareData(Parcel other) {
- assertNotRecycled();
return nativeCompareData(mNativePtr, other.mNativePtr);
}
@@ -868,7 +835,6 @@
/** @hide */
public final void setClassCookie(Class clz, Object cookie) {
- assertNotRecycled();
if (mClassCookies == null) {
mClassCookies = new ArrayMap<>();
}
@@ -878,13 +844,11 @@
/** @hide */
@Nullable
public final Object getClassCookie(Class clz) {
- assertNotRecycled();
return mClassCookies != null ? mClassCookies.get(clz) : null;
}
/** @hide */
public void removeClassCookie(Class clz, Object expectedCookie) {
- assertNotRecycled();
if (mClassCookies != null) {
Object removedCookie = mClassCookies.remove(clz);
if (removedCookie != expectedCookie) {
@@ -902,25 +866,21 @@
* @hide
*/
public boolean hasClassCookie(Class clz) {
- assertNotRecycled();
return mClassCookies != null && mClassCookies.containsKey(clz);
}
/** @hide */
public final void adoptClassCookies(Parcel from) {
- assertNotRecycled();
mClassCookies = from.mClassCookies;
}
/** @hide */
public Map<Class, Object> copyClassCookies() {
- assertNotRecycled();
return new ArrayMap<>(mClassCookies);
}
/** @hide */
public void putClassCookies(Map<Class, Object> cookies) {
- assertNotRecycled();
if (cookies == null) {
return;
}
@@ -932,9 +892,14 @@
/**
* Report whether the parcel contains any marshalled file descriptors.
+ *
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
*/
public boolean hasFileDescriptors() {
- assertNotRecycled();
return nativeHasFileDescriptors(mNativePtr);
}
@@ -942,6 +907,12 @@
* Report whether the parcel contains any marshalled file descriptors in the range defined by
* {@code offset} and {@code length}.
*
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
+ *
* @param offset The offset from which the range starts. Should be between 0 and
* {@link #dataSize()}.
* @param length The length of the range. Should be between 0 and {@link #dataSize()} - {@code
@@ -950,7 +921,6 @@
* @throws IllegalArgumentException if the parameters are out of the permitted ranges.
*/
public boolean hasFileDescriptors(int offset, int length) {
- assertNotRecycled();
return nativeHasFileDescriptorsInRange(mNativePtr, offset, length);
}
@@ -963,6 +933,12 @@
* <p>For most cases, it will use the self-reported {@link Parcelable#describeContents()} method
* for that.
*
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
+ *
* @throws IllegalArgumentException if you provide any object not supported by above methods
* (including if the unsupported object is inside a nested container).
*
@@ -1032,10 +1008,16 @@
*
* @throws UnsupportedOperationException if binder kernel driver was disabled or if method was
* invoked in case of Binder RPC protocol.
+ *
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
+ *
* @hide
*/
public boolean hasBinders() {
- assertNotRecycled();
return nativeHasBinders(mNativePtr);
}
@@ -1043,6 +1025,12 @@
* Report whether the parcel contains any marshalled {@link IBinder} objects in the range
* defined by {@code offset} and {@code length}.
*
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
+ *
* @param offset The offset from which the range starts. Should be between 0 and
* {@link #dataSize()}.
* @param length The length of the range. Should be between 0 and {@link #dataSize()} - {@code
@@ -1053,7 +1041,6 @@
* @hide
*/
public boolean hasBinders(int offset, int length) {
- assertNotRecycled();
return nativeHasBindersInRange(mNativePtr, offset, length);
}
@@ -1064,7 +1051,6 @@
* at the beginning of transactions as a header.
*/
public final void writeInterfaceToken(@NonNull String interfaceName) {
- assertNotRecycled();
nativeWriteInterfaceToken(mNativePtr, interfaceName);
}
@@ -1075,7 +1061,6 @@
* should propagate to the caller.
*/
public final void enforceInterface(@NonNull String interfaceName) {
- assertNotRecycled();
nativeEnforceInterface(mNativePtr, interfaceName);
}
@@ -1086,7 +1071,6 @@
* When used over binder, this exception should propagate to the caller.
*/
public void enforceNoDataAvail() {
- assertNotRecycled();
final int n = dataAvail();
if (n > 0) {
throw new BadParcelableException("Parcel data not fully consumed, unread size: " + n);
@@ -1103,7 +1087,6 @@
* @hide
*/
public boolean replaceCallingWorkSourceUid(int workSourceUid) {
- assertNotRecycled();
return nativeReplaceCallingWorkSourceUid(mNativePtr, workSourceUid);
}
@@ -1120,7 +1103,6 @@
* @hide
*/
public int readCallingWorkSourceUid() {
- assertNotRecycled();
return nativeReadCallingWorkSourceUid(mNativePtr);
}
@@ -1130,7 +1112,6 @@
* @param b Bytes to place into the parcel.
*/
public final void writeByteArray(@Nullable byte[] b) {
- assertNotRecycled();
writeByteArray(b, 0, (b != null) ? b.length : 0);
}
@@ -1142,7 +1123,6 @@
* @param len Number of bytes to write.
*/
public final void writeByteArray(@Nullable byte[] b, int offset, int len) {
- assertNotRecycled();
if (b == null) {
writeInt(-1);
return;
@@ -1164,7 +1144,6 @@
* @see #readBlob()
*/
public final void writeBlob(@Nullable byte[] b) {
- assertNotRecycled();
writeBlob(b, 0, (b != null) ? b.length : 0);
}
@@ -1183,7 +1162,6 @@
* @see #readBlob()
*/
public final void writeBlob(@Nullable byte[] b, int offset, int len) {
- assertNotRecycled();
if (b == null) {
writeInt(-1);
return;
@@ -1202,7 +1180,6 @@
* growing dataCapacity() if needed.
*/
public final void writeInt(int val) {
- assertNotRecycled();
int err = nativeWriteInt(mNativePtr, val);
if (err != OK) {
nativeSignalExceptionForError(err);
@@ -1214,7 +1191,6 @@
* growing dataCapacity() if needed.
*/
public final void writeLong(long val) {
- assertNotRecycled();
int err = nativeWriteLong(mNativePtr, val);
if (err != OK) {
nativeSignalExceptionForError(err);
@@ -1226,7 +1202,6 @@
* dataPosition(), growing dataCapacity() if needed.
*/
public final void writeFloat(float val) {
- assertNotRecycled();
int err = nativeWriteFloat(mNativePtr, val);
if (err != OK) {
nativeSignalExceptionForError(err);
@@ -1238,7 +1213,6 @@
* current dataPosition(), growing dataCapacity() if needed.
*/
public final void writeDouble(double val) {
- assertNotRecycled();
int err = nativeWriteDouble(mNativePtr, val);
if (err != OK) {
nativeSignalExceptionForError(err);
@@ -1250,19 +1224,16 @@
* growing dataCapacity() if needed.
*/
public final void writeString(@Nullable String val) {
- assertNotRecycled();
writeString16(val);
}
/** {@hide} */
public final void writeString8(@Nullable String val) {
- assertNotRecycled();
mReadWriteHelper.writeString8(this, val);
}
/** {@hide} */
public final void writeString16(@Nullable String val) {
- assertNotRecycled();
mReadWriteHelper.writeString16(this, val);
}
@@ -1274,19 +1245,16 @@
* @hide
*/
public void writeStringNoHelper(@Nullable String val) {
- assertNotRecycled();
writeString16NoHelper(val);
}
/** {@hide} */
public void writeString8NoHelper(@Nullable String val) {
- assertNotRecycled();
nativeWriteString8(mNativePtr, val);
}
/** {@hide} */
public void writeString16NoHelper(@Nullable String val) {
- assertNotRecycled();
nativeWriteString16(mNativePtr, val);
}
@@ -1298,7 +1266,6 @@
* for true or false, respectively, but may change in the future.
*/
public final void writeBoolean(boolean val) {
- assertNotRecycled();
writeInt(val ? 1 : 0);
}
@@ -1310,7 +1277,6 @@
@UnsupportedAppUsage
@RavenwoodThrow(blockedBy = android.text.Spanned.class)
public final void writeCharSequence(@Nullable CharSequence val) {
- assertNotRecycled();
TextUtils.writeToParcel(val, this, 0);
}
@@ -1319,7 +1285,6 @@
* growing dataCapacity() if needed.
*/
public final void writeStrongBinder(IBinder val) {
- assertNotRecycled();
nativeWriteStrongBinder(mNativePtr, val);
}
@@ -1328,7 +1293,6 @@
* growing dataCapacity() if needed.
*/
public final void writeStrongInterface(IInterface val) {
- assertNotRecycled();
writeStrongBinder(val == null ? null : val.asBinder());
}
@@ -1343,7 +1307,6 @@
* if {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set.</p>
*/
public final void writeFileDescriptor(@NonNull FileDescriptor val) {
- assertNotRecycled();
nativeWriteFileDescriptor(mNativePtr, val);
}
@@ -1352,7 +1315,6 @@
* This will be the new name for writeFileDescriptor, for consistency.
**/
public final void writeRawFileDescriptor(@NonNull FileDescriptor val) {
- assertNotRecycled();
nativeWriteFileDescriptor(mNativePtr, val);
}
@@ -1363,7 +1325,6 @@
* @param value The array of objects to be written.
*/
public final void writeRawFileDescriptorArray(@Nullable FileDescriptor[] value) {
- assertNotRecycled();
if (value != null) {
int N = value.length;
writeInt(N);
@@ -1383,7 +1344,6 @@
* the future.
*/
public final void writeByte(byte val) {
- assertNotRecycled();
writeInt(val);
}
@@ -1399,7 +1359,6 @@
* allows you to avoid mysterious type errors at the point of marshalling.
*/
public final void writeMap(@Nullable Map val) {
- assertNotRecycled();
writeMapInternal((Map<String, Object>) val);
}
@@ -1408,7 +1367,6 @@
* growing dataCapacity() if needed. The Map keys must be String objects.
*/
/* package */ void writeMapInternal(@Nullable Map<String,Object> val) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -1434,7 +1392,6 @@
* growing dataCapacity() if needed. The Map keys must be String objects.
*/
/* package */ void writeArrayMapInternal(@Nullable ArrayMap<String, Object> val) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -1464,7 +1421,6 @@
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void writeArrayMap(@Nullable ArrayMap<String, Object> val) {
- assertNotRecycled();
writeArrayMapInternal(val);
}
@@ -1483,7 +1439,6 @@
*/
public <T extends Parcelable> void writeTypedArrayMap(@Nullable ArrayMap<String, T> val,
int parcelableFlags) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -1505,7 +1460,6 @@
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void writeArraySet(@Nullable ArraySet<? extends Object> val) {
- assertNotRecycled();
final int size = (val != null) ? val.size() : -1;
writeInt(size);
for (int i = 0; i < size; i++) {
@@ -1518,7 +1472,6 @@
* growing dataCapacity() if needed.
*/
public final void writeBundle(@Nullable Bundle val) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -1532,7 +1485,6 @@
* growing dataCapacity() if needed.
*/
public final void writePersistableBundle(@Nullable PersistableBundle val) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -1546,7 +1498,6 @@
* growing dataCapacity() if needed.
*/
public final void writeSize(@NonNull Size val) {
- assertNotRecycled();
writeInt(val.getWidth());
writeInt(val.getHeight());
}
@@ -1556,7 +1507,6 @@
* growing dataCapacity() if needed.
*/
public final void writeSizeF(@NonNull SizeF val) {
- assertNotRecycled();
writeFloat(val.getWidth());
writeFloat(val.getHeight());
}
@@ -1567,7 +1517,6 @@
* {@link #writeValue} and must follow the specification there.
*/
public final void writeList(@Nullable List val) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -1587,7 +1536,6 @@
* {@link #writeValue} and must follow the specification there.
*/
public final void writeArray(@Nullable Object[] val) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -1608,7 +1556,6 @@
* specification there.
*/
public final <T> void writeSparseArray(@Nullable SparseArray<T> val) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -1624,7 +1571,6 @@
}
public final void writeSparseBooleanArray(@Nullable SparseBooleanArray val) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -1643,7 +1589,6 @@
* @hide
*/
public final void writeSparseIntArray(@Nullable SparseIntArray val) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -1659,7 +1604,6 @@
}
public final void writeBooleanArray(@Nullable boolean[] val) {
- assertNotRecycled();
if (val != null) {
int N = val.length;
writeInt(N);
@@ -1694,7 +1638,6 @@
}
private void ensureWithinMemoryLimit(int typeSize, @NonNull int... dimensions) {
- assertNotRecycled();
// For Multidimensional arrays, Calculate total object
// which will be allocated.
int totalObjects = 1;
@@ -1712,7 +1655,6 @@
}
private void ensureWithinMemoryLimit(int typeSize, int length) {
- assertNotRecycled();
int estimatedAllocationSize = 0;
try {
estimatedAllocationSize = Math.multiplyExact(typeSize, length);
@@ -1736,7 +1678,6 @@
@Nullable
public final boolean[] createBooleanArray() {
- assertNotRecycled();
int N = readInt();
ensureWithinMemoryLimit(SIZE_BOOLEAN, N);
// >>2 as a fast divide-by-4 works in the create*Array() functions
@@ -1754,7 +1695,6 @@
}
public final void readBooleanArray(@NonNull boolean[] val) {
- assertNotRecycled();
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
@@ -1767,7 +1707,6 @@
/** @hide */
public void writeShortArray(@Nullable short[] val) {
- assertNotRecycled();
if (val != null) {
int n = val.length;
writeInt(n);
@@ -1782,7 +1721,6 @@
/** @hide */
@Nullable
public short[] createShortArray() {
- assertNotRecycled();
int n = readInt();
ensureWithinMemoryLimit(SIZE_SHORT, n);
if (n >= 0 && n <= (dataAvail() >> 2)) {
@@ -1798,7 +1736,6 @@
/** @hide */
public void readShortArray(@NonNull short[] val) {
- assertNotRecycled();
int n = readInt();
if (n == val.length) {
for (int i = 0; i < n; i++) {
@@ -1810,7 +1747,6 @@
}
public final void writeCharArray(@Nullable char[] val) {
- assertNotRecycled();
if (val != null) {
int N = val.length;
writeInt(N);
@@ -1824,7 +1760,6 @@
@Nullable
public final char[] createCharArray() {
- assertNotRecycled();
int N = readInt();
ensureWithinMemoryLimit(SIZE_CHAR, N);
if (N >= 0 && N <= (dataAvail() >> 2)) {
@@ -1839,7 +1774,6 @@
}
public final void readCharArray(@NonNull char[] val) {
- assertNotRecycled();
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
@@ -1851,7 +1785,6 @@
}
public final void writeIntArray(@Nullable int[] val) {
- assertNotRecycled();
if (val != null) {
int N = val.length;
writeInt(N);
@@ -1865,7 +1798,6 @@
@Nullable
public final int[] createIntArray() {
- assertNotRecycled();
int N = readInt();
ensureWithinMemoryLimit(SIZE_INT, N);
if (N >= 0 && N <= (dataAvail() >> 2)) {
@@ -1880,7 +1812,6 @@
}
public final void readIntArray(@NonNull int[] val) {
- assertNotRecycled();
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
@@ -1892,7 +1823,6 @@
}
public final void writeLongArray(@Nullable long[] val) {
- assertNotRecycled();
if (val != null) {
int N = val.length;
writeInt(N);
@@ -1906,7 +1836,6 @@
@Nullable
public final long[] createLongArray() {
- assertNotRecycled();
int N = readInt();
ensureWithinMemoryLimit(SIZE_LONG, N);
// >>3 because stored longs are 64 bits
@@ -1922,7 +1851,6 @@
}
public final void readLongArray(@NonNull long[] val) {
- assertNotRecycled();
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
@@ -1934,7 +1862,6 @@
}
public final void writeFloatArray(@Nullable float[] val) {
- assertNotRecycled();
if (val != null) {
int N = val.length;
writeInt(N);
@@ -1948,7 +1875,6 @@
@Nullable
public final float[] createFloatArray() {
- assertNotRecycled();
int N = readInt();
ensureWithinMemoryLimit(SIZE_FLOAT, N);
// >>2 because stored floats are 4 bytes
@@ -1964,7 +1890,6 @@
}
public final void readFloatArray(@NonNull float[] val) {
- assertNotRecycled();
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
@@ -1976,7 +1901,6 @@
}
public final void writeDoubleArray(@Nullable double[] val) {
- assertNotRecycled();
if (val != null) {
int N = val.length;
writeInt(N);
@@ -1990,7 +1914,6 @@
@Nullable
public final double[] createDoubleArray() {
- assertNotRecycled();
int N = readInt();
ensureWithinMemoryLimit(SIZE_DOUBLE, N);
// >>3 because stored doubles are 8 bytes
@@ -2006,7 +1929,6 @@
}
public final void readDoubleArray(@NonNull double[] val) {
- assertNotRecycled();
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
@@ -2018,24 +1940,20 @@
}
public final void writeStringArray(@Nullable String[] val) {
- assertNotRecycled();
writeString16Array(val);
}
@Nullable
public final String[] createStringArray() {
- assertNotRecycled();
return createString16Array();
}
public final void readStringArray(@NonNull String[] val) {
- assertNotRecycled();
readString16Array(val);
}
/** {@hide} */
public final void writeString8Array(@Nullable String[] val) {
- assertNotRecycled();
if (val != null) {
int N = val.length;
writeInt(N);
@@ -2050,7 +1968,6 @@
/** {@hide} */
@Nullable
public final String[] createString8Array() {
- assertNotRecycled();
int N = readInt();
ensureWithinMemoryLimit(SIZE_COMPLEX_TYPE, N);
if (N >= 0) {
@@ -2066,7 +1983,6 @@
/** {@hide} */
public final void readString8Array(@NonNull String[] val) {
- assertNotRecycled();
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
@@ -2079,7 +1995,6 @@
/** {@hide} */
public final void writeString16Array(@Nullable String[] val) {
- assertNotRecycled();
if (val != null) {
int N = val.length;
writeInt(N);
@@ -2094,7 +2009,6 @@
/** {@hide} */
@Nullable
public final String[] createString16Array() {
- assertNotRecycled();
int N = readInt();
ensureWithinMemoryLimit(SIZE_COMPLEX_TYPE, N);
if (N >= 0) {
@@ -2110,7 +2024,6 @@
/** {@hide} */
public final void readString16Array(@NonNull String[] val) {
- assertNotRecycled();
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
@@ -2122,7 +2035,6 @@
}
public final void writeBinderArray(@Nullable IBinder[] val) {
- assertNotRecycled();
if (val != null) {
int N = val.length;
writeInt(N);
@@ -2147,7 +2059,6 @@
*/
public final <T extends IInterface> void writeInterfaceArray(
@SuppressLint("ArrayReturn") @Nullable T[] val) {
- assertNotRecycled();
if (val != null) {
int N = val.length;
writeInt(N);
@@ -2163,7 +2074,6 @@
* @hide
*/
public final void writeCharSequenceArray(@Nullable CharSequence[] val) {
- assertNotRecycled();
if (val != null) {
int N = val.length;
writeInt(N);
@@ -2179,7 +2089,6 @@
* @hide
*/
public final void writeCharSequenceList(@Nullable ArrayList<CharSequence> val) {
- assertNotRecycled();
if (val != null) {
int N = val.size();
writeInt(N);
@@ -2193,7 +2102,6 @@
@Nullable
public final IBinder[] createBinderArray() {
- assertNotRecycled();
int N = readInt();
ensureWithinMemoryLimit(SIZE_COMPLEX_TYPE, N);
if (N >= 0) {
@@ -2208,7 +2116,6 @@
}
public final void readBinderArray(@NonNull IBinder[] val) {
- assertNotRecycled();
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
@@ -2230,7 +2137,6 @@
@Nullable
public final <T extends IInterface> T[] createInterfaceArray(
@NonNull IntFunction<T[]> newArray, @NonNull Function<IBinder, T> asInterface) {
- assertNotRecycled();
int N = readInt();
ensureWithinMemoryLimit(SIZE_COMPLEX_TYPE, N);
if (N >= 0) {
@@ -2255,7 +2161,6 @@
public final <T extends IInterface> void readInterfaceArray(
@SuppressLint("ArrayReturn") @NonNull T[] val,
@NonNull Function<IBinder, T> asInterface) {
- assertNotRecycled();
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
@@ -2281,7 +2186,6 @@
* @see Parcelable
*/
public final <T extends Parcelable> void writeTypedList(@Nullable List<T> val) {
- assertNotRecycled();
writeTypedList(val, 0);
}
@@ -2301,7 +2205,6 @@
*/
public final <T extends Parcelable> void writeTypedSparseArray(@Nullable SparseArray<T> val,
int parcelableFlags) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -2331,7 +2234,6 @@
* @see Parcelable
*/
public <T extends Parcelable> void writeTypedList(@Nullable List<T> val, int parcelableFlags) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -2357,7 +2259,6 @@
* @see #readStringList
*/
public final void writeStringList(@Nullable List<String> val) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -2383,7 +2284,6 @@
* @see #readBinderList
*/
public final void writeBinderList(@Nullable List<IBinder> val) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -2406,7 +2306,6 @@
* @see #readInterfaceList
*/
public final <T extends IInterface> void writeInterfaceList(@Nullable List<T> val) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -2428,7 +2327,6 @@
* @see #readParcelableList(List, ClassLoader)
*/
public final <T extends Parcelable> void writeParcelableList(@Nullable List<T> val, int flags) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -2463,7 +2361,6 @@
*/
public final <T extends Parcelable> void writeTypedArray(@Nullable T[] val,
int parcelableFlags) {
- assertNotRecycled();
if (val != null) {
int N = val.length;
writeInt(N);
@@ -2486,7 +2383,6 @@
*/
public final <T extends Parcelable> void writeTypedObject(@Nullable T val,
int parcelableFlags) {
- assertNotRecycled();
if (val != null) {
writeInt(1);
val.writeToParcel(this, parcelableFlags);
@@ -2524,7 +2420,6 @@
*/
public <T> void writeFixedArray(@Nullable T val, int parcelableFlags,
@NonNull int... dimensions) {
- assertNotRecycled();
if (val == null) {
writeInt(-1);
return;
@@ -2636,7 +2531,6 @@
* should be used).</p>
*/
public final void writeValue(@Nullable Object v) {
- assertNotRecycled();
if (v instanceof LazyValue) {
LazyValue value = (LazyValue) v;
value.writeToParcel(this);
@@ -2754,7 +2648,6 @@
* @hide
*/
public void writeValue(int type, @Nullable Object v) {
- assertNotRecycled();
switch (type) {
case VAL_NULL:
break;
@@ -2868,7 +2761,6 @@
* {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
*/
public final void writeParcelable(@Nullable Parcelable p, int parcelableFlags) {
- assertNotRecycled();
if (p == null) {
writeString(null);
return;
@@ -2884,7 +2776,6 @@
* @see #readParcelableCreator
*/
public final void writeParcelableCreator(@NonNull Parcelable p) {
- assertNotRecycled();
String name = p.getClass().getName();
writeString(name);
}
@@ -2923,7 +2814,6 @@
*/
@TestApi
public boolean allowSquashing() {
- assertNotRecycled();
boolean previous = mAllowSquashing;
mAllowSquashing = true;
return previous;
@@ -2935,7 +2825,6 @@
*/
@TestApi
public void restoreAllowSquashing(boolean previous) {
- assertNotRecycled();
mAllowSquashing = previous;
if (!mAllowSquashing) {
mWrittenSquashableParcelables = null;
@@ -2992,7 +2881,6 @@
* @hide
*/
public boolean maybeWriteSquashed(@NonNull Parcelable p) {
- assertNotRecycled();
if (!mAllowSquashing) {
// Don't squash, and don't put it in the map either.
writeInt(0);
@@ -3043,7 +2931,6 @@
@SuppressWarnings("unchecked")
@Nullable
public <T extends Parcelable> T readSquashed(SquashReadHelper<T> reader) {
- assertNotRecycled();
final int offset = readInt();
final int pos = dataPosition();
@@ -3077,7 +2964,6 @@
* using the other approaches to writing data in to a Parcel.
*/
public final void writeSerializable(@Nullable Serializable s) {
- assertNotRecycled();
if (s == null) {
writeString(null);
return;
@@ -3130,7 +3016,6 @@
*/
@RavenwoodReplace(blockedBy = AppOpsManager.class)
public final void writeException(@NonNull Exception e) {
- assertNotRecycled();
AppOpsManager.prefixParcelWithAppOpsIfNeeded(this);
int code = getExceptionCode(e);
@@ -3211,7 +3096,6 @@
/** @hide */
public void writeStackTrace(@NonNull Throwable e) {
- assertNotRecycled();
final int sizePosition = dataPosition();
writeInt(0); // Header size will be filled in later
StackTraceElement[] stackTrace = e.getStackTrace();
@@ -3237,7 +3121,6 @@
*/
@RavenwoodReplace(blockedBy = AppOpsManager.class)
public final void writeNoException() {
- assertNotRecycled();
AppOpsManager.prefixParcelWithAppOpsIfNeeded(this);
// Despite the name of this function ("write no exception"),
@@ -3281,7 +3164,6 @@
* @see #writeNoException
*/
public final void readException() {
- assertNotRecycled();
int code = readExceptionCode();
if (code != 0) {
String msg = readString();
@@ -3305,7 +3187,6 @@
@UnsupportedAppUsage
@TestApi
public final int readExceptionCode() {
- assertNotRecycled();
int code = readInt();
if (code == EX_HAS_NOTED_APPOPS_REPLY_HEADER) {
AppOpsManager.readAndLogNotedAppops(this);
@@ -3339,7 +3220,6 @@
* @param msg The exception message.
*/
public final void readException(int code, String msg) {
- assertNotRecycled();
String remoteStackTrace = null;
final int remoteStackPayloadSize = readInt();
if (remoteStackPayloadSize > 0) {
@@ -3370,7 +3250,6 @@
/** @hide */
public Exception createExceptionOrNull(int code, String msg) {
- assertNotRecycled();
switch (code) {
case EX_PARCELABLE:
if (readInt() > 0) {
@@ -3403,7 +3282,6 @@
* Read an integer value from the parcel at the current dataPosition().
*/
public final int readInt() {
- assertNotRecycled();
return nativeReadInt(mNativePtr);
}
@@ -3411,7 +3289,6 @@
* Read a long integer value from the parcel at the current dataPosition().
*/
public final long readLong() {
- assertNotRecycled();
return nativeReadLong(mNativePtr);
}
@@ -3420,7 +3297,6 @@
* dataPosition().
*/
public final float readFloat() {
- assertNotRecycled();
return nativeReadFloat(mNativePtr);
}
@@ -3429,7 +3305,6 @@
* current dataPosition().
*/
public final double readDouble() {
- assertNotRecycled();
return nativeReadDouble(mNativePtr);
}
@@ -3438,19 +3313,16 @@
*/
@Nullable
public final String readString() {
- assertNotRecycled();
return readString16();
}
/** {@hide} */
public final @Nullable String readString8() {
- assertNotRecycled();
return mReadWriteHelper.readString8(this);
}
/** {@hide} */
public final @Nullable String readString16() {
- assertNotRecycled();
return mReadWriteHelper.readString16(this);
}
@@ -3462,19 +3334,16 @@
* @hide
*/
public @Nullable String readStringNoHelper() {
- assertNotRecycled();
return readString16NoHelper();
}
/** {@hide} */
public @Nullable String readString8NoHelper() {
- assertNotRecycled();
return nativeReadString8(mNativePtr);
}
/** {@hide} */
public @Nullable String readString16NoHelper() {
- assertNotRecycled();
return nativeReadString16(mNativePtr);
}
@@ -3482,7 +3351,6 @@
* Read a boolean value from the parcel at the current dataPosition().
*/
public final boolean readBoolean() {
- assertNotRecycled();
return readInt() != 0;
}
@@ -3493,7 +3361,6 @@
@UnsupportedAppUsage
@Nullable
public final CharSequence readCharSequence() {
- assertNotRecycled();
return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this);
}
@@ -3501,7 +3368,6 @@
* Read an object from the parcel at the current dataPosition().
*/
public final IBinder readStrongBinder() {
- assertNotRecycled();
final IBinder result = nativeReadStrongBinder(mNativePtr);
// If it's a reply from a method with @PropagateAllowBlocking, then inherit allow-blocking
@@ -3517,7 +3383,6 @@
* Read a FileDescriptor from the parcel at the current dataPosition().
*/
public final ParcelFileDescriptor readFileDescriptor() {
- assertNotRecycled();
FileDescriptor fd = nativeReadFileDescriptor(mNativePtr);
return fd != null ? new ParcelFileDescriptor(fd) : null;
}
@@ -3525,7 +3390,6 @@
/** {@hide} */
@UnsupportedAppUsage
public final FileDescriptor readRawFileDescriptor() {
- assertNotRecycled();
return nativeReadFileDescriptor(mNativePtr);
}
@@ -3536,7 +3400,6 @@
**/
@Nullable
public final FileDescriptor[] createRawFileDescriptorArray() {
- assertNotRecycled();
int N = readInt();
if (N < 0) {
return null;
@@ -3556,7 +3419,6 @@
* @return the FileDescriptor array, or null if the array is null.
**/
public final void readRawFileDescriptorArray(FileDescriptor[] val) {
- assertNotRecycled();
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
@@ -3571,7 +3433,6 @@
* Read a byte value from the parcel at the current dataPosition().
*/
public final byte readByte() {
- assertNotRecycled();
return (byte)(readInt() & 0xff);
}
@@ -3586,7 +3447,6 @@
*/
@Deprecated
public final void readMap(@NonNull Map outVal, @Nullable ClassLoader loader) {
- assertNotRecycled();
readMapInternal(outVal, loader, /* clazzKey */ null, /* clazzValue */ null);
}
@@ -3600,7 +3460,6 @@
public <K, V> void readMap(@NonNull Map<? super K, ? super V> outVal,
@Nullable ClassLoader loader, @NonNull Class<K> clazzKey,
@NonNull Class<V> clazzValue) {
- assertNotRecycled();
Objects.requireNonNull(clazzKey);
Objects.requireNonNull(clazzValue);
readMapInternal(outVal, loader, clazzKey, clazzValue);
@@ -3619,7 +3478,6 @@
*/
@Deprecated
public final void readList(@NonNull List outVal, @Nullable ClassLoader loader) {
- assertNotRecycled();
int N = readInt();
readListInternal(outVal, N, loader, /* clazz */ null);
}
@@ -3641,7 +3499,6 @@
*/
public <T> void readList(@NonNull List<? super T> outVal,
@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
- assertNotRecycled();
Objects.requireNonNull(clazz);
int n = readInt();
readListInternal(outVal, n, loader, clazz);
@@ -3661,7 +3518,6 @@
@Deprecated
@Nullable
public HashMap readHashMap(@Nullable ClassLoader loader) {
- assertNotRecycled();
return readHashMapInternal(loader, /* clazzKey */ null, /* clazzValue */ null);
}
@@ -3676,7 +3532,6 @@
@Nullable
public <K, V> HashMap<K, V> readHashMap(@Nullable ClassLoader loader,
@NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue) {
- assertNotRecycled();
Objects.requireNonNull(clazzKey);
Objects.requireNonNull(clazzValue);
return readHashMapInternal(loader, clazzKey, clazzValue);
@@ -3689,7 +3544,6 @@
*/
@Nullable
public final Bundle readBundle() {
- assertNotRecycled();
return readBundle(null);
}
@@ -3701,7 +3555,6 @@
*/
@Nullable
public final Bundle readBundle(@Nullable ClassLoader loader) {
- assertNotRecycled();
int length = readInt();
if (length < 0) {
if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
@@ -3722,7 +3575,6 @@
*/
@Nullable
public final PersistableBundle readPersistableBundle() {
- assertNotRecycled();
return readPersistableBundle(null);
}
@@ -3734,7 +3586,6 @@
*/
@Nullable
public final PersistableBundle readPersistableBundle(@Nullable ClassLoader loader) {
- assertNotRecycled();
int length = readInt();
if (length < 0) {
if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
@@ -3753,7 +3604,6 @@
*/
@NonNull
public final Size readSize() {
- assertNotRecycled();
final int width = readInt();
final int height = readInt();
return new Size(width, height);
@@ -3764,7 +3614,6 @@
*/
@NonNull
public final SizeF readSizeF() {
- assertNotRecycled();
final float width = readFloat();
final float height = readFloat();
return new SizeF(width, height);
@@ -3775,7 +3624,6 @@
*/
@Nullable
public final byte[] createByteArray() {
- assertNotRecycled();
return nativeCreateByteArray(mNativePtr);
}
@@ -3784,7 +3632,6 @@
* given byte array.
*/
public final void readByteArray(@NonNull byte[] val) {
- assertNotRecycled();
boolean valid = nativeReadByteArray(mNativePtr, val, (val != null) ? val.length : 0);
if (!valid) {
throw new RuntimeException("bad array lengths");
@@ -3797,7 +3644,6 @@
*/
@Nullable
public final byte[] readBlob() {
- assertNotRecycled();
return nativeReadBlob(mNativePtr);
}
@@ -3808,7 +3654,6 @@
@UnsupportedAppUsage
@Nullable
public final String[] readStringArray() {
- assertNotRecycled();
return createString16Array();
}
@@ -3818,7 +3663,6 @@
*/
@Nullable
public final CharSequence[] readCharSequenceArray() {
- assertNotRecycled();
CharSequence[] array = null;
int length = readInt();
@@ -3841,7 +3685,6 @@
*/
@Nullable
public final ArrayList<CharSequence> readCharSequenceList() {
- assertNotRecycled();
ArrayList<CharSequence> array = null;
int length = readInt();
@@ -3871,7 +3714,6 @@
@Deprecated
@Nullable
public ArrayList readArrayList(@Nullable ClassLoader loader) {
- assertNotRecycled();
return readArrayListInternal(loader, /* clazz */ null);
}
@@ -3894,7 +3736,6 @@
@Nullable
public <T> ArrayList<T> readArrayList(@Nullable ClassLoader loader,
@NonNull Class<? extends T> clazz) {
- assertNotRecycled();
Objects.requireNonNull(clazz);
return readArrayListInternal(loader, clazz);
}
@@ -3914,7 +3755,6 @@
@Deprecated
@Nullable
public Object[] readArray(@Nullable ClassLoader loader) {
- assertNotRecycled();
return readArrayInternal(loader, /* clazz */ null);
}
@@ -3936,7 +3776,6 @@
@SuppressLint({"ArrayReturn", "NullableCollection"})
@Nullable
public <T> T[] readArray(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
- assertNotRecycled();
Objects.requireNonNull(clazz);
return readArrayInternal(loader, clazz);
}
@@ -3956,7 +3795,6 @@
@Deprecated
@Nullable
public <T> SparseArray<T> readSparseArray(@Nullable ClassLoader loader) {
- assertNotRecycled();
return readSparseArrayInternal(loader, /* clazz */ null);
}
@@ -3978,7 +3816,6 @@
@Nullable
public <T> SparseArray<T> readSparseArray(@Nullable ClassLoader loader,
@NonNull Class<? extends T> clazz) {
- assertNotRecycled();
Objects.requireNonNull(clazz);
return readSparseArrayInternal(loader, clazz);
}
@@ -3990,7 +3827,6 @@
*/
@Nullable
public final SparseBooleanArray readSparseBooleanArray() {
- assertNotRecycled();
int N = readInt();
if (N < 0) {
return null;
@@ -4007,7 +3843,6 @@
*/
@Nullable
public final SparseIntArray readSparseIntArray() {
- assertNotRecycled();
int N = readInt();
if (N < 0) {
return null;
@@ -4032,7 +3867,6 @@
*/
@Nullable
public final <T> ArrayList<T> createTypedArrayList(@NonNull Parcelable.Creator<T> c) {
- assertNotRecycled();
int N = readInt();
if (N < 0) {
return null;
@@ -4056,7 +3890,6 @@
* @see #writeTypedList
*/
public final <T> void readTypedList(@NonNull List<T> list, @NonNull Parcelable.Creator<T> c) {
- assertNotRecycled();
int M = list.size();
int N = readInt();
int i = 0;
@@ -4086,7 +3919,6 @@
*/
public final @Nullable <T extends Parcelable> SparseArray<T> createTypedSparseArray(
@NonNull Parcelable.Creator<T> creator) {
- assertNotRecycled();
final int count = readInt();
if (count < 0) {
return null;
@@ -4116,7 +3948,6 @@
*/
public final @Nullable <T extends Parcelable> ArrayMap<String, T> createTypedArrayMap(
@NonNull Parcelable.Creator<T> creator) {
- assertNotRecycled();
final int count = readInt();
if (count < 0) {
return null;
@@ -4144,7 +3975,6 @@
*/
@Nullable
public final ArrayList<String> createStringArrayList() {
- assertNotRecycled();
int N = readInt();
if (N < 0) {
return null;
@@ -4171,7 +4001,6 @@
*/
@Nullable
public final ArrayList<IBinder> createBinderArrayList() {
- assertNotRecycled();
int N = readInt();
if (N < 0) {
return null;
@@ -4199,7 +4028,6 @@
@Nullable
public final <T extends IInterface> ArrayList<T> createInterfaceArrayList(
@NonNull Function<IBinder, T> asInterface) {
- assertNotRecycled();
int N = readInt();
if (N < 0) {
return null;
@@ -4220,7 +4048,6 @@
* @see #writeStringList
*/
public final void readStringList(@NonNull List<String> list) {
- assertNotRecycled();
int M = list.size();
int N = readInt();
int i = 0;
@@ -4242,7 +4069,6 @@
* @see #writeBinderList
*/
public final void readBinderList(@NonNull List<IBinder> list) {
- assertNotRecycled();
int M = list.size();
int N = readInt();
int i = 0;
@@ -4265,7 +4091,6 @@
*/
public final <T extends IInterface> void readInterfaceList(@NonNull List<T> list,
@NonNull Function<IBinder, T> asInterface) {
- assertNotRecycled();
int M = list.size();
int N = readInt();
int i = 0;
@@ -4297,7 +4122,6 @@
@NonNull
public final <T extends Parcelable> List<T> readParcelableList(@NonNull List<T> list,
@Nullable ClassLoader cl) {
- assertNotRecycled();
return readParcelableListInternal(list, cl, /*clazz*/ null);
}
@@ -4319,7 +4143,6 @@
@NonNull
public <T> List<T> readParcelableList(@NonNull List<T> list,
@Nullable ClassLoader cl, @NonNull Class<? extends T> clazz) {
- assertNotRecycled();
Objects.requireNonNull(list);
Objects.requireNonNull(clazz);
return readParcelableListInternal(list, cl, clazz);
@@ -4365,7 +4188,6 @@
*/
@Nullable
public final <T> T[] createTypedArray(@NonNull Parcelable.Creator<T> c) {
- assertNotRecycled();
int N = readInt();
if (N < 0) {
return null;
@@ -4379,7 +4201,6 @@
}
public final <T> void readTypedArray(@NonNull T[] val, @NonNull Parcelable.Creator<T> c) {
- assertNotRecycled();
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
@@ -4396,7 +4217,6 @@
*/
@Deprecated
public final <T> T[] readTypedArray(Parcelable.Creator<T> c) {
- assertNotRecycled();
return createTypedArray(c);
}
@@ -4413,7 +4233,6 @@
*/
@Nullable
public final <T> T readTypedObject(@NonNull Parcelable.Creator<T> c) {
- assertNotRecycled();
if (readInt() != 0) {
return c.createFromParcel(this);
} else {
@@ -4440,7 +4259,6 @@
* @see #readTypedArray
*/
public <T> void readFixedArray(@NonNull T val) {
- assertNotRecycled();
Class<?> componentType = val.getClass().getComponentType();
if (componentType == boolean.class) {
readBooleanArray((boolean[]) val);
@@ -4481,7 +4299,6 @@
*/
public <T, S extends IInterface> void readFixedArray(@NonNull T val,
@NonNull Function<IBinder, S> asInterface) {
- assertNotRecycled();
Class<?> componentType = val.getClass().getComponentType();
if (IInterface.class.isAssignableFrom(componentType)) {
readInterfaceArray((S[]) val, asInterface);
@@ -4508,7 +4325,6 @@
*/
public <T, S extends Parcelable> void readFixedArray(@NonNull T val,
@NonNull Parcelable.Creator<S> c) {
- assertNotRecycled();
Class<?> componentType = val.getClass().getComponentType();
if (Parcelable.class.isAssignableFrom(componentType)) {
readTypedArray((S[]) val, c);
@@ -4566,7 +4382,6 @@
*/
@Nullable
public <T> T createFixedArray(@NonNull Class<T> cls, @NonNull int... dimensions) {
- assertNotRecycled();
// Check if type matches with dimensions
// If type is one-dimensional array, delegate to other creators
// Otherwise, create an multi-dimensional array at once and then fill it with readFixedArray
@@ -4640,7 +4455,6 @@
@Nullable
public <T, S extends IInterface> T createFixedArray(@NonNull Class<T> cls,
@NonNull Function<IBinder, S> asInterface, @NonNull int... dimensions) {
- assertNotRecycled();
// Check if type matches with dimensions
// If type is one-dimensional array, delegate to other creators
// Otherwise, create an multi-dimensional array at once and then fill it with readFixedArray
@@ -4701,7 +4515,6 @@
@Nullable
public <T, S extends Parcelable> T createFixedArray(@NonNull Class<T> cls,
@NonNull Parcelable.Creator<S> c, @NonNull int... dimensions) {
- assertNotRecycled();
// Check if type matches with dimensions
// If type is one-dimensional array, delegate to other creators
// Otherwise, create an multi-dimensional array at once and then fill it with readFixedArray
@@ -4765,7 +4578,6 @@
*/
public final <T extends Parcelable> void writeParcelableArray(@Nullable T[] value,
int parcelableFlags) {
- assertNotRecycled();
if (value != null) {
int N = value.length;
writeInt(N);
@@ -4784,7 +4596,6 @@
*/
@Nullable
public final Object readValue(@Nullable ClassLoader loader) {
- assertNotRecycled();
return readValue(loader, /* clazz */ null);
}
@@ -4840,7 +4651,6 @@
*/
@Nullable
public Object readLazyValue(@Nullable ClassLoader loader) {
- assertNotRecycled();
int start = dataPosition();
int type = readInt();
if (isLengthPrefixed(type)) {
@@ -5243,7 +5053,6 @@
@Deprecated
@Nullable
public final <T extends Parcelable> T readParcelable(@Nullable ClassLoader loader) {
- assertNotRecycled();
return readParcelableInternal(loader, /* clazz */ null);
}
@@ -5263,7 +5072,6 @@
*/
@Nullable
public <T> T readParcelable(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
- assertNotRecycled();
Objects.requireNonNull(clazz);
return readParcelableInternal(loader, clazz);
}
@@ -5292,7 +5100,6 @@
@Nullable
public final <T extends Parcelable> T readCreator(@NonNull Parcelable.Creator<?> creator,
@Nullable ClassLoader loader) {
- assertNotRecycled();
if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
Parcelable.ClassLoaderCreator<?> classLoaderCreator =
(Parcelable.ClassLoaderCreator<?>) creator;
@@ -5320,7 +5127,6 @@
@Deprecated
@Nullable
public final Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader loader) {
- assertNotRecycled();
return readParcelableCreatorInternal(loader, /* clazz */ null);
}
@@ -5341,7 +5147,6 @@
@Nullable
public <T> Parcelable.Creator<T> readParcelableCreator(
@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
- assertNotRecycled();
Objects.requireNonNull(clazz);
return readParcelableCreatorInternal(loader, clazz);
}
@@ -5464,7 +5269,6 @@
@Deprecated
@Nullable
public Parcelable[] readParcelableArray(@Nullable ClassLoader loader) {
- assertNotRecycled();
return readParcelableArrayInternal(loader, /* clazz */ null);
}
@@ -5485,7 +5289,6 @@
@SuppressLint({"ArrayReturn", "NullableCollection"})
@Nullable
public <T> T[] readParcelableArray(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
- assertNotRecycled();
return readParcelableArrayInternal(loader, requireNonNull(clazz));
}
@@ -5519,7 +5322,6 @@
@Deprecated
@Nullable
public Serializable readSerializable() {
- assertNotRecycled();
return readSerializableInternal(/* loader */ null, /* clazz */ null);
}
@@ -5536,7 +5338,6 @@
*/
@Nullable
public <T> T readSerializable(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
- assertNotRecycled();
Objects.requireNonNull(clazz);
return readSerializableInternal(
loader == null ? getClass().getClassLoader() : loader, clazz);
@@ -5778,7 +5579,6 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public void readArrayMap(@NonNull ArrayMap<? super String, Object> outVal,
@Nullable ClassLoader loader) {
- assertNotRecycled();
final int N = readInt();
if (N < 0) {
return;
@@ -5795,7 +5595,6 @@
*/
@UnsupportedAppUsage
public @Nullable ArraySet<? extends Object> readArraySet(@Nullable ClassLoader loader) {
- assertNotRecycled();
final int size = readInt();
if (size < 0) {
return null;
@@ -5935,7 +5734,6 @@
* @hide For testing
*/
public long getOpenAshmemSize() {
- assertNotRecycled();
return nativeGetOpenAshmemSize(mNativePtr);
}
diff --git a/core/java/android/os/TestLooperManager.java b/core/java/android/os/TestLooperManager.java
index 4b16c1d..e216992 100644
--- a/core/java/android/os/TestLooperManager.java
+++ b/core/java/android/os/TestLooperManager.java
@@ -14,6 +14,8 @@
package android.os;
+import android.annotation.FlaggedApi;
+import android.annotation.Nullable;
import android.util.ArraySet;
import java.util.concurrent.LinkedBlockingQueue;
@@ -93,9 +95,52 @@
}
/**
- * Releases the looper to continue standard looping and processing of messages,
- * no further interactions with TestLooperManager will be allowed after
- * release() has been called.
+ * Retrieves and removes the next message that should be executed by this queue.
+ * If the queue is empty or no messages are deliverable, returns null.
+ * This method never blocks.
+ *
+ * <p>Callers should always call {@link #recycle(Message)} on the message when all interactions
+ * with it have completed.
+ */
+ @FlaggedApi(Flags.FLAG_MESSAGE_QUEUE_TESTABILITY)
+ @Nullable
+ public Message poll() {
+ checkReleased();
+ return mQueue.pollForTest();
+ }
+
+ /**
+ * Retrieves, but does not remove, the values of {@link Message#when} of next message that
+ * should be executed by this queue.
+ * If the queue is empty or no messages are deliverable, returns null.
+ * This method never blocks.
+ *
+ * <p>Callers should always call {@link #recycle(Message)} on the message when all interactions
+ * with it have completed.
+ */
+ @FlaggedApi(Flags.FLAG_MESSAGE_QUEUE_TESTABILITY)
+ @SuppressWarnings("AutoBoxing") // box the primitive long, or return null to indicate no value
+ @Nullable
+ public Long peekWhen() {
+ checkReleased();
+ return mQueue.peekWhenForTest();
+ }
+
+ /**
+ * Checks whether the Looper is currently blocked on a sync barrier.
+ *
+ * A Looper is blocked on a sync barrier if there is a Message in the Looper's
+ * queue that is ready for execution but is behind a sync barrier
+ */
+ @FlaggedApi(Flags.FLAG_MESSAGE_QUEUE_TESTABILITY)
+ public boolean isBlockedOnSyncBarrier() {
+ checkReleased();
+ return mQueue.isBlockedOnSyncBarrier();
+ }
+
+ /**
+ * Releases the looper to continue standard looping and processing of messages, no further
+ * interactions with TestLooperManager will be allowed after release() has been called.
*/
public void release() {
synchronized (sHeldLoopers) {
diff --git a/core/java/android/os/instrumentation/IDynamicInstrumentationManager.aidl b/core/java/android/os/instrumentation/IDynamicInstrumentationManager.aidl
index c45c51d..af56bfe 100644
--- a/core/java/android/os/instrumentation/IDynamicInstrumentationManager.aidl
+++ b/core/java/android/os/instrumentation/IDynamicInstrumentationManager.aidl
@@ -16,7 +16,7 @@
package android.os.instrumentation;
-import android.os.instrumentation.ExecutableMethodFileOffsets;
+import android.os.instrumentation.IOffsetCallback;
import android.os.instrumentation.MethodDescriptor;
import android.os.instrumentation.TargetProcess;
@@ -28,6 +28,7 @@
interface IDynamicInstrumentationManager {
/** Provides ART metadata about the described compiled method within the target process */
@PermissionManuallyEnforced
- @nullable ExecutableMethodFileOffsets getExecutableMethodFileOffsets(
- in TargetProcess targetProcess, in MethodDescriptor methodDescriptor);
+ void getExecutableMethodFileOffsets(
+ in TargetProcess targetProcess, in MethodDescriptor methodDescriptor,
+ in IOffsetCallback callback);
}
diff --git a/core/java/android/os/instrumentation/IOffsetCallback.aidl b/core/java/android/os/instrumentation/IOffsetCallback.aidl
new file mode 100644
index 0000000..a28c93f
--- /dev/null
+++ b/core/java/android/os/instrumentation/IOffsetCallback.aidl
@@ -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 android.os.instrumentation;
+
+import android.os.instrumentation.ExecutableMethodFileOffsets;
+
+/**
+ * System private API for providing dynamic instrumentation offset results.
+ *
+ * {@hide}
+ */
+oneway interface IOffsetCallback {
+ void onResult(in @nullable ExecutableMethodFileOffsets offsets);
+}
diff --git a/core/java/android/os/instrumentation/MethodDescriptorParser.java b/core/java/android/os/instrumentation/MethodDescriptorParser.java
new file mode 100644
index 0000000..57fc44f
--- /dev/null
+++ b/core/java/android/os/instrumentation/MethodDescriptorParser.java
@@ -0,0 +1,82 @@
+/*
+ * 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.instrumentation;
+
+import android.annotation.NonNull;
+
+import java.lang.reflect.Method;
+
+/**
+ * A utility class for dynamic instrumentation / uprobestats.
+ *
+ * @hide
+ */
+public final class MethodDescriptorParser {
+
+ /**
+ * Parses a {@link MethodDescriptor} (in string representation) into a {@link Method}.
+ */
+ public static Method parseMethodDescriptor(ClassLoader classLoader,
+ @NonNull MethodDescriptor descriptor) {
+ try {
+ Class<?> javaClass = classLoader.loadClass(descriptor.fullyQualifiedClassName);
+ Class<?>[] parameters = new Class[descriptor.fullyQualifiedParameters.length];
+ for (int i = 0; i < descriptor.fullyQualifiedParameters.length; i++) {
+ String typeName = descriptor.fullyQualifiedParameters[i];
+ boolean isArrayType = typeName.endsWith("[]");
+ if (isArrayType) {
+ typeName = typeName.substring(0, typeName.length() - 2);
+ }
+ switch (typeName) {
+ case "boolean":
+ parameters[i] = isArrayType ? boolean.class.arrayType() : boolean.class;
+ break;
+ case "byte":
+ parameters[i] = isArrayType ? byte.class.arrayType() : byte.class;
+ break;
+ case "char":
+ parameters[i] = isArrayType ? char.class.arrayType() : char.class;
+ break;
+ case "short":
+ parameters[i] = isArrayType ? short.class.arrayType() : short.class;
+ break;
+ case "int":
+ parameters[i] = isArrayType ? int.class.arrayType() : int.class;
+ break;
+ case "long":
+ parameters[i] = isArrayType ? long.class.arrayType() : long.class;
+ break;
+ case "float":
+ parameters[i] = isArrayType ? float.class.arrayType() : float.class;
+ break;
+ case "double":
+ parameters[i] = isArrayType ? double.class.arrayType() : double.class;
+ break;
+ default:
+ parameters[i] = isArrayType ? classLoader.loadClass(typeName).arrayType()
+ : classLoader.loadClass(typeName);
+ }
+ }
+
+ return javaClass.getDeclaredMethod(descriptor.methodName, parameters);
+ } catch (ClassNotFoundException | NoSuchMethodException e) {
+ throw new IllegalArgumentException(
+ "The specified method cannot be found. Is this descriptor valid? "
+ + descriptor, e);
+ }
+ }
+}
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index 2c4883f..aacc6e2 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -492,3 +492,13 @@
description: "This flag is used to enable the role system_vendor_intelligence"
bug: "377553620"
}
+
+flag {
+ name: "fine_power_monitor_permission"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "permissions"
+ description: "Add support for fine-grained PowerMonitor readings"
+ bug: "341941666"
+}
+
diff --git a/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java b/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java
index 64a3f0f..568a6d7 100644
--- a/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java
+++ b/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java
@@ -38,23 +38,30 @@
/**
* Client message associated with the request to disable secure lock on the device. This message
* will be shown on the device when secure lock mode is disabled.
+ *
+ * Since this text is shown in a restricted lockscreen state, typeface properties such as color,
+ * font weight, or other formatting may not be honored.
*/
- private final @NonNull String mMessage;
+ private final @NonNull CharSequence mMessage;
/**
* Creates DisableSecureLockDeviceParams with the given params.
*
* @param message Allows clients to pass in a message with information about the request to
* disable secure lock on the device. This message will be shown to the user when
- * secure lock mode is disabled. If an empty string is provided, it will default
- * to a system-defined string (e.g. "Secure lock mode has been disabled.")
+ * secure lock mode is disabled. If an empty CharSequence is provided, it will
+ * default to a system-defined CharSequence (e.g. "Secure lock mode has been
+ * disabled.")
+ *
+ * Since this text is shown in a restricted lockscreen state, typeface properties
+ * such as color, font weight, or other formatting may not be honored.
*/
- public DisableSecureLockDeviceParams(@NonNull String message) {
+ public DisableSecureLockDeviceParams(@NonNull CharSequence message) {
mMessage = message;
}
private DisableSecureLockDeviceParams(@NonNull Parcel in) {
- mMessage = Objects.requireNonNull(in.readString8());
+ mMessage = Objects.requireNonNull(in.readCharSequence());
}
public static final @NonNull Creator<DisableSecureLockDeviceParams> CREATOR =
@@ -77,6 +84,6 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString8(mMessage);
+ dest.writeCharSequence(mMessage);
}
}
diff --git a/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java b/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java
index 1d72772..dfa391f 100644
--- a/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java
+++ b/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java
@@ -38,23 +38,30 @@
/**
* Client message associated with the request to enable secure lock on the device. This message
* will be shown on the device when secure lock mode is enabled.
+ *
+ * Since this text is shown in a restricted lockscreen state, typeface properties such as color,
+ * font weight, or other formatting may not be honored.
*/
- private final @NonNull String mMessage;
+ private final @NonNull CharSequence mMessage;
/**
* Creates EnableSecureLockDeviceParams with the given params.
*
* @param message Allows clients to pass in a message with information about the request to
* enable secure lock on the device. This message will be shown to the user when
- * secure lock mode is enabled. If an empty string is provided, it will default
- * to a system-defined string (e.g. "Device is securely locked remotely.")
+ * secure lock mode is enabled. If an empty CharSequence is provided, it will
+ * default to a system-defined CharSequence (e.g. "Device is securely locked
+ * remotely.")
+ *
+ * Since this text is shown in a restricted lockscreen state, typeface properties
+ * such as color, font weight, or other formatting may not be honored.
*/
- public EnableSecureLockDeviceParams(@NonNull String message) {
+ public EnableSecureLockDeviceParams(@NonNull CharSequence message) {
mMessage = message;
}
private EnableSecureLockDeviceParams(@NonNull Parcel in) {
- mMessage = Objects.requireNonNull(in.readString8());
+ mMessage = Objects.requireNonNull(in.readCharSequence());
}
public static final @NonNull Creator<EnableSecureLockDeviceParams> CREATOR =
@@ -77,6 +84,6 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString8(mMessage);
+ dest.writeCharSequence(mMessage);
}
}
diff --git a/core/java/android/service/autofill/FillEventHistory.java b/core/java/android/service/autofill/FillEventHistory.java
index fba8e42..6d62a2c 100644
--- a/core/java/android/service/autofill/FillEventHistory.java
+++ b/core/java/android/service/autofill/FillEventHistory.java
@@ -341,7 +341,7 @@
/** Credential Manager suggestions are shown instead of Autofill suggestion */
@FlaggedApi(FLAG_AUTOFILL_W_METRICS)
- public static final int UI_TYPE_CREDMAN = 4;
+ public static final int UI_TYPE_CREDENTIAL_MANAGER = 4;
/** @hide */
@IntDef(prefix = { "UI_TYPE_" }, value = {
diff --git a/services/core/java/com/android/server/notification/RateEstimator.java b/core/java/android/service/notification/RateEstimator.java
similarity index 92%
rename from services/core/java/com/android/server/notification/RateEstimator.java
rename to core/java/android/service/notification/RateEstimator.java
index eda96ac..04789c1 100644
--- a/services/core/java/com/android/server/notification/RateEstimator.java
+++ b/core/java/android/service/notification/RateEstimator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 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.
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.server.notification;
+package android.service.notification;
/**
@@ -22,7 +22,7 @@
*
* {@hide}
*/
-class RateEstimator {
+public class RateEstimator {
private static final double RATE_ALPHA = 0.7;
private static final double MINIMUM_DT = 0.0005;
diff --git a/core/java/android/speech/tts/EventLogTags.logtags b/core/java/android/speech/tts/EventLogTags.logtags
index e209a28..5ba2bae 100644
--- a/core/java/android/speech/tts/EventLogTags.logtags
+++ b/core/java/android/speech/tts/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.speech.tts;
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index c9d560c..802bddd 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -1301,17 +1301,23 @@
}
/**
- * Represents the {@link FrameRateCategory} for the Normal frame rate
+ * Normal category determines the framework's recommended normal frame rate.
+ * Opt for this normal rate unless a higher frame rate significantly enhances
+ * the user experience.
*
- * @see FrameRateCategory
+ * @see #getSuggestedFrameRate(int)
+ * @see #FRAME_RATE_CATEGORY_HIGH
*/
@FlaggedApi(FLAG_ENABLE_GET_SUGGESTED_FRAME_RATE)
public static final int FRAME_RATE_CATEGORY_NORMAL = 0;
/**
- * Represents the {@link FrameRateCategory} for the High frame rate
+ * High category determines the framework's recommended high frame rate.
+ * Opt for this high rate when a higher frame rate significantly enhances
+ * the user experience.
*
- * @see FrameRateCategory
+ * @see #getSuggestedFrameRate(int)
+ * @see #FRAME_RATE_CATEGORY_NORMAL
*/
@FlaggedApi(FLAG_ENABLE_GET_SUGGESTED_FRAME_RATE)
public static final int FRAME_RATE_CATEGORY_HIGH = 1;
@@ -1332,22 +1338,17 @@
*
* <p> For example, an animation that does not require fast render rates can use
* the {@link #FRAME_RATE_CATEGORY_NORMAL} to get the suggested frame rate.
- * The suggested frame rate then can be used in the
- * {@link Surface.FrameRateParams.Builder#setDesiredRateRange} for desiredMinRate.
*
* <pre>{@code
* float desiredMinRate = display.getSuggestedFrameRate(FRAME_RATE_CATEGORY_NORMAL);
- * Surface.FrameRateParams params = new Surface.FrameRateParams.Builder().
- * setDesiredRateRange(desiredMinRate, Float.MAX).build();
- * surface.setFrameRate(params);
+ * surface.setFrameRate(desiredMinRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT);
* }</pre>
* </p>
*
* @param category either {@link #FRAME_RATE_CATEGORY_NORMAL}
* or {@link #FRAME_RATE_CATEGORY_HIGH}
*
- * @see Surface#setFrameRate(Surface.FrameRateParams)
- * @see SurfaceControl.Transaction#setFrameRate(SurfaceControl, Surface.FrameRateParams)
+ * @see Surface#setFrameRate(float, int)
* @throws IllegalArgumentException when category is not {@link #FRAME_RATE_CATEGORY_NORMAL}
* or {@link #FRAME_RATE_CATEGORY_HIGH}
*/
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 5da4985..072a037 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -933,6 +933,27 @@
void detachWindowContext(IBinder clientToken);
/**
+ * Reparents the {@link android.window.WindowContext} to the
+ * {@link com.android.server.wm.DisplayArea} on another display.
+ * This method also reparent the WindowContext associated WindowToken to another display if
+ * necessary.
+ * <p>
+ * {@code type} and {@code options} must be the same as the previous call of
+ * {@link #attachWindowContextToDisplayArea} on the same Context otherwise this will fail
+ * silently.
+ *
+ * @param appThread the process that the window context is on.
+ * @param clientToken the window context's token
+ * @param type The window type of the WindowContext
+ * @param displayId The new display id this context windows should be parented to
+ * @param options Bundle the context was created with
+ *
+ * @return True if the operation was successful, False otherwise.
+ */
+ boolean reparentWindowContextToDisplayArea(in IApplicationThread appThread,
+ IBinder clientToken, int displayId);
+
+ /**
* Registers a listener, which is to be called whenever cross-window blur is enabled/disabled.
*
* @param listener the listener to be registered
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 67050e0..213ece0 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -296,8 +296,8 @@
@SoftInputModeFlags int softInputMode, int windowFlags) {
final int softInputAdjustMode = softInputMode & SOFT_INPUT_MASK_ADJUST;
final int visibleInsetsTypes = softInputAdjustMode != SOFT_INPUT_ADJUST_NOTHING
- ? systemBars() | ime()
- : systemBars();
+ ? systemBars() | displayCutout() | ime()
+ : systemBars() | displayCutout();
@InsetsType int forceConsumingTypes = 0;
Insets insets = Insets.NONE;
for (int i = mSources.size() - 1; i >= 0; i--) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0681745..d15b0f5 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -17184,7 +17184,7 @@
final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
final WindowMetrics metrics = windowManager.getMaximumWindowMetrics();
final Insets insets = metrics.getWindowInsets().getInsets(
- WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout());
+ WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout());
outRect.set(metrics.getBounds());
outRect.inset(insets);
outRect.offsetTo(0, 0);
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 63bf392..9e97a8e 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -591,7 +591,7 @@
res.getBoolean(
com.android.internal.R.bool.config_viewBasedRotaryEncoderHapticsEnabled);
mViewTouchScreenHapticScrollFeedbackEnabled =
- Flags.enableTouchScrollFeedback()
+ Flags.enableScrollFeedbackForTouch()
? res.getBoolean(
com.android.internal.R.bool
.config_viewTouchScreenHapticScrollFeedbackEnabled)
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 1be7f48..43a946a 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -87,8 +87,12 @@
* <p>This value is added to mainly help with debugging purpose.
*/
@FlaggedApi(FLAG_AUTOFILL_W_METRICS)
+ @SuppressWarnings(
+ "ActionValue") // Lint expects this as
+ // android.view.contentcapture.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER
+ // but should not have contentcapture
public static final String EXTRA_VIRTUAL_STRUCTURE_TYPE =
- "android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_TYPE";
+ "android.view.extra.VIRTUAL_STRUCTURE_TYPE";
/**
* Key used for specifying the version of the view that generated the virtual structure for
@@ -98,8 +102,12 @@
* "104.0.5112.69", then the value should be "104.0.5112.69"
*/
@FlaggedApi(FLAG_AUTOFILL_W_METRICS)
+ @SuppressWarnings(
+ "ActionValue") // Lint expects this as
+ // android.view.contentcapture.extra.VIRTUAL_STRUCTURE_TYPE
+ // but should not have contentcapture
public static final String EXTRA_VIRTUAL_STRUCTURE_VERSION_NUMBER =
- "android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER";
+ "android.view.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER";
/**
* Set the identifier for this view.
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 1de0474..60e528c 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -26,6 +26,7 @@
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.service.autofill.Flags.improveFillDialogAconfig;
import static android.service.autofill.Flags.relayoutFix;
import static android.view.ContentInfo.SOURCE_AUTOFILL;
import static android.view.autofill.Helper.sDebug;
@@ -787,6 +788,11 @@
private AutofillStateFingerprint mAutofillStateFingerprint;
+ /**
+ * Whether improveFillDialog feature is enabled or not.
+ */
+ private boolean mImproveFillDialogEnabled;
+
/** @hide */
public interface AutofillClient {
/**
@@ -1017,6 +1023,17 @@
mRelayoutFix = relayoutFix() && AutofillFeatureFlags.enableRelayoutFixes();
mRelativePositionForRelayout = AutofillFeatureFlags.enableRelativeLocationForRelayout();
mIsCredmanIntegrationEnabled = Flags.autofillCredmanIntegration();
+ mImproveFillDialogEnabled =
+ improveFillDialogAconfig() && AutofillFeatureFlags.isImproveFillDialogEnabled();
+ }
+
+ /**
+ * Whether improvement to fill dialog is enabled.
+ *
+ * @hide
+ */
+ public boolean isImproveFillDialogEnabled() {
+ return mImproveFillDialogEnabled;
}
/**
@@ -1679,6 +1696,11 @@
private void notifyViewReadyInner(AutofillId id, @Nullable String[] autofillHints,
boolean isCredmanRequested) {
+ if (isImproveFillDialogEnabled() && !isCredmanRequested) {
+ // We do not want to send pre-trigger request.
+ // TODO(b/377868687): verify if we can remove the flow for isCredmanRequested too.
+ return;
+ }
if (sDebug) {
Log.d(TAG, "notifyViewReadyInner:" + id);
}
@@ -2046,6 +2068,34 @@
}
/**
+ * Notify autofill system that IME animation has started
+ * @param startTimeMs start time as measured by SystemClock.elapsedRealtime()
+ */
+ void notifyImeAnimationStart(long startTimeMs) {
+ try {
+ mService.notifyImeAnimationStart(mSessionId, startTimeMs, mContext.getUserId());
+ } catch (RemoteException e) {
+ // The failure could be a consequence of something going wrong on the
+ // server side. Just log the exception and move-on.
+ Log.w(TAG, "notifyImeAnimationStart(): RemoteException caught but ignored " + e);
+ }
+ }
+
+ /**
+ * Notify autofill system that IME animation has ended
+ * @param endTimeMs end time as measured by SystemClock.elapsedRealtime()
+ */
+ void notifyImeAnimationEnd(long endTimeMs) {
+ try {
+ mService.notifyImeAnimationEnd(mSessionId, endTimeMs, mContext.getUserId());
+ } catch (RemoteException e) {
+ // The failure could be a consequence of something going wrong on the
+ // server side. Just log the exception and move-on.
+ Log.w(TAG, "notifyImeAnimationStart(): RemoteException caught but ignored " + e);
+ }
+ }
+
+ /**
* Called when a virtual view that supports autofill is exited.
*
* @param view the virtual view parent.
@@ -4050,6 +4100,10 @@
@FlaggedApi(FLAG_FILL_DIALOG_IMPROVEMENTS)
@Deprecated
public boolean showAutofillDialog(@NonNull View view) {
+ if (isImproveFillDialogEnabled()) {
+ Log.i(TAG, "showAutofillDialog() return false due to improve fill dialog");
+ return false;
+ }
Objects.requireNonNull(view);
if (shouldShowAutofillDialog(view, view.getAutofillId())) {
mShowAutofillDialogCalled = true;
@@ -4093,6 +4147,10 @@
@FlaggedApi(FLAG_FILL_DIALOG_IMPROVEMENTS)
@Deprecated
public boolean showAutofillDialog(@NonNull View view, int virtualId) {
+ if (isImproveFillDialogEnabled()) {
+ Log.i(TAG, "showAutofillDialog() return false due to improve fill dialog");
+ return false;
+ }
Objects.requireNonNull(view);
if (shouldShowAutofillDialog(view, getAutofillId(view, virtualId))) {
mShowAutofillDialogCalled = true;
@@ -4117,7 +4175,7 @@
return false;
}
- if (getImeStateFlag(view) == FLAG_IME_SHOWING) {
+ if (getImeStateFlag(view) == FLAG_IME_SHOWING && !isImproveFillDialogEnabled()) {
// IME is showing
return false;
}
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index f67405f..28f8577 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -70,4 +70,6 @@
void notifyNotExpiringResponseDuringAuth(int sessionId, int userId);
void notifyViewEnteredIgnoredDuringAuthCount(int sessionId, int userId);
void setAutofillIdsAttemptedForRefill(int sessionId, in List<AutofillId> ids, int userId);
+ void notifyImeAnimationStart(int sessionId, long startTimeMs, int userId);
+ void notifyImeAnimationEnd(int sessionId, long endTimeMs, int userId);
}
diff --git a/core/java/android/view/flags/scroll_capture.aconfig b/core/java/android/view/flags/scroll_capture.aconfig
index 9080b16..6dccbad 100644
--- a/core/java/android/view/flags/scroll_capture.aconfig
+++ b/core/java/android/view/flags/scroll_capture.aconfig
@@ -11,3 +11,12 @@
}
}
+flag {
+ name: "scroll_capture_relax_scroll_view_criteria"
+ namespace: "systemui"
+ description: "Treat all custom ViewGroups which support scrollTo as ScrollView"
+ bug: "189827634"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/java/android/view/flags/scroll_feedback_flags.aconfig b/core/java/android/view/flags/scroll_feedback_flags.aconfig
index ebda4d4..ddf6ff1 100644
--- a/core/java/android/view/flags/scroll_feedback_flags.aconfig
+++ b/core/java/android/view/flags/scroll_feedback_flags.aconfig
@@ -17,10 +17,10 @@
}
flag {
- namespace: "toolkit"
- name: "enable_touch_scroll_feedback"
+ namespace: "wear_frameworks"
+ name: "enable_scroll_feedback_for_touch"
description: "Enables touchscreen haptic scroll feedback"
- bug: "331830899"
+ bug: "382135785"
is_fixed_read_only: true
}
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index b606340..b929324 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -16,13 +16,20 @@
package android.view.textclassifier;
+import static android.Manifest.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE;
+
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Build;
import android.os.ServiceManager;
+import android.permission.flags.Flags;
import android.view.textclassifier.TextClassifier.TextClassifierType;
import com.android.internal.annotations.GuardedBy;
@@ -115,6 +122,29 @@
}
}
+ /**
+ * Returns a specific type of text classifier.
+ * If the specified text classifier cannot be found, this returns {@link TextClassifier#NO_OP}.
+ * <p>
+ *
+ * @see TextClassifier#CLASSIFIER_TYPE_SELF_PROVIDED
+ * @see TextClassifier#CLASSIFIER_TYPE_DEVICE_DEFAULT
+ * @see TextClassifier#CLASSIFIER_TYPE_ANDROID_DEFAULT
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ @RequiresPermission(ACCESS_TEXT_CLASSIFIER_BY_TYPE)
+ public TextClassifier getClassifier(@TextClassifierType int type) {
+ if (mContext.checkCallingOrSelfPermission(ACCESS_TEXT_CLASSIFIER_BY_TYPE)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Caller does not have permission " + ACCESS_TEXT_CLASSIFIER_BY_TYPE);
+ }
+ return getTextClassifier(type);
+ }
+
private TextClassificationConstants getSettings() {
synchronized (mLock) {
if (mSettings == null) {
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index ef50045..59afdac 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -16,16 +16,20 @@
package android.view.textclassifier;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
import android.annotation.WorkerThread;
import android.os.LocaleList;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
+import android.permission.flags.Flags;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.URLSpan;
@@ -63,11 +67,6 @@
/** @hide */
String LOG_TAG = "androidtc";
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {LOCAL, SYSTEM, DEFAULT_SYSTEM})
- @interface TextClassifierType {} // TODO: Expose as system APIs.
/** Specifies a TextClassifier that runs locally in the app's process. @hide */
int LOCAL = 0;
/** Specifies a TextClassifier that runs in the system process and serves all apps. @hide */
@@ -76,8 +75,33 @@
int DEFAULT_SYSTEM = 2;
/** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {CLASSIFIER_TYPE_SELF_PROVIDED, CLASSIFIER_TYPE_DEVICE_DEFAULT,
+ CLASSIFIER_TYPE_ANDROID_DEFAULT})
+ @interface TextClassifierType {
+ }
+ /** Specifies a TextClassifier that runs locally in the app's process. @hide */
+ @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ @SystemApi
+ int CLASSIFIER_TYPE_SELF_PROVIDED = LOCAL;
+ /**
+ * Specifies a TextClassifier that is set as the default on this particular device. This may be
+ * the same as CLASSIFIER_TYPE_DEVICE_DEFAULT, unless set otherwise by the device manufacturer.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ @SystemApi
+ int CLASSIFIER_TYPE_DEVICE_DEFAULT = SYSTEM;
+ /** Specifies the TextClassifier that is provided by Android. @hide */
+ @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ @SystemApi
+ int CLASSIFIER_TYPE_ANDROID_DEFAULT = DEFAULT_SYSTEM;
+
+ /** @hide */
+ @SuppressLint("SwitchIntDef")
static String typeToString(@TextClassifierType int type) {
- switch (type) {
+ int unflaggedType = type;
+ switch (unflaggedType) {
case LOCAL:
return "Local";
case SYSTEM:
@@ -108,6 +132,9 @@
String TYPE_DATE_TIME = "datetime";
/** Flight number in IATA format. */
String TYPE_FLIGHT_NUMBER = "flight";
+ /** Onetime password. */
+ @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ String TYPE_OTP = "otp";
/**
* Word that users may be interested to look up for meaning.
* @hide
@@ -126,7 +153,8 @@
TYPE_DATE,
TYPE_DATE_TIME,
TYPE_FLIGHT_NUMBER,
- TYPE_DICTIONARY
+ TYPE_DICTIONARY,
+ TYPE_OTP
})
@interface EntityType {}
@@ -198,6 +226,16 @@
String EXTRA_FROM_TEXT_CLASSIFIER = "android.view.textclassifier.extra.FROM_TEXT_CLASSIFIER";
/**
+ * Extra specifying the package name of the app from which the text to be classified originated.
+ *
+ * For example, a notification assistant might use TextClassifier, but the notification
+ * content could originate from a different app. This key allows you to provide
+ * the package name of that source app.
+ */
+ @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ String EXTRA_TEXT_ORIGIN_PACKAGE = "android.view.textclassifier.extra.TEXT_ORIGIN_PACKAGE";
+
+ /**
* Returns suggested text selection start and end indices, recognized entity types, and their
* associated confidence scores. The entity types are ordered from highest to lowest scoring.
*
diff --git a/core/java/android/webkit/EventLogTags.logtags b/core/java/android/webkit/EventLogTags.logtags
index a90aebd..8bbd5a9 100644
--- a/core/java/android/webkit/EventLogTags.logtags
+++ b/core/java/android/webkit/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.webkit;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 3c854ea..fc3014a 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -16,7 +16,7 @@
package android.widget;
-import static android.view.flags.Flags.enableTouchScrollFeedback;
+import static android.view.flags.Flags.enableScrollFeedbackForTouch;
import static android.view.flags.Flags.scrollFeedbackApi;
import static android.view.flags.Flags.viewVelocityApi;
@@ -3737,7 +3737,7 @@
atEdge = trackMotionScroll(deltaY, incrementalDeltaY);
// TODO: b/360198915 - Add unit testing for using ScrollFeedbackProvider
- if (enableTouchScrollFeedback()) {
+ if (vtev != null && enableScrollFeedbackForTouch()) {
initHapticScrollFeedbackProviderIfNotExists();
mHapticScrollFeedbackProvider.onScrollProgress(
vtev.getDeviceId(), vtev.getSource(), MotionEvent.AXIS_Y,
@@ -3779,7 +3779,7 @@
mTouchMode = TOUCH_MODE_OVERSCROLL;
}
- if (enableTouchScrollFeedback()) {
+ if (vtev != null && enableScrollFeedbackForTouch()) {
initHapticScrollFeedbackProviderIfNotExists();
mHapticScrollFeedbackProvider.onScrollLimit(
vtev.getDeviceId(), vtev.getSource(),
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 2cd3901..9c2833b 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -47,6 +47,7 @@
import android.app.PendingIntent;
import android.app.RemoteInput;
import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager.ServiceCollectionCache;
import android.appwidget.flags.Flags;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
@@ -54,7 +55,6 @@
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentSender;
-import android.content.ServiceConnection;
import android.content.om.FabricatedOverlay;
import android.content.om.OverlayInfo;
import android.content.om.OverlayManager;
@@ -82,7 +82,6 @@
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
-import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
@@ -127,8 +126,8 @@
import com.android.internal.R;
import com.android.internal.util.Preconditions;
import com.android.internal.widget.IRemoteViewsFactory;
-import com.android.internal.widget.remotecompose.core.operations.Theme;
import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.operations.Theme;
import com.android.internal.widget.remotecompose.player.RemoteComposeDocument;
import com.android.internal.widget.remotecompose.player.RemoteComposePlayer;
@@ -1391,8 +1390,10 @@
/**
* @hide
*/
- public CompletableFuture<Void> collectAllIntents(int bitmapSizeLimit) {
- return mCollectionCache.collectAllIntentsNoComplete(this, bitmapSizeLimit);
+ public CompletableFuture<Void> collectAllIntents(int bitmapSizeLimit,
+ @NonNull ServiceCollectionCache collectionCache) {
+ return mCollectionCache.collectAllIntentsNoComplete(this, bitmapSizeLimit,
+ collectionCache);
}
private class RemoteCollectionCache {
@@ -1446,7 +1447,8 @@
}
public @NonNull CompletableFuture<Void> collectAllIntentsNoComplete(
- @NonNull RemoteViews inViews, int bitmapSizeLimit) {
+ @NonNull RemoteViews inViews, int bitmapSizeLimit,
+ @NonNull ServiceCollectionCache collectionCache) {
SparseArray<Intent> idToIntentMapping = new SparseArray<>();
// Collect the number of uinque Intent (which is equal to the number of new connections
// to make) for size allocation and exclude certain collections from being written to
@@ -1478,7 +1480,7 @@
/ numOfIntents;
return connectAllUniqueIntents(individualSize, individualBitmapSizeLimit,
- idToIntentMapping);
+ idToIntentMapping, collectionCache);
}
private void collectAllIntentsInternal(@NonNull RemoteViews inViews,
@@ -1544,13 +1546,14 @@
}
private @NonNull CompletableFuture<Void> connectAllUniqueIntents(int individualSize,
- int individualBitmapSize, @NonNull SparseArray<Intent> idToIntentMapping) {
+ int individualBitmapSize, @NonNull SparseArray<Intent> idToIntentMapping,
+ @NonNull ServiceCollectionCache collectionCache) {
List<CompletableFuture<Void>> intentFutureList = new ArrayList<>();
for (int i = 0; i < idToIntentMapping.size(); i++) {
String currentIntentUri = mIdToUriMapping.get(idToIntentMapping.keyAt(i));
Intent currentIntent = idToIntentMapping.valueAt(i);
intentFutureList.add(getItemsFutureFromIntentWithTimeout(currentIntent,
- individualSize, individualBitmapSize)
+ individualSize, individualBitmapSize, collectionCache)
.thenAccept(items -> {
items.setHierarchyRootData(getHierarchyRootData());
mUriToCollectionMapping.put(currentIntentUri, items);
@@ -1561,7 +1564,8 @@
}
private static CompletableFuture<RemoteCollectionItems> getItemsFutureFromIntentWithTimeout(
- Intent intent, int individualSize, int individualBitmapSize) {
+ Intent intent, int individualSize, int individualBitmapSize,
+ @NonNull ServiceCollectionCache collectionCache) {
if (intent == null) {
Log.e(LOG_TAG, "Null intent received when generating adapter future");
return CompletableFuture.completedFuture(new RemoteCollectionItems
@@ -1581,39 +1585,24 @@
return result;
}
- context.bindService(intent, Context.BindServiceFlags.of(Context.BIND_AUTO_CREATE),
- result.defaultExecutor(), new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName componentName,
- IBinder iBinder) {
- RemoteCollectionItems items;
- try {
- items = IRemoteViewsFactory.Stub.asInterface(iBinder)
- .getRemoteCollectionItems(individualSize,
- individualBitmapSize);
- } catch (RemoteException re) {
- items = new RemoteCollectionItems.Builder().build();
- Log.e(LOG_TAG, "Error getting collection items from the"
- + " factory", re);
- } finally {
- context.unbindService(this);
- }
+ collectionCache.connectAndConsume(intent, iBinder -> {
+ RemoteCollectionItems items;
+ try {
+ items = IRemoteViewsFactory.Stub.asInterface(iBinder)
+ .getRemoteCollectionItems(individualSize,
+ individualBitmapSize);
+ } catch (RemoteException re) {
+ items = new RemoteCollectionItems.Builder().build();
+ Log.e(LOG_TAG, "Error getting collection items from the"
+ + " factory", re);
+ }
- if (items == null) {
- items = new RemoteCollectionItems.Builder().build();
- }
+ if (items == null) {
+ items = new RemoteCollectionItems.Builder().build();
+ }
- result.complete(items);
- }
-
- @Override
- public void onNullBinding(ComponentName name) {
- context.unbindService(this);
- }
-
- @Override
- public void onServiceDisconnected(ComponentName componentName) { }
- });
+ result.complete(items);
+ }, result.defaultExecutor());
result.completeOnTimeout(
new RemoteCollectionItems.Builder().build(),
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 511c832..184933f 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -16,7 +16,7 @@
package android.widget;
-import static android.view.flags.Flags.enableTouchScrollFeedback;
+import static android.view.flags.Flags.enableScrollFeedbackForTouch;
import static android.view.flags.Flags.viewVelocityApi;
import android.annotation.ColorInt;
@@ -909,7 +909,7 @@
}
// TODO: b/360198915 - Add unit tests.
- if (enableTouchScrollFeedback()) {
+ if (enableScrollFeedbackForTouch()) {
if (hitTopLimit || hitBottomLimit) {
initHapticScrollFeedbackProviderIfNotExists();
mHapticScrollFeedbackProvider.onScrollLimit(vtev.getDeviceId(),
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d7750bd..71a832d 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -18,6 +18,7 @@
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.graphics.Paint.NEW_FONT_VARIATION_MANAGEMENT;
import static android.view.ContentInfo.FLAG_CONVERT_TO_PLAIN_TEXT;
import static android.view.ContentInfo.SOURCE_AUTOFILL;
import static android.view.ContentInfo.SOURCE_CLIPBOARD;
@@ -5542,7 +5543,21 @@
&& fontVariationSettings.equals(existingSettings))) {
return true;
}
- boolean effective = mTextPaint.setFontVariationSettings(fontVariationSettings);
+
+ final boolean useFontVariationStore = Flags.typefaceRedesignReadonly()
+ && CompatChanges.isChangeEnabled(NEW_FONT_VARIATION_MANAGEMENT);
+ boolean effective;
+ if (useFontVariationStore) {
+ if (mFontWeightAdjustment != 0
+ && mFontWeightAdjustment != Configuration.FONT_WEIGHT_ADJUSTMENT_UNDEFINED) {
+ mTextPaint.setFontVariationSettings(fontVariationSettings, mFontWeightAdjustment);
+ } else {
+ mTextPaint.setFontVariationSettings(fontVariationSettings);
+ }
+ effective = true;
+ } else {
+ effective = mTextPaint.setFontVariationSettings(fontVariationSettings);
+ }
if (effective && mLayout != null) {
nullLayouts();
@@ -10114,6 +10129,10 @@
outAttrs.extras.putBoolean(
STYLUS_HANDWRITING_ENABLED_ANDROIDX_EXTRAS_KEY, handwritingEnabled);
}
+ if (android.view.inputmethod.Flags.writingTools()) {
+ // default to same behavior as isSuggestionsEnabled().
+ outAttrs.setWritingToolsEnabled(isSuggestionsEnabled());
+ }
ArrayList<Class<? extends HandwritingGesture>> gestures = new ArrayList<>();
gestures.add(SelectGesture.class);
gestures.add(SelectRangeGesture.class);
diff --git a/core/java/android/window/WindowContext.java b/core/java/android/window/WindowContext.java
index 2b370b9..84a8b8f 100644
--- a/core/java/android/window/WindowContext.java
+++ b/core/java/android/window/WindowContext.java
@@ -32,6 +32,7 @@
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
import java.lang.ref.Reference;
@@ -95,20 +96,20 @@
}
/**
- * Updates this context to a new displayId.
+ * Moves this context to another display.
* <p>
- * Note that this doesn't re-parent previously attached windows (they should be removed and
- * re-added manually after this is called). Resources associated with this context will have
- * the correct value and configuration for the new display after this is called.
+ * Note that this re-parents all the previously attached windows. Resources associated with this
+ * context will have the correct value and configuration for the new display after this is
+ * called.
*/
- @Override
- public void updateDisplay(int displayId) {
- if (displayId == getDisplayId()) {
- return;
+ public void reparentToDisplay(int displayId) {
+ if (Flags.reparentWindowTokenApi()) {
+ if (displayId == getDisplayId()) {
+ return;
+ }
+ super.updateDisplay(displayId);
+ mController.reparentToDisplayArea(mType, displayId, mOptions);
}
- super.updateDisplay(displayId);
- mController.detachIfNeeded();
- mController.attachToDisplayArea(mType, displayId, mOptions);
}
@Override
diff --git a/core/java/android/window/WindowContextController.java b/core/java/android/window/WindowContextController.java
index c9ac245..1e2f454 100644
--- a/core/java/android/window/WindowContextController.java
+++ b/core/java/android/window/WindowContextController.java
@@ -158,6 +158,21 @@
}
}
+ /**
+ * Reparents the window context from the current attached display to another. {@code type} and
+ * {@code options} must be the same as the previous attach call, otherwise this will fail
+ * silently.
+ */
+ public void reparentToDisplayArea(
+ @WindowType int type, int displayId, @Nullable Bundle options) {
+ if (mAttachedToDisplayArea != AttachStatus.STATUS_ATTACHED) {
+ attachToDisplayArea(type, displayId, options);
+ return;
+ }
+ // No need to propagate type and options as this is already attached and they can't change.
+ getWindowTokenClientController().reparentToDisplayArea(mToken, displayId);
+ }
+
/** Gets the {@link WindowTokenClientController}. */
@VisibleForTesting
@NonNull
diff --git a/core/java/android/window/WindowTokenClientController.java b/core/java/android/window/WindowTokenClientController.java
index fa34595..1ec05b6 100644
--- a/core/java/android/window/WindowTokenClientController.java
+++ b/core/java/android/window/WindowTokenClientController.java
@@ -197,6 +197,21 @@
}
}
+ /**
+ * Reparents a {@link WindowTokenClient} and its associated WindowContainer if there's one.
+ */
+ public void reparentToDisplayArea(@NonNull WindowTokenClient client, int displayId) {
+ try {
+ if (!getWindowManagerService().reparentWindowContextToDisplayArea(mAppThread, client,
+ displayId)) {
+ Log.e(TAG,
+ "Didn't succeed reparenting of " + client + " to displayId=" + displayId);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
private void onWindowContextTokenAttached(@NonNull WindowTokenClient client,
@NonNull WindowContextInfo info, boolean shouldReportConfigChange) {
recordWindowContextToken(client);
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 8ebc1ed..a05d003 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -449,6 +449,14 @@
}
flag {
+ name: "reparent_window_token_api"
+ namespace: "lse_desktop_experience"
+ description: "Allows to reparent a window token to a different display"
+ is_fixed_read_only: true
+ bug: "381258683"
+}
+
+flag {
name: "enable_desktop_windowing_hsum"
namespace: "lse_desktop_experience"
description: "Enables HSUM on desktop mode."
@@ -481,4 +489,15 @@
namespace: "lse_desktop_experience"
description: "Bugfixes / papercuts to bring Desktop Windowing to secondary displays."
bug: "382023296"
+}
+
+flag {
+ name: "enable_top_visible_root_task_per_user_tracking"
+ namespace: "lse_desktop_experience"
+ description: "Enables tracking the top visible root tasks for a user."
+ bug: "381038076"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
\ No newline at end of file
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index f01aa80..2cfc680 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -163,5 +163,4 @@
void finishOperationForDevice(IBinder clientId, int code, int uid, String packageName,
@nullable String attributionTag, int virtualDeviceId);
List<AppOpsManager.PackageOps> getPackagesForOpsForDevice(in int[] ops, String persistentDeviceId);
- oneway void noteOperationsInBatch(in Map batchedNoteOps);
}
diff --git a/core/java/com/android/internal/jank/EventLogTags.logtags b/core/java/com/android/internal/jank/EventLogTags.logtags
index 66ee131..dfec499 100644
--- a/core/java/com/android/internal/jank/EventLogTags.logtags
+++ b/core/java/com/android/internal/jank/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.internal.jank;
diff --git a/core/java/com/android/internal/view/ScrollCaptureInternal.java b/core/java/com/android/internal/view/ScrollCaptureInternal.java
index 72b5488..0ed0613 100644
--- a/core/java/com/android/internal/view/ScrollCaptureInternal.java
+++ b/core/java/com/android/internal/view/ScrollCaptureInternal.java
@@ -16,6 +16,8 @@
package com.android.internal.view;
+import static android.view.flags.Flags.scrollCaptureRelaxScrollViewCriteria;
+
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
@@ -49,7 +51,7 @@
public static final int TYPE_FIXED = 0;
/**
- * Slides a single child view using mScrollX/mScrollY.
+ * Moves the viewport across absolute positioned child views using the scrollY property.
*/
public static final int TYPE_SCROLLING = 1;
@@ -63,7 +65,7 @@
/**
* Unknown scrollable view with no child views (or not a subclass of ViewGroup).
*/
- private static final int TYPE_OPAQUE = 3;
+ public static final int TYPE_OPAQUE = 3;
/**
* Performs tests on the given View and determines:
@@ -73,7 +75,7 @@
* This needs to be fast and not alloc memory. It's called on everything in the tree not marked
* as excluded during scroll capture search.
*/
- private static int detectScrollingType(View view) {
+ public static int detectScrollingType(View view) {
// Confirm that it can scroll.
if (!(view.canScrollVertically(DOWN) || view.canScrollVertically(UP))) {
// Nothing to scroll here, move along.
@@ -95,25 +97,25 @@
if (DEBUG_VERBOSE) {
Log.v(TAG, "hint: is a subclass of ViewGroup");
}
-
- // ScrollViews accept only a single child.
- if (((ViewGroup) view).getChildCount() > 1) {
- if (DEBUG_VERBOSE) {
- Log.v(TAG, "hint: scrollable with multiple children");
+ // Flag: Optionally allow ScrollView-like ViewGroups which have more than one child view.
+ if (!scrollCaptureRelaxScrollViewCriteria()) {
+ // ScrollViews accept only a single child.
+ if (((ViewGroup) view).getChildCount() > 1) {
+ if (DEBUG_VERBOSE) {
+ Log.v(TAG, "hint: scrollable with multiple children");
+ }
+ return TYPE_RECYCLING;
}
- return TYPE_RECYCLING;
}
// At least one child view is required.
- if (((ViewGroup) view).getChildCount() < 1) {
- if (DEBUG_VERBOSE) {
- Log.v(TAG, "scrollable with no children");
- }
+ if (((ViewGroup) view).getChildCount() == 0) {
+ Log.w(TAG, "scrollable but no children!");
return TYPE_OPAQUE;
}
if (DEBUG_VERBOSE) {
Log.v(TAG, "hint: single child view");
}
- //Because recycling containers don't use scrollY, a non-zero value means Scroll view.
+ // Because recycling containers don't use scrollY, a non-zero value means Scroll view.
if (view.getScrollY() != 0) {
if (DEBUG_VERBOSE) {
Log.v(TAG, "hint: scrollY != 0");
@@ -132,7 +134,7 @@
Log.v(TAG, "hint: cannot be scrolled up");
}
- // canScrollVertically(UP) == false, getScrollY() == 0, getChildCount() == 1.
+ // canScrollVertically(UP) == false, getScrollY() == 0, getChildCount() >= 1.
// For Recycling containers, this should be a no-op (RecyclerView logs a warning)
view.scrollTo(view.getScrollX(), 1);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
index 1e9ba78..33f93fc 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
@@ -699,6 +699,7 @@
}
op.markNotDirty();
op.apply(context);
+ context.incrementOpCount();
}
}
@@ -1000,6 +1001,16 @@
private final float[] mScaleOutput = new float[2];
private final float[] mTranslateOutput = new float[2];
private int mRepaintNext = -1; // delay to next repaint -1 = don't 1 = asap
+ private int mLastOpCount;
+
+ /**
+ * This is the number of ops used to calculate the last frame.
+ *
+ * @return number of ops
+ */
+ public int getOpsPerFrame() {
+ return mLastOpCount;
+ }
/**
* Returns > 0 if it needs to repaint
@@ -1017,6 +1028,7 @@
* @param theme the theme we want to use for this document.
*/
public void paint(@NonNull RemoteContext context, int theme) {
+ context.getLastOpCount();
context.getPaintContext().clearNeedsRepaint();
context.loadFloat(RemoteContext.ID_DENSITY, context.getDensity());
context.mMode = RemoteContext.ContextMode.UNSET;
@@ -1027,21 +1039,24 @@
context.mRemoteComposeState = mRemoteComposeState;
context.mRemoteComposeState.setContext(context);
+ // If we have a content sizing set, we are going to take the original document
+ // dimension into account and apply scale+translate according to the RootContentBehavior
+ // rules.
if (mContentSizing == RootContentBehavior.SIZING_SCALE) {
// we need to add canvas transforms ops here
computeScale(context.mWidth, context.mHeight, mScaleOutput);
- computeTranslate(
- context.mWidth,
- context.mHeight,
- mScaleOutput[0],
- mScaleOutput[1],
- mTranslateOutput);
+ float sw = mScaleOutput[0];
+ float sh = mScaleOutput[1];
+ computeTranslate(context.mWidth, context.mHeight, sw, sh, mTranslateOutput);
context.mPaintContext.translate(mTranslateOutput[0], mTranslateOutput[1]);
- context.mPaintContext.scale(mScaleOutput[0], mScaleOutput[1]);
+ context.mPaintContext.scale(sw, sh);
+ } else {
+ // If not, we set the document width and height to be the current context width and
+ // height.
+ setWidth((int) context.mWidth);
+ setHeight((int) context.mHeight);
}
mTimeVariables.updateTime(context);
- context.loadFloat(RemoteContext.ID_WINDOW_WIDTH, context.mWidth);
- context.loadFloat(RemoteContext.ID_WINDOW_HEIGHT, context.mHeight);
mRepaintNext = context.updateOps();
if (mRootLayoutComponent != null) {
if (context.mWidth != mRootLayoutComponent.getWidth()
@@ -1051,11 +1066,11 @@
if (mRootLayoutComponent.needsMeasure()) {
mRootLayoutComponent.layout(context);
}
- // TODO -- this should be specifically about applying animation, not paint
- mRootLayoutComponent.paint(context.getPaintContext());
- context.mPaintContext.reset();
- // TODO -- should be able to remove this
- mRootLayoutComponent.updateVariables(context);
+ if (mRootLayoutComponent.needsBoundsAnimation()) {
+ mRepaintNext = 1;
+ mRootLayoutComponent.clearNeedsBoundsAnimation();
+ mRootLayoutComponent.animatingBounds(context);
+ }
if (DEBUG) {
String hierarchy = mRootLayoutComponent.displayHierarchy();
System.out.println(hierarchy);
@@ -1081,6 +1096,7 @@
op.markNotDirty();
((VariableSupport) op).updateVariables(context);
}
+ context.incrementOpCount();
op.apply(context);
}
}
@@ -1093,6 +1109,38 @@
if (DEBUG && mRootLayoutComponent != null) {
System.out.println(mRootLayoutComponent.displayHierarchy());
}
+ mLastOpCount = context.getLastOpCount();
+ }
+
+ /**
+ * Get an estimated number of operations executed in a paint
+ *
+ * @return number of operations
+ */
+ public int getNumberOfOps() {
+ int count = mOperations.size();
+
+ for (Operation mOperation : mOperations) {
+ if (mOperation instanceof Component) {
+ count += getChildOps((Component) mOperation);
+ }
+ }
+ return count;
+ }
+
+ private int getChildOps(@NonNull Component base) {
+ int count = base.mList.size();
+ for (Operation mOperation : base.mList) {
+
+ if (mOperation instanceof Component) {
+ int mult = 1;
+ if (mOperation instanceof LoopOperation) {
+ mult = ((LoopOperation) mOperation).estimateIterations();
+ }
+ count += mult * getChildOps((Component) mOperation);
+ }
+ }
+ return count;
}
@NonNull
@@ -1116,6 +1164,9 @@
if (mOperation instanceof Component) {
Component com = (Component) mOperation;
count += addChildren(com, map, buffer);
+ } else if (mOperation instanceof LoopOperation) {
+ LoopOperation com = (LoopOperation) mOperation;
+ count += addChildren(com, map, buffer);
}
}
@@ -1153,6 +1204,35 @@
if (mOperation instanceof Component) {
count += addChildren((Component) mOperation, map, tmp);
}
+ if (mOperation instanceof LoopOperation) {
+ count += addChildren((LoopOperation) mOperation, map, tmp);
+ }
+ }
+ return count;
+ }
+
+ private int addChildren(
+ @NonNull LoopOperation base,
+ @NonNull HashMap<String, int[]> map,
+ @NonNull WireBuffer tmp) {
+ int count = base.mList.size();
+ for (Operation mOperation : base.mList) {
+ Class<? extends Operation> c = mOperation.getClass();
+ int[] values;
+ if (map.containsKey(c.getSimpleName())) {
+ values = map.get(c.getSimpleName());
+ } else {
+ values = new int[2];
+ map.put(c.getSimpleName(), values);
+ }
+ values[0] += 1;
+ values[1] += sizeOfComponent(mOperation, tmp);
+ if (mOperation instanceof Component) {
+ count += addChildren((Component) mOperation, map, tmp);
+ }
+ if (mOperation instanceof LoopOperation) {
+ count += addChildren((LoopOperation) mOperation, map, tmp);
+ }
}
return count;
}
@@ -1198,7 +1278,6 @@
* @param ctl the call back to allow evaluation of shaders
*/
public void checkShaders(RemoteContext context, ShaderControl ctl) {
- int count = 0;
for (Operation op : mOperations) {
if (op instanceof TextData) {
op.apply(context);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
index c03f44b..b5587ce 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
@@ -40,6 +40,7 @@
* <p>We also contain a PaintContext, so that any operation can draw as needed.
*/
public abstract class RemoteContext {
+ private static final int MAX_OP_COUNT = 100_000; // Maximum cmds per frame
protected @NonNull CoreDocument mDocument =
new CoreDocument(); // todo: is this a valid way to initialize? bbade@
public @NonNull RemoteComposeState mRemoteComposeState =
@@ -52,6 +53,7 @@
int mDebug = 0;
+ private int mOpCount;
private int mTheme = Theme.UNSPECIFIED;
public float mWidth = 0f;
@@ -631,4 +633,23 @@
float right,
float bottom,
int metadataId);
+
+ /** increments the count of operations executed in a pass */
+ public void incrementOpCount() {
+ mOpCount++;
+ if (mOpCount > MAX_OP_COUNT) {
+ throw new RuntimeException("Too many operations executed");
+ }
+ }
+
+ /**
+ * Get the last Op Count and clear the count.
+ *
+ * @return the number of ops executed.
+ */
+ public int getLastOpCount() {
+ int count = mOpCount;
+ mOpCount = 0;
+ return count;
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
index cd7ebec..ea917db 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
@@ -24,7 +24,7 @@
/** This generates the standard system variables for time. */
public class TimeVariables {
- private static final float BUILD = 0.01f;
+ private static final float BUILD = 0.02f;
/**
* This class populates all time variables in the system
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
index dcf1d25..e05bdf2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
@@ -106,6 +106,7 @@
for (Operation op : mList) {
if (op instanceof TextData) {
op.apply(context);
+ context.incrementOpCount();
}
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
index e95dfda..8a77dc3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
@@ -66,6 +66,34 @@
protected float mZIndex = 0f;
+ private boolean mNeedsBoundsAnimation = false;
+
+ /**
+ * Mark the component as needing a bounds animation pass
+ */
+ public void markNeedsBoundsAnimation() {
+ mNeedsBoundsAnimation = true;
+ if (mParent != null && !mParent.mNeedsBoundsAnimation) {
+ mParent.markNeedsBoundsAnimation();
+ }
+ }
+
+ /**
+ * Clear the bounds animation pass flag
+ */
+ public void clearNeedsBoundsAnimation() {
+ mNeedsBoundsAnimation = false;
+ }
+
+ /**
+ * True if needs a bounds animation
+ *
+ * @return true if needs a bounds animation pass
+ */
+ public boolean needsBoundsAnimation() {
+ return mNeedsBoundsAnimation;
+ }
+
public float getZIndex() {
return mZIndex;
}
@@ -382,12 +410,40 @@
} else {
mVisibility = m.getVisibility();
}
- setWidth(m.getW());
- setHeight(m.getH());
- setLayoutPosition(m.getX(), m.getY());
+ if (mAnimateMeasure == null) {
+ setWidth(m.getW());
+ setHeight(m.getH());
+ setLayoutPosition(m.getX(), m.getY());
+ updateComponentValues(context);
+ clearNeedsBoundsAnimation();
+ } else {
+ mAnimateMeasure.apply(context);
+ updateComponentValues(context);
+ markNeedsBoundsAnimation();
+ }
mFirstLayout = false;
}
+ /**
+ * Animate the bounds of the component as needed
+ * @param context
+ */
+ public void animatingBounds(@NonNull RemoteContext context) {
+ if (mAnimateMeasure != null) {
+ mAnimateMeasure.apply(context);
+ updateComponentValues(context);
+ markNeedsBoundsAnimation();
+ } else {
+ clearNeedsBoundsAnimation();
+ }
+ for (Operation op : mList) {
+ if (op instanceof Measurable) {
+ Measurable m = (Measurable) op;
+ m.animatingBounds(context);
+ }
+ }
+ }
+
@NonNull public float[] locationInWindow = new float[2];
public boolean contains(float x, float y) {
@@ -698,9 +754,6 @@
}
public void paintingComponent(@NonNull PaintContext context) {
- if (!mComponentValues.isEmpty()) {
- updateComponentValues(context.getContext());
- }
if (mPreTranslate != null) {
mPreTranslate.paint(context);
}
@@ -718,8 +771,10 @@
}
if (op instanceof PaintOperation) {
((PaintOperation) op).paint(context);
+ context.getContext().incrementOpCount();
} else {
op.apply(context.getContext());
+ context.getContext().incrementOpCount();
}
}
context.restore();
@@ -728,7 +783,7 @@
public boolean applyAnimationAsNeeded(@NonNull PaintContext context) {
if (context.isAnimationEnabled() && mAnimateMeasure != null) {
- mAnimateMeasure.apply(context);
+ mAnimateMeasure.paint(context);
context.needsRepaint();
return true;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
index e25392c..9103885 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
@@ -286,7 +286,9 @@
@Override
public void paintingComponent(@NonNull PaintContext context) {
Component prev = context.getContext().mLastComponent;
- context.getContext().mLastComponent = this;
+ RemoteContext remoteContext = context.getContext();
+
+ remoteContext.mLastComponent = this;
context.save();
context.translate(mX, mY);
if (context.isVisualDebug()) {
@@ -329,6 +331,7 @@
child.updateVariables(context.getContext());
child.markNotDirty();
}
+ remoteContext.incrementOpCount();
child.paint(context);
}
} else {
@@ -337,6 +340,7 @@
child.updateVariables(context.getContext());
child.markNotDirty();
}
+ remoteContext.incrementOpCount();
child.paint(context);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
index 505656e..9fc5da8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
@@ -57,6 +57,7 @@
for (Operation op : mList) {
if (op instanceof TextData) {
op.apply(context);
+ context.incrementOpCount();
}
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
index 1b85681..ab1e0ac 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
@@ -107,9 +107,11 @@
@Override
public void paint(@NonNull PaintContext context) {
+ RemoteContext remoteContext = context.getContext();
if (mIndexVariableId == 0) {
for (float i = mFromOut; i < mUntilOut; i += mStepOut) {
for (Operation op : mList) {
+ remoteContext.incrementOpCount();
op.apply(context.getContext());
}
}
@@ -120,6 +122,7 @@
if (op instanceof VariableSupport && op.isDirty()) {
((VariableSupport) op).updateVariables(context.getContext());
}
+ remoteContext.incrementOpCount();
op.apply(context.getContext());
}
}
@@ -172,4 +175,16 @@
.field(DocumentedOperation.FLOAT, "step", "value step")
.field(DocumentedOperation.FLOAT, "until", "stops less than or equal");
}
+
+ /**
+ * Calculate and estimate of the number of iterations
+ *
+ * @return number of loops or 10 if based on variables
+ */
+ public int estimateIterations() {
+ if (!(Float.isNaN(mUntil) || Float.isNaN(mFrom) || Float.isNaN(mStep))) {
+ return (int) (0.5f + (mUntil - mFrom) / mStep);
+ }
+ return 10; // this is a generic estmate if the values are variables;
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
index 11c0f3f..11fa7ee 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
@@ -137,8 +137,8 @@
return;
}
context.mLastComponent = this;
- mWidth = context.mWidth;
- mHeight = context.mHeight;
+ setWidth(context.mWidth);
+ setHeight(context.mHeight);
// TODO: reuse MeasurePass
MeasurePass measurePass = new MeasurePass();
@@ -155,7 +155,9 @@
@Override
public void paint(@NonNull PaintContext context) {
mNeedsRepaint = false;
- context.getContext().mLastComponent = this;
+ RemoteContext remoteContext = context.getContext();
+ remoteContext.mLastComponent = this;
+
context.save();
if (mParent == null) { // root layout
@@ -165,6 +167,7 @@
for (Operation op : mList) {
if (op instanceof PaintOperation) {
((PaintOperation) op).paint(context);
+ remoteContext.incrementOpCount();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
index 2af3c73..1de956b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/animation/AnimateMeasure.java
@@ -19,6 +19,7 @@
import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
import com.android.internal.widget.remotecompose.core.operations.layout.Component;
import com.android.internal.widget.remotecompose.core.operations.layout.DecoratorComponent;
import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
@@ -103,13 +104,18 @@
@NonNull public PaintBundle paint = new PaintBundle();
- public void apply(@NonNull PaintContext context) {
- update(context.getContext().currentTime);
-
+ /**
+ * Apply the layout portion of the animation if any
+ *
+ * @param context
+ */
+ public void apply(@NonNull RemoteContext context) {
+ update(context.currentTime);
mComponent.setX(getX());
mComponent.setY(getY());
mComponent.setWidth(getWidth());
mComponent.setHeight(getHeight());
+ mComponent.updateVariables(context);
float w = mComponent.getWidth();
float h = mComponent.getHeight();
@@ -120,10 +126,17 @@
h -= pop.getTop() + pop.getBottom();
}
if (op instanceof DecoratorComponent) {
- ((DecoratorComponent) op).layout(context.getContext(), mComponent, w, h);
+ ((DecoratorComponent) op).layout(context, mComponent, w, h);
}
}
+ }
+ /**
+ * Paint the transition animation for the component owned
+ *
+ * @param context
+ */
+ public void paint(@NonNull PaintContext context) {
if (mOriginal.getVisibility() != mTarget.getVisibility()) {
if (mTarget.getVisibility() == Component.Visibility.GONE) {
switch (mExitAnimation) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java
index fbf2784..a999874 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/measure/Measurable.java
@@ -44,4 +44,11 @@
* @return true if need to remeasured, false otherwise
*/
boolean needsMeasure();
+
+ /**
+ * Animate bounds of the component
+ *
+ * @param context
+ */
+ void animatingBounds(RemoteContext context);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
index d2ba13f..a1609ac 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ComponentModifiers.java
@@ -49,6 +49,7 @@
super.apply(context);
for (ModifierOperation op : mList) {
op.apply(context);
+ context.incrementOpCount();
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
index 7dad293..6eb83f1 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
@@ -250,8 +250,23 @@
mInner.clearLocalString("SYSTEM:" + name);
}
+ /**
+ * This is the number of ops used to calculate the last frame.
+ *
+ * @return number of ops
+ */
+ public int getOpsPerFrame() {
+ return mInner.getDocument().mDocument.getOpsPerFrame();
+ }
+
/** Id action callback interface */
public interface IdActionCallbacks {
+ /**
+ * Callback for on action
+ *
+ * @param id the id of the action
+ * @param metadata the metadata of the action
+ */
void onAction(int id, String metadata);
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 8e3303a..027113a 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -92,7 +92,6 @@
"android_view_VelocityTracker.cpp",
"android_view_VerifiedKeyEvent.cpp",
"android_view_VerifiedMotionEvent.cpp",
- "com_android_internal_util_ArrayUtils.cpp",
"com_android_internal_util_VirtualRefBasePtr.cpp",
"core_jni_helpers.cpp",
":deviceproductinfoconstants_aidl",
@@ -264,6 +263,7 @@
"com_android_internal_os_ZygoteCommandBuffer.cpp",
"com_android_internal_os_ZygoteInit.cpp",
"com_android_internal_security_VerityUtils.cpp",
+ "com_android_internal_util_ArrayUtils.cpp",
"hwbinder/EphemeralStorage.cpp",
"fd_utils.cpp",
"android_hardware_input_InputWindowHandle.cpp",
diff --git a/core/jni/android_app_PropertyInvalidatedCache.cpp b/core/jni/android_app_PropertyInvalidatedCache.cpp
index ead6666..12585d5 100644
--- a/core/jni/android_app_PropertyInvalidatedCache.cpp
+++ b/core/jni/android_app_PropertyInvalidatedCache.cpp
@@ -28,24 +28,77 @@
#include "core_jni_helpers.h"
#include "android_app_PropertyInvalidatedCache.h"
+namespace android::app::PropertyInvalidatedCache {
+
+// These provide run-time access to the sizing parameters.
+int NonceStore::getMaxNonce() const {
+ return kMaxNonce;
+}
+
+size_t NonceStore::getMaxByte() const {
+ return kMaxByte;
+}
+
+// Fetch a nonce, returning UNSET if the index is out of range. This method specifically
+// does not throw or generate an error if the index is out of range; this allows the method
+// to be called in a CriticalNative JNI API.
+int64_t NonceStore::getNonce(int index) const {
+ if (index < 0 || index >= kMaxNonce) {
+ return UNSET;
+ } else {
+ return nonce()[index];
+ }
+}
+
+// Set a nonce and return true. Return false if the index is out of range. This method
+// specifically does not throw or generate an error if the index is out of range; this
+// allows the method to be called in a CriticalNative JNI API.
+bool NonceStore::setNonce(int index, int64_t value) {
+ if (index < 0 || index >= kMaxNonce) {
+ return false;
+ } else {
+ nonce()[index] = value;
+ return true;
+ }
+}
+
+// Fetch just the byte-block hash
+int32_t NonceStore::getHash() const {
+ return mByteHash;
+}
+
+// Copy the byte block to the target and return the current hash.
+int32_t NonceStore::getByteBlock(block_t* block, size_t len) const {
+ memcpy(block, (void*) byteBlock(), std::min(kMaxByte, len));
+ return mByteHash;
+}
+
+// Set the byte block and the hash.
+void NonceStore::setByteBlock(int hash, const block_t* block, size_t len) {
+ memcpy((void*) byteBlock(), block, len = std::min(kMaxByte, len));
+ mByteHash = hash;
+}
+
+} // namespace android::app::PropertyInvalidatedCache;
+
namespace {
using namespace android::app::PropertyInvalidatedCache;
// Convert a jlong to a nonce block. This is a convenience function that should be inlined by
// the compiler.
-inline SystemCacheNonce* sysCache(jlong ptr) {
- return reinterpret_cast<SystemCacheNonce*>(ptr);
+inline NonceStore* nonceCache(jlong ptr) {
+ return reinterpret_cast<NonceStore*>(ptr);
}
// Return the number of nonces in the nonce block.
jint getMaxNonce(JNIEnv*, jclass, jlong ptr) {
- return sysCache(ptr)->getMaxNonce();
+ return nonceCache(ptr)->getMaxNonce();
}
// Return the number of string bytes in the nonce block.
jint getMaxByte(JNIEnv*, jclass, jlong ptr) {
- return sysCache(ptr)->getMaxByte();
+ return nonceCache(ptr)->getMaxByte();
}
// Set the byte block. The first int is the hash to set and the second is the array to copy.
@@ -56,25 +109,25 @@
jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "null byte block");
return;
}
- sysCache(ptr)->setByteBlock(hash, value.get(), value.size());
+ nonceCache(ptr)->setByteBlock(hash, value.get(), value.size());
}
// Fetch the byte block. If the incoming hash is the same as the local hash, the Java layer is
// presumed to have an up-to-date copy of the byte block; do not copy byte array. The local
// hash is returned.
jint getByteBlock(JNIEnv* env, jclass, jlong ptr, jint hash, jbyteArray val) {
- if (sysCache(ptr)->getHash() == hash) {
+ if (nonceCache(ptr)->getHash() == hash) {
return hash;
}
ScopedByteArrayRW value(env, val);
- return sysCache(ptr)->getByteBlock(value.get(), value.size());
+ return nonceCache(ptr)->getByteBlock(value.get(), value.size());
}
// Fetch the byte block hash.
//
// This is a CriticalNative method and therefore does not get the JNIEnv or jclass parameters.
jint getByteBlockHash(jlong ptr) {
- return sysCache(ptr)->getHash();
+ return nonceCache(ptr)->getHash();
}
// Get a nonce value. So that this method can be CriticalNative, it returns 0 if the value is
@@ -83,7 +136,7 @@
//
// This method is @CriticalNative and does not take a JNIEnv* or jclass argument.
jlong getNonce(jlong ptr, jint index) {
- return sysCache(ptr)->getNonce(index);
+ return nonceCache(ptr)->getNonce(index);
}
// Set a nonce value. So that this method can be CriticalNative, it returns a boolean: false if
@@ -92,7 +145,7 @@
//
// This method is @CriticalNative and does not take a JNIEnv* or jclass argument.
jboolean setNonce(jlong ptr, jint index, jlong value) {
- return sysCache(ptr)->setNonce(index, value);
+ return nonceCache(ptr)->setNonce(index, value);
}
static const JNINativeMethod gMethods[] = {
diff --git a/core/jni/android_app_PropertyInvalidatedCache.h b/core/jni/android_app_PropertyInvalidatedCache.h
index eefa8fa..00aa281 100644
--- a/core/jni/android_app_PropertyInvalidatedCache.h
+++ b/core/jni/android_app_PropertyInvalidatedCache.h
@@ -18,10 +18,100 @@
#include <memory.h>
#include <atomic>
+#include <cstdint>
-namespace android {
-namespace app {
-namespace PropertyInvalidatedCache {
+namespace android::app::PropertyInvalidatedCache {
+
+/**
+ * A head of a CacheNonce object. This contains all the fields that have a fixed size and
+ * location. Fields with a variable location are found via offsets. The offsets make this
+ * object position-independent, which is required because it is in shared memory and would be
+ * mapped into different virtual addresses for different processes.
+ */
+class NonceStore {
+ protected:
+ // A convenient typedef. The jbyteArray element type is jbyte, which the compiler treats as
+ // signed char.
+ typedef signed char block_t;
+
+ // The nonce type.
+ typedef std::atomic<int64_t> nonce_t;
+
+ // Atomics should be safe to use across processes if they are lock free.
+ static_assert(nonce_t::is_always_lock_free == true);
+
+ // The value of an unset field.
+ static constexpr int UNSET = 0;
+
+ // The size of the nonce array.
+ const int32_t kMaxNonce;
+
+ // The size of the byte array.
+ const size_t kMaxByte;
+
+ // The offset to the nonce array.
+ const size_t mNonceOffset;
+
+ // The offset to the byte array.
+ const size_t mByteOffset;
+
+ // The byte block hash. This is fixed and at a known offset, so leave it in the base class.
+ volatile std::atomic<int32_t> mByteHash;
+
+ // The constructor is protected! It only makes sense when called from a subclass.
+ NonceStore(int kMaxNonce, size_t kMaxByte, volatile nonce_t* nonce, volatile block_t* block) :
+ kMaxNonce(kMaxNonce),
+ kMaxByte(kMaxByte),
+ mNonceOffset(offset(this, const_cast<nonce_t*>(nonce))),
+ mByteOffset(offset(this, const_cast<block_t*>(block))) {
+ }
+
+ public:
+
+ // These provide run-time access to the sizing parameters.
+ int getMaxNonce() const;
+ size_t getMaxByte() const;
+
+ // Fetch a nonce, returning UNSET if the index is out of range. This method specifically
+ // does not throw or generate an error if the index is out of range; this allows the method
+ // to be called in a CriticalNative JNI API.
+ int64_t getNonce(int index) const;
+
+ // Set a nonce and return true. Return false if the index is out of range. This method
+ // specifically does not throw or generate an error if the index is out of range; this
+ // allows the method to be called in a CriticalNative JNI API.
+ bool setNonce(int index, int64_t value);
+
+ // Fetch just the byte-block hash
+ int32_t getHash() const;
+
+ // Copy the byte block to the target and return the current hash.
+ int32_t getByteBlock(block_t* block, size_t len) const;
+
+ // Set the byte block and the hash.
+ void setByteBlock(int hash, const block_t* block, size_t len);
+
+ private:
+
+ // A convenience function to compute the offset between two unlike pointers.
+ static size_t offset(void const* base, void const* member) {
+ return reinterpret_cast<uintptr_t>(member) - reinterpret_cast<std::uintptr_t>(base);
+ }
+
+ // Return the address of the nonce array.
+ volatile nonce_t* nonce() const {
+ // The array is located at an offset from <this>.
+ return reinterpret_cast<nonce_t*>(
+ reinterpret_cast<std::uintptr_t>(this) + mNonceOffset);
+ }
+
+ // Return the address of the byte block array.
+ volatile block_t* byteBlock() const {
+ // The array is located at an offset from <this>.
+ return reinterpret_cast<block_t*>(
+ reinterpret_cast<std::uintptr_t>(this) + mByteOffset);
+ }
+};
/**
* A cache nonce block contains an array of std::atomic<int64_t> and an array of bytes. The
@@ -36,111 +126,31 @@
* The template is parameterized by the number of nonces it supports and the number of bytes in
* the string block.
*/
-template<int maxNonce, size_t maxByte> class CacheNonce {
-
- // The value of an unset field.
- static const int UNSET = 0;
-
- // A convenient typedef. The jbyteArray element type is jbyte, which the compiler treats as
- // signed char.
- typedef signed char block_t;
+template<int maxNonce, size_t maxByte> class CacheNonce : public NonceStore {
// The array of nonces
- volatile std::atomic<int64_t> mNonce[maxNonce];
+ volatile nonce_t mNonce[maxNonce];
// The byte array. This is not atomic but it is guarded by the mByteHash.
volatile block_t mByteBlock[maxByte];
- // The hash that validates the byte block
- volatile std::atomic<int32_t> mByteHash;
-
- // Pad the class to a multiple of 8 bytes.
- int32_t _pad;
-
public:
-
- // The expected size of this instance. This is a compile-time constant and can be used in a
- // static assertion.
- static const int expectedSize =
- maxNonce * sizeof(std::atomic<int64_t>)
- + sizeof(std::atomic<int32_t>)
- + maxByte * sizeof(block_t)
- + sizeof(int32_t);
-
- // These provide run-time access to the sizing parameters.
- int getMaxNonce() const {
- return maxNonce;
- }
-
- size_t getMaxByte() const {
- return maxByte;
- }
-
// Construct and initialize the memory.
- CacheNonce() {
+ CacheNonce() :
+ NonceStore(maxNonce, maxByte, &mNonce[0], &mByteBlock[0])
+ {
for (int i = 0; i < maxNonce; i++) {
mNonce[i] = UNSET;
}
mByteHash = UNSET;
memset((void*) mByteBlock, UNSET, sizeof(mByteBlock));
}
-
- // Fetch a nonce, returning UNSET if the index is out of range. This method specifically
- // does not throw or generate an error if the index is out of range; this allows the method
- // to be called in a CriticalNative JNI API.
- int64_t getNonce(int index) const {
- if (index < 0 || index >= maxNonce) {
- return UNSET;
- } else {
- return mNonce[index];
- }
- }
-
- // Set a nonce and return true. Return false if the index is out of range. This method
- // specifically does not throw or generate an error if the index is out of range; this
- // allows the method to be called in a CriticalNative JNI API.
- bool setNonce(int index, int64_t value) {
- if (index < 0 || index >= maxNonce) {
- return false;
- } else {
- mNonce[index] = value;
- return true;
- }
- }
-
- // Fetch just the byte-block hash
- int32_t getHash() const {
- return mByteHash;
- }
-
- // Copy the byte block to the target and return the current hash.
- int32_t getByteBlock(block_t* block, size_t len) const {
- memcpy(block, (void*) mByteBlock, std::min(maxByte, len));
- return mByteHash;
- }
-
- // Set the byte block and the hash.
- void setByteBlock(int hash, const block_t* block, size_t len) {
- memcpy((void*) mByteBlock, block, len = std::min(maxByte, len));
- mByteHash = hash;
- }
};
-/**
- * Sizing parameters for the system_server PropertyInvalidatedCache support. A client can
- * retrieve the values through the accessors in CacheNonce instances.
- */
-static const int MAX_NONCE = 64;
-static const int BYTE_BLOCK_SIZE = 8192;
+// The CacheNonce for system server holds 64 nonces with a string block of 8192 bytes. This is
+// more than enough for system_server PropertyInvalidatedCache support. The configuration
+// values are not defined as visible constants. Clients should use the accessors on the
+// SystemCacheNonce instance if they need the sizing parameters.
+typedef CacheNonce</* max nonce */ 64, /* byte block size */ 8192> SystemCacheNonce;
-// The CacheNonce for system server holds 64 nonces with a string block of 8192 bytes.
-typedef CacheNonce<MAX_NONCE, BYTE_BLOCK_SIZE> SystemCacheNonce;
-
-// The goal of this assertion is to ensure that the data structure is the same size across 32-bit
-// and 64-bit systems.
-static_assert(sizeof(SystemCacheNonce) == SystemCacheNonce::expectedSize,
- "Unexpected SystemCacheNonce size");
-
-} // namespace PropertyInvalidatedCache
-} // namespace app
-} // namespace android
+} // namespace android.app.PropertyInvalidatedCache
diff --git a/core/jni/android_database_SQLiteRawStatement.cpp b/core/jni/android_database_SQLiteRawStatement.cpp
index 85a6bdf..32c2ef7 100644
--- a/core/jni/android_database_SQLiteRawStatement.cpp
+++ b/core/jni/android_database_SQLiteRawStatement.cpp
@@ -70,22 +70,6 @@
}
}
-
-// This throws a SQLiteBindOrColumnIndexOutOfRangeException if the column index is out
-// of bounds. It returns true if an exception was thrown.
-static bool throwIfInvalidColumn(JNIEnv *env, jlong stmtPtr, jint col) {
- if (col < 0 || col >= sqlite3_data_count(stmt(stmtPtr))) {
- int count = sqlite3_data_count(stmt(stmtPtr));
- std::string message = android::base::StringPrintf(
- "column index %d out of bounds [0,%d]", col, count - 1);
- char const * errmsg = sqlite3_errstr(SQLITE_RANGE);
- throw_sqlite3_exception(env, SQLITE_RANGE, errmsg, message.c_str());
- return true;
- } else {
- return false;
- }
-}
-
// If the last operation failed, throw an exception and return true. Otherwise return false.
static bool throwIfError(JNIEnv *env, jlong stmtPtr) {
switch (sqlite3_errcode(db(stmtPtr))) {
@@ -97,6 +81,31 @@
return true;
}
+// This throws a SQLiteBindOrColumnIndexOutOfRangeException if the column index is out of
+// bounds. It throws SQLiteMisuseException if the statement's column count is zero; that
+// generally occurs because the client has forgotten to call step() or the client has stepped
+// past the end of the query. The function returns true if an exception was thrown.
+static bool throwIfInvalidColumn(JNIEnv *env, jlong stmtPtr, jint col) {
+ int count = sqlite3_data_count(stmt(stmtPtr));
+ if (throwIfError(env, stmtPtr)) {
+ return true;
+ } else if (count == 0) {
+ // A count of zero indicates a misuse: the statement has never been step()'ed.
+ const char* message = "row has no data";
+ const char* errmsg = sqlite3_errstr(SQLITE_MISUSE);
+ throw_sqlite3_exception(env, SQLITE_MISUSE, errmsg, message);
+ return true;
+ } else if (col < 0 || col >= count) {
+ std::string message = android::base::StringPrintf(
+ "column index %d out of bounds [0,%d]", col, count - 1);
+ char const * errmsg = sqlite3_errstr(SQLITE_RANGE);
+ throw_sqlite3_exception(env, SQLITE_RANGE, errmsg, message.c_str());
+ return true;
+ } else {
+ return false;
+ }
+}
+
static jint bindParameterCount(JNIEnv* env, jclass, jlong stmtPtr) {
return sqlite3_bind_parameter_count(stmt(stmtPtr));
}
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
index 805d5ad..cd39e6f 100644
--- a/core/jni/android_os_SELinux.cpp
+++ b/core/jni/android_os_SELinux.cpp
@@ -34,23 +34,27 @@
namespace android {
namespace {
-std::atomic<selabel_handle*> sehandle{nullptr};
+std::atomic<selabel_handle *> file_sehandle{nullptr};
-selabel_handle* GetSELabelHandle() {
- selabel_handle* h = sehandle.load();
+selabel_handle *GetSELabelHandle_impl(selabel_handle *(*handle_func)(),
+ std::atomic<selabel_handle *> *handle_cache) {
+ selabel_handle *h = handle_cache->load();
if (h != nullptr) {
return h;
}
- h = selinux_android_file_context_handle();
+ h = handle_func();
selabel_handle* expected = nullptr;
- if (!sehandle.compare_exchange_strong(expected, h)) {
+ if (!handle_cache->compare_exchange_strong(expected, h)) {
selabel_close(h);
- return sehandle.load();
+ return handle_cache->load();
}
return h;
}
+selabel_handle *GetSELabelFileBackendHandle() {
+ return GetSELabelHandle_impl(selinux_android_file_context_handle, &file_sehandle);
+}
}
struct SecurityContext_Delete {
@@ -106,7 +110,7 @@
return NULL;
}
- auto* selabel_handle = GetSELabelHandle();
+ auto *selabel_handle = GetSELabelFileBackendHandle();
if (selabel_handle == NULL) {
ALOGE("fileSelabelLookup => Failed to get SEHandle");
return NULL;
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index b2eeff3..f40cfd9f 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -532,7 +532,12 @@
static const size_t kPageSize = getpagesize();
// App compat is only applicable on 16kb-page-size devices.
- return kPageSize == 0x4000;
+ if (kPageSize != 0x4000) {
+ return false;
+ }
+
+ // Explicit disabled status for app compat
+ return !android::base::GetBoolProperty("pm.16kb.app_compat.disabled", false);
}
static jint
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6b05690..6b8056c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -6853,6 +6853,13 @@
<permission android:name="android.permission.BATTERY_STATS"
android:protectionLevel="signature|privileged|development" />
+ <!-- @SystemApi @hide Allows an application to collect high-precision PowerMonitor readings
+ <p>Protection level: signature|privileged|development
+ @FlaggedApi(android.permission.flags.Flags.FLAG_FINE_POWER_MONITOR_PERMISSION) -->
+ <permission android:name="android.permission.ACCESS_FINE_POWER_MONITORS"
+ android:protectionLevel="signature|privileged|development"
+ android:featureFlag="android.permission.flags.fine_power_monitor_permission" />
+
<!--Allows an application to manage statscompanion.
<p>Not for use by third-party applications.
@hide -->
@@ -8792,6 +8799,17 @@
android:protectionLevel="signature|privileged|vendorPrivileged"
android:featureFlag="android.media.tv.flags.kids_mode_tvdb_sharing"/>
+ <!-- @SystemApi
+ @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled")
+ This permission is required to access the specific text classifier you need from the
+ TextClassificationManager.
+ <p>Protection level: signature|role
+ @hide
+ -->
+ <permission android:name="android.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE"
+ android:protectionLevel="signature|role"
+ android:featureFlag="android.permission.flags.text_classifier_choice_api_enabled"/>
+
<!-- Attribution for Geofencing service. -->
<attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
<!-- Attribution for Country Detector. -->
diff --git a/core/res/res/color-watch-v36/btn_material_filled_background_color.xml b/core/res/res/color-watch-v36/btn_material_filled_background_color.xml
index 70aace4..39b5b10 100644
--- a/core/res/res/color-watch-v36/btn_material_filled_background_color.xml
+++ b/core/res/res/color-watch-v36/btn_material_filled_background_color.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:alpha="?attr/disabledAlpha"
- android:color="?attr/materialColorOnSurface" />
- <item android:color="?attr/materialColorPrimary" />
+ android:color="@color/materialColorOnSurface" />
+ <item android:color="@color/materialColorPrimary" />
</selector>
\ No newline at end of file
diff --git a/core/res/res/color-watch-v36/btn_material_filled_content_color.xml b/core/res/res/color-watch-v36/btn_material_filled_content_color.xml
index 4cc8fe5..a70586b 100644
--- a/core/res/res/color-watch-v36/btn_material_filled_content_color.xml
+++ b/core/res/res/color-watch-v36/btn_material_filled_content_color.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:alpha="?attr/primaryContentAlpha"
- android:color="?attr/materialColorOnSurface" />
- <item android:color="?attr/materialColorOnPrimary" />
+ android:color="@color/materialColorOnSurface" />
+ <item android:color="@color/materialColorOnPrimary" />
</selector>
\ No newline at end of file
diff --git a/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml b/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
index b2a25af..e2e274e 100644
--- a/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
+++ b/core/res/res/color-watch-v36/btn_material_filled_tonal_background_color.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:alpha="?attr/disabledAlpha"
- android:color="?attr/materialColorOnSurface" />
- <item android:color="?attr/materialColorSurfaceContainer" />
+ android:color="@color/materialColorOnSurface" />
+ <item android:color="@color/materialColorSurfaceContainer" />
</selector>
\ No newline at end of file
diff --git a/core/res/res/color-watch-v36/btn_material_filled_tonal_content_color.xml b/core/res/res/color-watch-v36/btn_material_filled_tonal_content_color.xml
index 59810356..32de688 100644
--- a/core/res/res/color-watch-v36/btn_material_filled_tonal_content_color.xml
+++ b/core/res/res/color-watch-v36/btn_material_filled_tonal_content_color.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:alpha="?attr/primaryContentAlpha"
- android:color="?attr/materialColorOnSurface" />
- <item android:color="?attr/materialColorOnSurface" />
+ android:color="@color/materialColorOnSurface" />
+ <item android:color="@color/materialColorOnSurface" />
</selector>
\ No newline at end of file
diff --git a/core/res/res/color-watch-v36/btn_material_outlined_background_color.xml b/core/res/res/color-watch-v36/btn_material_outlined_background_color.xml
index 665f47f..3f43ca7 100644
--- a/core/res/res/color-watch-v36/btn_material_outlined_background_color.xml
+++ b/core/res/res/color-watch-v36/btn_material_outlined_background_color.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:alpha="?attr/disabledAlpha"
- android:color="?attr/materialColorOnSurface" />
- <item android:color="?attr/materialColorOutline" />
+ android:color="@color/materialColorOnSurface" />
+ <item android:color="@color/materialColorOutline" />
</selector>
diff --git a/core/res/res/color/input_method_switch_on_item.xml b/core/res/res/color/input_method_switch_on_item.xml
index 49fe081..f38e0ac 100644
--- a/core/res/res/color/input_method_switch_on_item.xml
+++ b/core/res/res/color/input_method_switch_on_item.xml
@@ -16,6 +16,6 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_activated="true" android:color="?attr/materialColorOnSecondaryContainer" />
- <item android:color="?attr/materialColorOnSurface" />
+ <item android:state_activated="true" android:color="@color/materialColorOnSecondaryContainer" />
+ <item android:color="@color/materialColorOnSurface" />
</selector>
diff --git a/core/res/res/color/notification_expand_button_state_tint.xml b/core/res/res/color/notification_expand_button_state_tint.xml
index 5a8594f..3409a2c 100644
--- a/core/res/res/color/notification_expand_button_state_tint.xml
+++ b/core/res/res/color/notification_expand_button_state_tint.xml
@@ -16,9 +16,9 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:state_pressed="true" android:color="?androidprv:attr/materialColorOnPrimaryFixed"
+ <item android:state_pressed="true" android:color="@androidprv:color/materialColorOnPrimaryFixed"
android:alpha="0.15"/>
- <item android:state_hovered="true" android:color="?androidprv:attr/materialColorOnPrimaryFixed"
+ <item android:state_hovered="true" android:color="@androidprv:color/materialColorOnPrimaryFixed"
android:alpha="0.11"/>
<item android:color="@color/transparent" />
</selector>
\ No newline at end of file
diff --git a/core/res/res/color/system_on_surface_disabled.xml b/core/res/res/color/system_on_surface_disabled.xml
index aba87f5..039ab02 100644
--- a/core/res/res/color/system_on_surface_disabled.xml
+++ b/core/res/res/color/system_on_surface_disabled.xml
@@ -15,6 +15,6 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="?attr/materialColorOnSurface"
+ <item android:color="@color/materialColorOnSurface"
android:alpha="?attr/disabledAlpha" />
</selector>
diff --git a/core/res/res/color/system_outline_disabled.xml b/core/res/res/color/system_outline_disabled.xml
index 0a67ce3..b5a6b6b 100644
--- a/core/res/res/color/system_outline_disabled.xml
+++ b/core/res/res/color/system_outline_disabled.xml
@@ -15,6 +15,6 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="?attr/materialColorOutline"
+ <item android:color="@color/materialColorOutline"
android:alpha="?attr/disabledAlpha" />
</selector>
diff --git a/core/res/res/color/system_surface_disabled.xml b/core/res/res/color/system_surface_disabled.xml
index 2d7fe7d..1572272 100644
--- a/core/res/res/color/system_surface_disabled.xml
+++ b/core/res/res/color/system_surface_disabled.xml
@@ -15,6 +15,6 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="?attr/materialColorSurface"
+ <item android:color="@color/materialColorSurface"
android:alpha="?attr/disabledAlpha" />
</selector>
diff --git a/core/res/res/drawable-watch-v36/progress_ring_wear_material3.xml b/core/res/res/drawable-watch-v36/progress_ring_wear_material3.xml
index 5c0e5f6..8250ee6 100644
--- a/core/res/res/drawable-watch-v36/progress_ring_wear_material3.xml
+++ b/core/res/res/drawable-watch-v36/progress_ring_wear_material3.xml
@@ -27,7 +27,7 @@
android:innerRadiusRatio="@dimen/progressbar_inner_radius_ratio"
android:thickness="@dimen/progressbar_thickness"
android:useLevel="false">
- <solid android:color="?attr/materialColorSurfaceContainer"/>
+ <solid android:color="@color/materialColorSurfaceContainer"/>
</shape>
</item>
<item>
@@ -36,7 +36,7 @@
android:innerRadiusRatio="@dimen/progressbar_inner_radius_ratio"
android:thickness="@dimen/progressbar_thickness"
android:useLevel="true">
- <solid android:color="?attr/materialColorPrimary"/>
+ <solid android:color="@color/materialColorPrimary"/>
</shape>
</item>
</layer-list>
diff --git a/core/res/res/drawable/floating_popup_background.xml b/core/res/res/drawable/floating_popup_background.xml
index 99acedf..7200954 100644
--- a/core/res/res/drawable/floating_popup_background.xml
+++ b/core/res/res/drawable/floating_popup_background.xml
@@ -18,7 +18,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHighest"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHighest"/>
<corners android:radius="?android:attr/dialogCornerRadius" />
</shape>
diff --git a/core/res/res/drawable/immersive_cling_bg.xml b/core/res/res/drawable/immersive_cling_bg.xml
index de29c32..b28a423 100644
--- a/core/res/res/drawable/immersive_cling_bg.xml
+++ b/core/res/res/drawable/immersive_cling_bg.xml
@@ -20,5 +20,5 @@
<corners
android:bottomLeftRadius="28dp"
android:bottomRightRadius="28dp"/>
- <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
</shape>
diff --git a/core/res/res/drawable/input_method_switch_button.xml b/core/res/res/drawable/input_method_switch_button.xml
index 396d81e..1ee9b81 100644
--- a/core/res/res/drawable/input_method_switch_button.xml
+++ b/core/res/res/drawable/input_method_switch_button.xml
@@ -30,7 +30,7 @@
<shape android:shape="rectangle">
<corners android:radius="28dp"/>
<solid android:color="@color/transparent"/>
- <stroke android:color="?attr/materialColorPrimary"
+ <stroke android:color="@color/materialColorPrimary"
android:width="1dp"/>
<padding android:left="16dp"
android:top="8dp"
diff --git a/core/res/res/drawable/input_method_switch_item_background.xml b/core/res/res/drawable/input_method_switch_item_background.xml
index eb7a246..ce5b6f9 100644
--- a/core/res/res/drawable/input_method_switch_item_background.xml
+++ b/core/res/res/drawable/input_method_switch_item_background.xml
@@ -29,7 +29,7 @@
<item android:state_activated="true">
<shape android:shape="rectangle">
<corners android:radius="28dp"/>
- <solid android:color="?attr/materialColorSecondaryContainer"/>
+ <solid android:color="@color/materialColorSecondaryContainer"/>
</shape>
</item>
</selector>
diff --git a/core/res/res/layout/floating_popup_menu_button.xml b/core/res/res/layout/floating_popup_menu_button.xml
index 0b3861c..f6e6adf 100644
--- a/core/res/res/layout/floating_popup_menu_button.xml
+++ b/core/res/res/layout/floating_popup_menu_button.xml
@@ -54,7 +54,7 @@
android:ellipsize="end"
android:fontFamily="@*android:string/config_bodyFontFamily"
android:textSize="@dimen/floating_toolbar_text_size"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:background="@null"
android:focusable="false"
android:focusableInTouchMode="false"
diff --git a/core/res/res/layout/floating_popup_overflow_button.xml b/core/res/res/layout/floating_popup_overflow_button.xml
index a51836b..5fd774f 100644
--- a/core/res/res/layout/floating_popup_overflow_button.xml
+++ b/core/res/res/layout/floating_popup_overflow_button.xml
@@ -26,4 +26,4 @@
android:paddingBottom="@dimen/floating_toolbar_menu_image_button_vertical_padding"
android:scaleType="centerInside"
android:background="?attr/actionBarItemBackground"
- android:tint="?androidprv:attr/materialColorOnSurface" />
+ android:tint="@androidprv:color/materialColorOnSurface" />
diff --git a/core/res/res/layout/immersive_mode_cling.xml b/core/res/res/layout/immersive_mode_cling.xml
index 2cde9e6..4e869b7 100644
--- a/core/res/res/layout/immersive_mode_cling.xml
+++ b/core/res/res/layout/immersive_mode_cling.xml
@@ -42,7 +42,7 @@
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:text="@string/immersive_cling_title"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textSize="24sp"
android:fontFamily="google-sans" />
@@ -54,7 +54,7 @@
android:paddingTop="14dp"
android:gravity="center_horizontal"
android:text="@string/immersive_cling_description"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
android:textSize="14sp"
android:fontFamily="google-sans" />
@@ -72,7 +72,7 @@
android:minWidth="48dp"
android:minHeight="48dp"
android:text="@string/immersive_cling_positive"
- android:textColor="?androidprv:attr/materialColorOnPrimary"
+ android:textColor="@androidprv:color/materialColorOnPrimary"
android:textAllCaps="false"
android:textSize="14sp"
android:textFontWeight="500"
diff --git a/core/res/res/layout/input_method_switch_item_divider.xml b/core/res/res/layout/input_method_switch_item_divider.xml
index 4f8c963..b56cfb7 100644
--- a/core/res/res/layout/input_method_switch_item_divider.xml
+++ b/core/res/res/layout/input_method_switch_item_divider.xml
@@ -26,7 +26,7 @@
<View
android:layout_width="match_parent"
android:layout_height="1dp"
- android:background="?attr/materialColorOutlineVariant"
+ android:background="@color/materialColorOutlineVariant"
android:layout_marginStart="20dp"
android:layout_marginEnd="24dp"
android:importantForAccessibility="no"/>
diff --git a/core/res/res/layout/input_method_switch_item_header.xml b/core/res/res/layout/input_method_switch_item_header.xml
index f0080a6..05c73d0 100644
--- a/core/res/res/layout/input_method_switch_item_header.xml
+++ b/core/res/res/layout/input_method_switch_item_header.xml
@@ -33,6 +33,6 @@
android:fontFamily="google-sans-text"
android:textAppearance="?attr/textAppearance"
android:accessibilityHeading="true"
- android:textColor="?attr/materialColorPrimary"/>
+ android:textColor="@color/materialColorPrimary"/>
</LinearLayout>
diff --git a/core/res/res/layout/input_method_switch_item_new.xml b/core/res/res/layout/input_method_switch_item_new.xml
index 7b241af..3688608 100644
--- a/core/res/res/layout/input_method_switch_item_new.xml
+++ b/core/res/res/layout/input_method_switch_item_new.xml
@@ -56,7 +56,7 @@
android:marqueeRepeatLimit="1"
android:singleLine="true"
android:fontFamily="google-sans-text"
- android:textColor="?attr/materialColorOnSurfaceVariant"
+ android:textColor="@color/materialColorOnSurfaceVariant"
android:textAppearance="?attr/textAppearanceListItemSecondary"
android:textAllCaps="true"
android:visibility="gone"/>
diff --git a/core/res/res/layout/notification_2025_text.xml b/core/res/res/layout/notification_2025_text.xml
index 48b1083..474f6d2 100644
--- a/core/res/res/layout/notification_2025_text.xml
+++ b/core/res/res/layout/notification_2025_text.xml
@@ -21,6 +21,7 @@
android:layout_height="@dimen/notification_text_height"
android:layout_gravity="top"
android:layout_marginTop="@dimen/notification_text_margin_top"
+ android:ellipsize="end"
android:fadingEdge="horizontal"
android:gravity="top"
android:maxLines="1"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index edb926c..c02c13c 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -369,13 +369,13 @@
<string name="permlab_statusBar" msgid="8798267849526214017">"deaktiveer of verander statusbalk"</string>
<string name="permdesc_statusBar" msgid="5809162768651019642">"Laat die app toe om die statusbalk te deaktiveer en stelselikone by te voeg of te verwyder."</string>
<string name="permlab_statusBarService" msgid="2523421018081437981">"wees die statusbalk"</string>
- <string name="permdesc_statusBarService" msgid="6652917399085712557">"Laat die program toe om die statusbalk te wees."</string>
+ <string name="permdesc_statusBarService" msgid="6652917399085712557">"Laat die app toe om die statusbalk te wees."</string>
<string name="permlab_expandStatusBar" msgid="1184232794782141698">"vou statusbalk in of uit"</string>
<string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Laat die program toe om die statusbalk uit te vou of in te vou."</string>
<string name="permlab_fullScreenIntent" msgid="4310888199502509104">"wys kennisgewings as volskermaktiwiteite op \'n geslote skerm"</string>
<string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Laat die program toe om kennisgewings as volskermaktiwiteite op \'n geslote toestel te wys"</string>
<string name="permlab_install_shortcut" msgid="7451554307502256221">"installeer kortpaaie"</string>
- <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Stel \'n program in staat om Tuisskerm-kortpaaie by te voeg sonder gebruikerinmenging."</string>
+ <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Stel \'n app in staat om Tuisskerm-kortpaaie by te voeg sonder gebruikerinmenging."</string>
<string name="permlab_uninstall_shortcut" msgid="295263654781900390">"deïnstalleer kortpaaie"</string>
<string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Laat die app toe om Tuisskerm-kortpaaie te verwyder sonder gebruikerinmenging."</string>
<string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"herlei uitgaande oproepe"</string>
@@ -387,17 +387,17 @@
<string name="permlab_receiveMms" msgid="4000650116674380275">"ontvang teksboodskappe (MMS)"</string>
<string name="permdesc_receiveMms" msgid="958102423732219710">"Laat die program toe om MMS-boodskappe te ontvang en te verwerk. Dit beteken dat die program boodskappe wat na jou toestel gestuur is kan monitor of uitvee, sonder dat jy dit gesien het."</string>
<string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"Stuur seluitsendingboodskappe aan"</string>
- <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Laat die program toe om die seluitsendingmodule te bind om seluitsendingboodskappe aan te stuur wanneer hulle ontvang word. Seluitsendingwaarskuwings word in sommige liggings gelewer om jou oor noodsituasies te waarsku. Kwaadwillige programme kan met die werkverrigting of werking van jou toestel inmeng wanneer \'n noodseluitsending ontvang word."</string>
+ <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Laat die app toe om aan die seluitsendingmodule te bind om seluitsendingboodskappe aan te stuur wanneer hulle ontvang word. Seluitsendingwaarskuwings word in sommige liggings gelewer om jou oor noodsituasies te waarsku. Kwaadwillige apps kan met die werkverrigting of werking van jou toestel inmeng wanneer \'n noodseluitsending ontvang word."</string>
<string name="permlab_manageOngoingCalls" msgid="281244770664231782">"Bestuur voortgaande oproepe"</string>
<string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"Stel \'n program in staat om besonderhede oor voortgaande oproepe op jou toestel te sien, en hierdie oproepe te beheer."</string>
<string name="permlab_accessLastKnownCellId" msgid="7638226620825665130">"Kry toegang tot laaste bekende selidentiteit."</string>
<string name="permdesc_accessLastKnownCellId" msgid="6664621339249308857">"Laat ’n app toe om toegang tot die laaste bekende selidentiteit te kry wat deur telefonie verskaf is"</string>
<string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"lees seluitsending-boodskappe"</string>
- <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Laat die program toe om seluitsending-boodskappe te lees wat deur jou toestel ontvang word. Seluitsending-waarskuwings word in sommige plekke afgelewer om jou van noodsituasies te waarsku. Kwaadwillige programme mag inmeng met die prestasie of die werking van jou toestel wanneer \'n noodgeval se seluitsending ontvang word."</string>
+ <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Laat die app toe om seluitsending-boodskappe te lees wat deur jou toestel ontvang word. Seluitsending-waarskuwings word in sommige plekke afgelewer om jou van noodsituasies te waarsku. Kwaadwillige apps kan inmeng met die prestasie of die werking van jou toestel wanneer \'n noodgeval se seluitsending ontvang word."</string>
<string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"lees ingetekende nuus"</string>
- <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Laat die program toe om details oor die tans gesinkroniseerde strome te kry."</string>
+ <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Laat die app toe om details oor die tans gesinkroniseerde strome te kry."</string>
<string name="permlab_sendSms" msgid="7757368721742014252">"SMS-boodskappe te stuur en te bekyk"</string>
- <string name="permdesc_sendSms" msgid="6757089798435130769">"Laat die program toe om SMS-boodskappe te stuur. Dit kan tot onverwagse heffings lei. Kwaadwillige programme kan jou geld kos deur boodskappe sonder jou bevestiging te stuur."</string>
+ <string name="permdesc_sendSms" msgid="6757089798435130769">"Laat die app toe om SMS-boodskappe te stuur. Dit kan tot onverwagse heffings lei. Kwaadwillige apps kan jou geld kos deur boodskappe sonder jou bevestiging te stuur."</string>
<string name="permlab_readSms" msgid="5164176626258800297">"lees jou teksboodskappe (SMS of MMS)"</string>
<string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Hierdie program kan alle SMS\'e (teksboodskappe) wat op jou tablet geberg is, lees."</string>
<string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Hierdie app kan alle SMS- (teks)-boodskappe lees wat op jou Android TV-toestel geberg is."</string>
@@ -411,24 +411,24 @@
<string name="permlab_reorderTasks" msgid="7598562301992923804">"herrangskik lopende programme"</string>
<string name="permdesc_reorderTasks" msgid="8796089937352344183">"Laat die program toe om take na die voorgrond of agtergrond te skuif. Die program kan dit moontlik sonder jou insette doen."</string>
<string name="permlab_enableCarMode" msgid="893019409519325311">"aktiveer motormodus"</string>
- <string name="permdesc_enableCarMode" msgid="56419168820473508">"Laat die program toe om die motormodus te aktiveer."</string>
+ <string name="permdesc_enableCarMode" msgid="56419168820473508">"Laat die app toe om die motormodus te aktiveer."</string>
<string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"maak ander programme toe"</string>
<string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"Laat die app toe om agtergrondprosesse van ander apps te beëindig. Dit kan moontlik veroorsaak dat ander apps ophou werk."</string>
- <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Hierdie program kan bo-op ander programme verskyn"</string>
+ <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Hierdie app kan bo-op ander apps verskyn"</string>
<string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Hierdie app kan bokant ander apps of ander dele van die skerm verskyn. Dit kan met normale appgebruik inmeng en die voorkoms van ander apps verander."</string>
<string name="permlab_hideOverlayWindows" msgid="6382697828482271802">"versteek ander apps se oorleggers"</string>
<string name="permdesc_hideOverlayWindows" msgid="5660242821651958225">"Hierdie app kan versoek dat die stelsel oorleggers wat oorspronklik van apps af kom, versteek sodat hulle nie bo-op hulle wys nie."</string>
<string name="permlab_runInBackground" msgid="541863968571682785">"loop op die agtergrond"</string>
- <string name="permdesc_runInBackground" msgid="4344539472115495141">"Hierdie program kan op die agtergrond loop. Dit kan die battery vinniger laat pap word."</string>
+ <string name="permdesc_runInBackground" msgid="4344539472115495141">"Hierdie app kan op die agtergrond loop. Dit kan die battery vinniger laat pap word."</string>
<string name="permlab_useDataInBackground" msgid="783415807623038947">"gebruik data op die agtergrond"</string>
<string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Hierdie app kan data op die agtergrond gebruik. Dit kan die datagebruik vergroot."</string>
<string name="permlab_schedule_exact_alarm" msgid="6683283918033029730">"Skeduleer handelinge met presiese tydsbesturing"</string>
<string name="permdesc_schedule_exact_alarm" msgid="8198009212013211497">"Hierdie app kan werk skeduleer om op ’n gewenste tyd in die toekoms plaas te vind. Dit beteken ook dat die app kan werk wanneer die toestel nie aktief gebruik word nie."</string>
<string name="permlab_use_exact_alarm" msgid="348045139777131552">"Skeduleer wekkers of geleentheidonthounotas"</string>
<string name="permdesc_use_exact_alarm" msgid="7033761461886938912">"Hierdie app kan handelinge soos wekkers en onthounotas skeduleer om jou op ’n gewenste tyd in die toekoms in kennis te stel."</string>
- <string name="permlab_persistentActivity" msgid="464970041740567970">"laat program altyd loop"</string>
- <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Laat die program toe om dele van ditself deurdringend in die geheue te hou. Dit kan geheue wat aan ander programme beskikbaar is, beperk, en die tablet stadiger maak."</string>
- <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Laat die program toe om dele daarvan in die geheue te laat voortbestaan. Dit kan geheue wat vir ander programme beskikbaar is, beperk en sodoende jou Android TV-toestel stadiger maak."</string>
+ <string name="permlab_persistentActivity" msgid="464970041740567970">"laat app altyd loop"</string>
+ <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Laat die app toe om dele van die app deurdringend in die geheue te hou. Dit kan geheue wat aan ander apps beskikbaar is, beperk, en die tablet stadiger maak."</string>
+ <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Laat die app toe om dele daarvan in die geheue te laat voortbestaan. Dit kan geheue wat vir ander apps beskikbaar is, beperk en sodoende jou Android TV-toestel stadiger maak."</string>
<string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Laat die app toe om dele van die app deurdringend in die geheue te hou. Dit kan geheue wat aan ander apps beskikbaar is, beperk, en die foon stadiger maak."</string>
<string name="permlab_foregroundService" msgid="1768855976818467491">"laat loop voorgronddiens"</string>
<string name="permdesc_foregroundService" msgid="8720071450020922795">"Laat die program toe om van voorgronddienste gebruik te maak."</string>
@@ -465,8 +465,8 @@
<string name="permlab_writeSettings" msgid="8057285063719277394">"verander stelsel-instellings"</string>
<string name="permdesc_writeSettings" msgid="8293047411196067188">"Laat die program toe om die stelsel se instellingsdata te verander. Kwaadwillige programme kan dalk jou stelsel se opstelling korrupteer."</string>
<string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"laat loop wanneer begin"</string>
- <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Laat die program toe om homself te begin so gou as moontlik nadat die stelsel laai. Dit maak dat dit langer neem vir die tablet om te begin, en dit laat die foon toe om die tablet stadiger te maak omdat dit altyd loop."</string>
- <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Laat die program toe om self te begin sodra die stelsel klaar geselflaai het. Dit kan dalk daartoe lei dat die toestel langer neem om jou Android TV-toestel te begin, en laat die program toe om die hele toestel stadiger te maak deur altyd te loop."</string>
+ <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Laat die app toe om self te begin sodra die stelsel geselflaai het. Dit maak dat dit langer neem vir die tablet om te begin, en dit laat die foon toe om die tablet stadiger te maak omdat dit altyd loop."</string>
+ <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Laat die app toe om self te begin sodra die stelsel klaar geselflaai het. Dit kan dalk daartoe lei dat die toestel langer neem om jou Android TV-toestel te begin, en laat die app toe om die hele toestel stadiger te maak deur altyd te loop."</string>
<string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"Laat die program toe om homself te begin so gou as moontlik nadat die stelsel laai. Dit maak dat dit langer neem vir die foon om te begin, en dit laat die foon toe om die foon stadiger te maak omdat dit altyd loop."</string>
<string name="permlab_broadcastSticky" msgid="4552241916400572230">"Stuur klewerige uitsending"</string>
<string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"Laat die app toe om vaste uitsendings te stuur, wat agterbly nadat die uitsending klaar is. Oormatige gebruik kan die tablet stadig of onstabiel maak deurdat dit te veel geheue gebruik."</string>
@@ -484,20 +484,20 @@
<string name="permdesc_readCallLog" msgid="8964770895425873433">"Hierdie program kan jou oproepgeskiedenis lees."</string>
<string name="permlab_writeCallLog" msgid="670292975137658895">"skryf oproeprekord"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Laat die app toe om jou tablet se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige apps kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
- <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Laat die program toe om jou Android TV-toestel se oproeprekord te wysig, insluitend data oor inkomende en uitgaande oproepe. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te wysig."</string>
- <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Laat die program toe om jou foon se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
- <string name="permlab_bodySensors" msgid="662918578601619569">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl program gebruik word"</string>
+ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Laat die app toe om jou Android TV-toestel se oproeprekord te wysig, insluitend data oor inkomende en uitgaande oproepe. Kwaadwillige apps kan dit gebruik om jou oproeprekord uit te vee of te wysig."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Laat die app toe om jou foon se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige apps kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
+ <string name="permlab_bodySensors" msgid="662918578601619569">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl app gebruik word"</string>
<string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Gee die app toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl die app gebruik word."</string>
- <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl program op agtergrond is"</string>
- <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Gee die program toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl dit op die agtergrond is."</string>
+ <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl app op die agtergrond is"</string>
+ <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Gee die app toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl dit op die agtergrond is."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Lees kalendergebeurtenisse en -besonderhede"</string>
- <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Hierdie program kan alle kalendergebeurtenisse lees wat op jou tablet geberg is of jou kalenderdata stoor."</string>
- <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Hierdie program kan alle kalendergeleenthede wat op jou Android TV-toestel geberg is, lees of jou kalenderdata stoor."</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Hierdie app kan alle kalendergebeurtenisse lees wat op jou tablet geberg is of jou kalenderdata stoor."</string>
+ <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Hierdie app kan alle kalendergeleenthede lees wat op jou Android TV-toestel geberg is of jou kalenderdata stoor."</string>
<string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Hierdie program kan alle kalendergebeurtenisse lees wat op jou foon geberg is of jou kalenderdata stoor."</string>
<string name="permlab_writeCalendar" msgid="6422137308329578076">"voeg by of verander kalenderafsprake en stuur \'n e-pos aan gaste sonder eienaars se medewete"</string>
<string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Hierdie program kan kalendergebeurtenisse op jou tablet byvoeg, verwyder of verander. Hierdie program kan boodskappe stuur wat lyk of dit van kalendereienaars af kom of gebeurtenisse verander sonder om hul eienaars in te lig."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Hierdie program kan kalendergeleenthede op jou Android TV-toestel byvoeg, verwyder of verander. Hierdie program kan boodskappe stuur wat lyk of dit van kalendereienaars af kom of geleenthede verander sonder om hul eienaars in kennis te stel."</string>
- <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Hierdie program kan kalendergebeurtenisse op jou foon byvoeg, verwyder of verander. Hierdie program kan boodskappe stuur wat lyk of dit van kalendereienaars af kom of gebeurtenisse verander sonder om hul eienaars in te lig."</string>
+ <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Hierdie app kan kalendergebeurtenisse op jou foon byvoeg, verwyder of verander. Hierdie app kan boodskappe stuur wat lyk of dit van kalendereienaars af kom of gebeurtenisse verander sonder om hul eienaars in te lig."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"Kry toegang tot ekstra liggingverskaffer-bevele"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Gee die app toegang tot ekstra liggingverskaffer-bevele. Dit kan die app dalk toelaat om in te meng met die werking van die GPS of ander liggingbronne."</string>
<string name="permlab_accessFineLocation" msgid="6426318438195622966">"kry net op die voorgrond toegang tot presiese ligging"</string>
@@ -515,7 +515,7 @@
<string name="permlab_detectScreenCapture" msgid="4447042362828799433">"bespeur skermskote van appvensters"</string>
<string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Hierdie app sal ingelig word as ’n skermskoot geneem word terwyl die app gebruik word."</string>
<string name="permlab_sim_communication" msgid="176788115994050692">"stuur bevele na die SIM"</string>
- <string name="permdesc_sim_communication" msgid="4179799296415957960">"Laat die program toe om bevele na die SIM te stuur. Dit is baie gevaarlik."</string>
+ <string name="permdesc_sim_communication" msgid="4179799296415957960">"Laat die app toe om bevele na die SIM te stuur. Dit is baie gevaarlik."</string>
<string name="permlab_activityRecognition" msgid="1782303296053990884">"herken fisieke aktiwiteit"</string>
<string name="permdesc_activityRecognition" msgid="8667484762991357519">"Hierdie program kan jou fisieke aktiwiteit herken."</string>
<string name="permlab_camera" msgid="6320282492904119413">"neem foto\'s en video\'s"</string>
@@ -534,19 +534,19 @@
<string name="permlab_callPhone" msgid="1798582257194643320">"skakel foonnommers direk"</string>
<string name="permdesc_callPhone" msgid="7892422187827695656">"Laat die app toe om foonnommers sonder jou insae te bel. Dit kan onvoorsiene heffings of oproepe tot gevolg hê. Neem kennis dat dit nie die app toelaat om noodnommers te bel nie. Kwaadwillige apps kan jou geld kos deur oproepe te maak sonder jou bevestiging of diensverskafferkodes te bel wat veroorsaak dat inkomende oproepe outomaties na ’n ander nommer aangestuur word."</string>
<string name="permlab_accessImsCallService" msgid="442192920714863782">"toegang tot kitsboodskapoproepdiens"</string>
- <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Laat die program toe om die kitsboodskapdiens te gebruik om oproepe sonder jou ingryping te maak."</string>
+ <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Laat die app toe om die kitsboodskapdiens te gebruik om oproepe sonder jou ingryping te maak."</string>
<string name="permlab_readPhoneState" msgid="8138526903259297969">"lees foonstatus en identiteit"</string>
<string name="permdesc_readPhoneState" msgid="7229063553502788058">"Laat die program toe om toegang tot die foonfunksies van die toestel te verkry. Hierdie toestemming laat die program toe om te bepaal wat die foonnommer en toestel-IDs is, of die oproep aan die gang is, en die afgeleë nommer wat deur \'n oproep verbind word."</string>
<string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"lees basiese telefoniestatus en -identiteit"</string>
<string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Gee die program toegang tot die toestel se basiese telefoniekenmerke."</string>
<string name="permlab_manageOwnCalls" msgid="9033349060307561370">"roeteer oproepe deur die stelsel"</string>
- <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Laat die program toe om sy oproepe deur die stelsel te stuur om die oproepervaring te verbeter."</string>
+ <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Laat die app toe om sy oproepe deur die stelsel te stuur om die oproepervaring te verbeter."</string>
<string name="permlab_callCompanionApp" msgid="3654373653014126884">"sien en beheer oproepe deur die stelsel."</string>
<string name="permdesc_callCompanionApp" msgid="8474168926184156261">"Laat die program toe om deurlopende oproepe op die toestel te sien en te beheer. Dit sluit inligting in soos oproepnommers vir oproepe en die toedrag van die oproepe."</string>
<string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"vrygestel van beperkings op oudio-opnames"</string>
<string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"Stel die program vry van beperkings om oudio op te neem."</string>
<string name="permlab_acceptHandover" msgid="2925523073573116523">"gaan voort met \'n oproep uit \'n ander app"</string>
- <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Laat die program toe om \'n oproep voort te sit wat in \'n ander program begin is."</string>
+ <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Laat die app toe om \'n oproep voort te sit wat in \'n ander app begin is."</string>
<string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"lees foonnommers"</string>
<string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Laat die program toe om toegang tot die toestel se foonnommers te kry."</string>
<string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"hou motorskerm aan"</string>
@@ -558,7 +558,7 @@
<string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Laat die app toe om te keer dat jou Android TV-toestel slaap."</string>
<string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"Laat die app toe om die foon te keer om te slaap."</string>
<string name="permlab_transmitIr" msgid="8077196086358004010">"versend infrarooi"</string>
- <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Laat die program toe om die tablet se infrarooisender te gebruik."</string>
+ <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Laat die app toe om die tablet se infrarooisender te gebruik."</string>
<string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Laat die app toe om jou Android TV-toestel se infrarooisender te gebruik."</string>
<string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Laat die program toe om die foon se infrarooisender te gebruik."</string>
<string name="permlab_setWallpaper" msgid="6959514622698794511">"stel muurpapier"</string>
@@ -566,25 +566,25 @@
<string name="permlab_accessHiddenProfile" msgid="8607094418491556823">"Kry toegang tot versteekte profiele"</string>
<string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"Laat die app toe om toegang tot versteekte profiele te kry."</string>
<string name="permlab_setWallpaperHints" msgid="1153485176642032714">"verstel jou muurpapier se grootte"</string>
- <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Laat die program toe om die stelsel se muurpapier se groottewenke te stel."</string>
+ <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Laat die app toe om die stelsel se muurpapier se groottewenke te stel."</string>
<string name="permlab_setTimeZone" msgid="7922618798611542432">"stel tydsone"</string>
<string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"Laat die app toe om die tablet se tydsone te verander."</string>
<string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Laat die program toe om jou Android TV-toestel se tydsone te verander."</string>
- <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Laat die program toe om die foon se tydsone te verander."</string>
+ <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Laat die app toe om die foon se tydsone te verander."</string>
<string name="permlab_getAccounts" msgid="5304317160463582791">"soek rekeninge op die toestel"</string>
<string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Laat die app toe om die lys van rekeninge wat aan die tablet bekend is, te kry. Dit kan moontlik enige rekeninge wat geskep is deur apps wat jy geïnstalleer het, insluit."</string>
- <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Laat die program toe om die lys rekeninge wat aan jou Android TV-toestel bekend is, te kry. Dit kan dalk rekeninge insluit wat geskep is deur programme wat jy geïnstalleer het."</string>
+ <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Laat die app toe om die lys rekeninge wat aan jou Android TV-toestel bekend is, te kry. Dit kan dalk rekeninge insluit wat geskep is deur apps wat jy geïnstalleer het."</string>
<string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Laat die app toe om die lys van rekeninge wat aan die foon bekend is, te kry. Dit kan moontlik enige rekeninge wat geskep is deur apps wat jy geïnstalleer het, insluit."</string>
<string name="permlab_accessNetworkState" msgid="2349126720783633918">"bekyk netwerkverbindings"</string>
- <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Laat die program toe om inligting oor netwerkverbindings, soos watter netwerke bestaan en gekoppel is, te sien."</string>
+ <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Laat die app toe om inligting oor netwerkverbindings, soos watter netwerke bestaan en gekoppel is, te sien."</string>
<string name="permlab_createNetworkSockets" msgid="3224420491603590541">"verkry volle netwerktoegang"</string>
<string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"Laat die program toe om netwerksokke te skep en gepasmaakte netwerkprotokolle te gebruik. Die blaaier en ander programme verskaf reeds die middele waardeur data na die internet gestuur kan word, so hierdie toestemming word nie vereis om data na die internet te stuur nie."</string>
<string name="permlab_changeNetworkState" msgid="8945711637530425586">"verander netwerkverbinding"</string>
- <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Laat die program toe om die status van netwerkkonnektiwiteit te verander."</string>
+ <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Laat die app toe om die status van netwerkkonnektiwiteit te verander."</string>
<string name="permlab_changeTetherState" msgid="9079611809931863861">"verander verbinde konnektiwiteit"</string>
<string name="permdesc_changeTetherState" msgid="3025129606422533085">"Laat die app toe om die status van verbinde netwerkkonnektiwiteit te verander."</string>
<string name="permlab_accessWifiState" msgid="5552488500317911052">"bekyk Wi-Fi-verbindings"</string>
- <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Laat die program toe om inligting oor Wi-Fi-netwerke, soos of Wi-Fi geaktiveer is en die name van gekoppelde Wi-Fi toestelle, te sien."</string>
+ <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Laat die app toe om inligting oor wi-fi-netwerke, soos of wi-fi geaktiveer is en die name van gekoppelde wi-fi-toestelle, te sien."</string>
<string name="permlab_changeWifiState" msgid="7947824109713181554">"koppel en ontkoppel van Wi-Fi"</string>
<string name="permdesc_changeWifiState" msgid="7170350070554505384">"Laat die program toe om te koppel aan en te ontkoppel van Wi-Fi-toegangspunte en om veranderings aan Wi-Fi-netwerke se toestelopstellings te maak."</string>
<string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"laat Wi-Fi-multisendontvangs toe"</string>
@@ -592,14 +592,14 @@
<string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Laat die app toe om pakkette te ontvang wat met multi-uitsendingadresse na alle toestelle op \'n wi-fi-netwerk gestuur is, nie net jou Android TV-toestel nie. Dit gebruik meer krag as nie-multi-uitsendingmodus."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Laat die program toe om pakkies te ontvang wat met behulp van multisaai-adresse na alle toestelle op \'n Wi-Fi-netwerk gestuur is, nie net jou foon nie. Dit gebruik meer krag as die nie-multisaaimodus."</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"gaan in by Bluetooth-instellings"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Laat die program toe om die plaaslike Bluetooth-tablet op te stel, en om met afstandbeheer toestelle saam te bind."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Laat die app toe om die plaaslike Bluetooth-tablet op te stel, en om met afstandbeheer toestelle saam te bind."</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Laat die app toe om Bluetooth op jou Android TV-toestel op te stel, en om afgeleë toestelle te ontdek en met hulle saam te bind."</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Laat die program toe om die plaaslike Bluetooth-foon op te stel en te ontdek en met afgeleë toestelle saam te bind."</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"koppel aan en ontkoppel van WiMAX"</string>
- <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Laat die program toe om te bepaal of WiMAX geaktiveer is en of enige WiMAX-netwerke gekoppel is."</string>
+ <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Laat die app toe om te bepaal of WiMAX geaktiveer is en of enige WiMAX-netwerke gekoppel is."</string>
<string name="permlab_changeWimaxState" msgid="6223305780806267462">"verander WiMAX-status"</string>
- <string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Laat die program toe om die tablet aan WiMAX-netwerke te koppel en daarvan te ontkoppel."</string>
- <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Laat die program toe om jou Android TV-toestel aan WiMAX-netwerke te koppel en daarvan te ontkoppel."</string>
+ <string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Laat die app toe om die tablet aan WiMAX-netwerke te koppel en daarvan te ontkoppel."</string>
+ <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Laat die app toe om jou Android TV-toestel aan WiMAX-netwerke te koppel en daarvan te ontkoppel."</string>
<string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Laat die app toe om die foon aan WiMAX-netwerke te koppel en daarvan te ontkoppel."</string>
<string name="permlab_bluetooth" msgid="586333280736937209">"bind saam met Bluetooth-toestelle"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Laat die app toe om die opstelling van Bluetooth op die tablet te sien, en om verbindings met saamgebinde toestelle te maak en te aanvaar."</string>
@@ -630,21 +630,21 @@
<string name="permlab_postNotification" msgid="4875401198597803658">"wys kennisgewings"</string>
<string name="permdesc_postNotification" msgid="5974977162462877075">"Laat die program toe om kennisgewings te wys"</string>
<string name="permlab_turnScreenOn" msgid="219344053664171492">"skakel die skerm aan"</string>
- <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Laat die program toe om die skerm aan te skakel."</string>
+ <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"Laat die app toe om die skerm aan te skakel."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"gebruik biometriese hardeware"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Laat die program toe om biometriese hardeware vir stawing te gebruik"</string>
<string name="permlab_manageFingerprint" msgid="7432667156322821178">"bestuur vingerafdrukhardeware"</string>
<string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Laat die app toe om metodes te benut om vingerafdruktemplate vir gebruik by te voeg en uit te vee."</string>
<string name="permlab_useFingerprint" msgid="1001421069766751922">"gebruik vingerafdrukhardeware"</string>
- <string name="permdesc_useFingerprint" msgid="412463055059323742">"Laat die program toe om vingerafdrukhardeware vir stawing te gebruik"</string>
+ <string name="permdesc_useFingerprint" msgid="412463055059323742">"Laat die app toe om vingerafdrukhardeware vir stawing te gebruik"</string>
<string name="permlab_audioWrite" msgid="8501705294265669405">"wysig jou musiekversameling"</string>
<string name="permdesc_audioWrite" msgid="8057399517013412431">"Laat die program toe om jou musiekversameling te wysig."</string>
<string name="permlab_videoWrite" msgid="5940738769586451318">"wysig jou videoversameling"</string>
- <string name="permdesc_videoWrite" msgid="6124731210613317051">"Laat die program toe om jou videoversameling te wysig."</string>
+ <string name="permdesc_videoWrite" msgid="6124731210613317051">"Laat die app toe om jou videoversameling te wysig."</string>
<string name="permlab_imagesWrite" msgid="1774555086984985578">"wysig jou fotoversameling"</string>
- <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Laat die program toe om jou fotoversameling te wysig."</string>
+ <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Laat die app toe om jou fotoversameling te wysig."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"lees liggings in jou mediaversameling"</string>
- <string name="permdesc_mediaLocation" msgid="597912899423578138">"Laat die program toe om liggings in jou mediaversameling te lees."</string>
+ <string name="permdesc_mediaLocation" msgid="597912899423578138">"Laat die app toe om liggings in jou mediaversameling te lees."</string>
<string name="biometric_app_setting_name" msgid="3339209978734534457">"Gebruik biometrie"</string>
<string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Gebruik biometrie of skermslot"</string>
<string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifieer dat dit jy is"</string>
@@ -764,17 +764,17 @@
<string name="permlab_readSyncSettings" msgid="6250532864893156277">"lees sinkroniseer-instellings"</string>
<string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Laat die app toe om die sinkroniseringinstellings van \'n rekening te lees. Byvoorbeeld, dit kan bepaal of die People-app met \'n rekening gesinkroniseer is."</string>
<string name="permlab_writeSyncSettings" msgid="6583154300780427399">"wissel tussen sinkronisasie aan en af"</string>
- <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Laat \'n program toe om die sinkroniseringinstellings van \'n rekening te verander. Byvoorbeeld, dit kan gebruik word om sinkronisasie van die People-program met \'n ander rekening te aktiveer."</string>
+ <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Laat \'n app toe om die sinkroniseringinstellings van \'n rekening te verander. Byvoorbeeld, dit kan gebruik word om sinkronisasie van die People-app met \'n ander rekening te aktiveer."</string>
<string name="permlab_readSyncStats" msgid="3747407238320105332">"lees sinkroniseerstatistiek"</string>
- <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Laat \'n program toe om die sinkroniseringstatistieke van \'n rekening te lees, insluitend die geskiedenis van sinkroniseringgebeure en hoeveel data gesinkroniseer is."</string>
+ <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Laat \'n app toe om die sinkroniseringstatistieke van \'n rekening te lees, insluitend die geskiedenis van sinkroniseringgebeure en hoeveel data gesinkroniseer is."</string>
<string name="permlab_sdcardRead" msgid="5791467020950064920">"lees jou gedeelde berging se inhoud"</string>
- <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Laat die program toe om jou gedeelde berging se inhoud te lees."</string>
+ <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Laat die app toe om jou gedeelde berging se inhoud te lees."</string>
<string name="permlab_readMediaAudio" msgid="8723513075731763810">"lees oudiolêers in gedeelde berging"</string>
- <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Laat die program toe om oudiolêers in jou gedeelde berging te lees."</string>
+ <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Laat die app toe om oudiolêers in jou gedeelde berging te lees."</string>
<string name="permlab_readMediaVideo" msgid="7768003311260655007">"lees videolêers in gedeelde berging"</string>
- <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Laat die program toe om videolêers in jou gedeelde berging te lees."</string>
+ <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Laat die app toe om videolêers in jou gedeelde berging te lees."</string>
<string name="permlab_readMediaImages" msgid="4057590631020986789">"lees prentlêers in gedeelde berging"</string>
- <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Laat die program toe om prentlêers in jou gedeelde berging te lees."</string>
+ <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Laat die app toe om prentlêers in jou gedeelde berging te lees."</string>
<string name="permlab_readVisualUserSelect" msgid="5516204215354667586">"lees prent- en videolêers wat gebruiker in gedeelde berging kies"</string>
<string name="permdesc_readVisualUserSelect" msgid="8027174717714968217">"Laat die app toe om prent- en videolêers te lees wat jy in jou gedeelde berging kies."</string>
<string name="permlab_sdcardWrite" msgid="4863021819671416668">"verander of vee jou gedeelde berging se inhoud uit"</string>
@@ -782,23 +782,23 @@
<string name="permlab_use_sip" msgid="8250774565189337477">"maak en/of ontvang SIP-oproepe"</string>
<string name="permdesc_use_sip" msgid="3590270893253204451">"Laat die app toe om SIP-oproepe te maak en te ontvang."</string>
<string name="permlab_register_sim_subscription" msgid="1653054249287576161">"registreer nuwe telekommunikasie-SIM-verbindings"</string>
- <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Laat die program toe om nuwe telekommunikasie-SIM-verbindings te registreer."</string>
+ <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Laat die app toe om nuwe telekommunikasie-SIM-verbindings te registreer."</string>
<string name="permlab_register_call_provider" msgid="6135073566140050702">"registreer nuwe telekommunikasieverbindings"</string>
- <string name="permdesc_register_call_provider" msgid="4201429251459068613">"Laat die program toe om nuwe telekommunikasieverbindings te registreer."</string>
+ <string name="permdesc_register_call_provider" msgid="4201429251459068613">"Laat die app toe om nuwe telekommunikasieverbindings te registreer."</string>
<string name="permlab_connection_manager" msgid="3179365584691166915">"bestuur telekom-verbindings"</string>
<string name="permdesc_connection_manager" msgid="1426093604238937733">"Laat die app toe om telekom-verbindings te bestuur."</string>
<string name="permlab_bind_incall_service" msgid="5990625112603493016">"beleef interaksie met inoproep-skerm"</string>
- <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Laat die program beheer wanneer en hoe die gebruiker die inoproep-skerm sien."</string>
+ <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Laat die app beheer wanneer en hoe die gebruiker die inoproep-skerm sien."</string>
<string name="permlab_bind_connection_service" msgid="5409268245525024736">"werk met telefoniedienste saam"</string>
- <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Laat die program toe om met telefoniedienste saam te werk om oproepe te maak of ontvang."</string>
+ <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Laat die app toe om met telefoniedienste saam te werk om oproepe te maak of ontvang."</string>
<string name="permlab_control_incall_experience" msgid="6436863486094352987">"bied \'n inoproep-gebruikerervaring"</string>
- <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Laat die program toe om \'n inoproep-gebruikerervaring te bied."</string>
+ <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Laat die app toe om \'n inoproep-gebruikerervaring te bied."</string>
<string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"lees netwerkgebruik-geskiedenis"</string>
<string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"Laat die app toe om historiese netwerkgebruik vir spesifieke netwerke en apps te lees."</string>
<string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"bestuur netwerkbeleid"</string>
<string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"Laat die app toe om netwerkbeleide te bestuur en app-spesifieke reëls te definieer."</string>
<string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"verander verrekening van netwerkgebruik"</string>
- <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Laat die program toe om te verander hoe netwerkgebruik teenoor programme gemeet word. Nie vir gebruik deur normale programme nie."</string>
+ <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Laat die app toe om te verander hoe netwerkgebruik teenoor apps gemeet word. Nie vir gebruik deur normale apps nie."</string>
<string name="permlab_accessNotifications" msgid="7130360248191984741">"kry toegang tot kennisgewings"</string>
<string name="permdesc_accessNotifications" msgid="761730149268789668">"Laat die program toe om kennisgewings op te haal, te bestudeer en te verwyder, insluitende die kennisgewings wat deur ander programme geplaas is."</string>
<string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"bind aan \'n kennisgewingluisteraardiens"</string>
@@ -814,11 +814,11 @@
<string name="permlab_setInputCalibration" msgid="932069700285223434">"verander invoertoestelkalibrasie"</string>
<string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Laat die app toe om die kalibrasieparameters van die raakskerm te wysig. Dit behoort nooit vir normale apps nodig te wees nie."</string>
<string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"gaan in by DRM-sertifikate"</string>
- <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Laat \'n program toe om DRM-sertifikate op te stel en te gebruik. Behoort nooit vir normale programme nodig te wees nie."</string>
+ <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Laat \'n app toe om DRM-sertifikate op te stel en te gebruik. Dit behoort nooit vir normale apps nodig te wees nie."</string>
<string name="permlab_handoverStatus" msgid="7620438488137057281">"ontvang Android Straal-oordragstatus"</string>
- <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Laat hierdie program toe om inligting oor huidige Android Straal-oordragte te ontvang."</string>
+ <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Laat hierdie app toe om inligting oor huidige Android Straal-oordragte te ontvang."</string>
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"verwyder DRM-sertifikate"</string>
- <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Laat \'n program toe om DRM-sertifikate te verwyder. Behoort nooit vir gewone programme nodig te wees nie."</string>
+ <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Laat \'n app toe om DRM-sertifikate te verwyder. Dit behoort nooit vir gewone apps nodig te wees nie."</string>
<string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"bind aan \'n diensverskaffer-boodskapdiens"</string>
<string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Dit laat die houer toe om aan die top-koppelvlak van \'n diensverskaffer-boodskapdiens te bind. Behoort nooit vir gewone programme nodig te wees nie."</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"verbind aan diensverskafferdienste"</string>
@@ -1106,7 +1106,7 @@
<string name="permlab_setAlarm" msgid="1158001610254173567">"stel \'n wekker"</string>
<string name="permdesc_setAlarm" msgid="2185033720060109640">"Laat die app toe om \'n alarm in \'n geïnstalleerde wekkerapp te stel. Sommige wekkerapps werk dalk nie met hierdie funksie nie."</string>
<string name="permlab_addVoicemail" msgid="4770245808840814471">"voeg stemboodskap by"</string>
- <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Laat die program toe om boodskappe by te voeg by jou stempos-inkassie."</string>
+ <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Laat die app toe om boodskappe by te voeg by jou stempos-inkassie."</string>
<string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> het van jou knipbord af geplak"</string>
<string name="more_item_label" msgid="7419249600215749115">"Meer"</string>
<string name="prepend_shortcut_label" msgid="1743716737502867951">"Kieslys+"</string>
@@ -1237,7 +1237,7 @@
<string name="low_internal_storage_view_text" msgid="8172166728369697835">"Sommige stelselfunksies werk moontlik nie"</string>
<string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Nie genoeg berging vir die stelsel nie. Maak seker jy het 250 MB spasie beskikbaar en herbegin."</string>
<string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> loop tans"</string>
- <string name="app_running_notification_text" msgid="5120815883400228566">"Tik vir meer inligting of om die program te stop."</string>
+ <string name="app_running_notification_text" msgid="5120815883400228566">"Tik vir meer inligting of om die app te stop."</string>
<string name="ok" msgid="2646370155170753815">"OK"</string>
<string name="cancel" msgid="6908697720451760115">"Kanselleer"</string>
<string name="yes" msgid="9069828999585032361">"OK"</string>
@@ -1279,7 +1279,7 @@
<string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"Vang prent vas met %1$s"</string>
<string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Vang prent vas"</string>
<string name="alwaysUse" msgid="3153558199076112903">"Gebruik hierdie aksie by verstek."</string>
- <string name="use_a_different_app" msgid="4987790276170972776">"Gebruik \'n ander program"</string>
+ <string name="use_a_different_app" msgid="4987790276170972776">"Gebruik \'n ander app"</string>
<string name="clearDefaultHintMsg" msgid="1325866337702524936">"Vee die verstek instelling uit in Stelselinstellings > Programme > Afgelaai."</string>
<string name="chooseActivity" msgid="8563390197659779956">"Kies \'n handeling"</string>
<string name="chooseUsbActivity" msgid="2096269989990986612">"Kies \'n app vir die USB-toestel"</string>
@@ -1303,7 +1303,7 @@
<string name="report" msgid="2149194372340349521">"Verslag"</string>
<string name="wait" msgid="7765985809494033348">"Wag"</string>
<string name="webpage_unresponsive" msgid="7850879412195273433">"Die bladsy reageer nie meer nie.\n\nWil jy dit toemaak?"</string>
- <string name="launch_warning_title" msgid="6725456009564953595">"Program herlei"</string>
+ <string name="launch_warning_title" msgid="6725456009564953595">"App is herlei"</string>
<string name="launch_warning_replace" msgid="3073392976283203402">"<xliff:g id="APP_NAME">%1$s</xliff:g> loop nou."</string>
<string name="launch_warning_original" msgid="3332206576800169626">"<xliff:g id="APP_NAME">%1$s</xliff:g> is oorspronklik laat loop."</string>
<string name="screen_compat_mode_scale" msgid="8627359598437527726">"Skaal"</string>
@@ -1314,7 +1314,7 @@
<string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> is gebou vir \'n onversoenbare weergawe van die Android-bedryfstelsel en kan dalk op \'n onverwagte manier reageer. \'n Opgedateerde weergawe van die program is dalk beskikbaar."</string>
<string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Wys altyd"</string>
<string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Kyk vir opdatering"</string>
- <string name="smv_application" msgid="3775183542777792638">"Die program <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) het sy selfopgelegde StrictMode-beleid oortree."</string>
+ <string name="smv_application" msgid="3775183542777792638">"Die app <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) het sy selfopgelegde StrictMode-beleid oortree."</string>
<string name="smv_process" msgid="1398801497130695446">"Die proses <xliff:g id="PROCESS">%1$s</xliff:g> het die selfopgelegde StrictMode-beleid geskend."</string>
<string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Foon dateer tans op …"</string>
<string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"Tablet dateer tans oop …"</string>
@@ -1397,7 +1397,7 @@
<string name="decline" msgid="6490507610282145874">"Weier"</string>
<string name="select_character" msgid="3352797107930786979">"Voeg karakter in"</string>
<string name="sms_control_title" msgid="4748684259903148341">"Stuur SMS-boodskappe"</string>
- <string name="sms_control_message" msgid="6574313876316388239">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> stuur \'n groot aantal SMS-boodskappe. Wil jy hierdie program toelaat om voort te gaan om boodskappe te stuur?"</string>
+ <string name="sms_control_message" msgid="6574313876316388239">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> stuur \'n groot aantal SMS-boodskappe. Wil jy hierdie app toelaat om voort te gaan om boodskappe te stuur?"</string>
<string name="sms_control_yes" msgid="4858845109269524622">"Laat toe"</string>
<string name="sms_control_no" msgid="4845717880040355570">"Weier"</string>
<string name="sms_short_code_confirm_message" msgid="1385416688897538724">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wil \'n boodskap na <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> stuur."</string>
@@ -1417,8 +1417,8 @@
<string name="sim_restart_button" msgid="8481803851341190038">"Herbegin"</string>
<string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Aktiveer mobiele diens"</string>
<string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Laai die diensverskafferprogram af om jou nuwe SIM te aktiveer"</string>
- <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Laai die <xliff:g id="APP_NAME">%1$s</xliff:g>-program af om jou nuwe SIM te aktiveer"</string>
- <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Laai program af"</string>
+ <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Laai die <xliff:g id="APP_NAME">%1$s</xliff:g>-app af om jou nuwe SIM te aktiveer"</string>
+ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Laai app af"</string>
<string name="carrier_app_notification_title" msgid="5815477368072060250">"Nuwe SIM is ingesit"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"Tik om dit op te stel"</string>
<string name="time_picker_dialog_title" msgid="9053376764985220821">"Stel tyd"</string>
@@ -1533,13 +1533,13 @@
<string name="permlab_route_media_output" msgid="8048124531439513118">"roeteer media-uitvoer"</string>
<string name="permdesc_route_media_output" msgid="1759683269387729675">"Laat \'n app toe om media-uitvoere na ander eksterne toestelle te roeteer."</string>
<string name="permlab_readInstallSessions" msgid="7279049337895583621">"lees installeersessies"</string>
- <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Laat \'n program toe om installasiesessies te lees. Dit laat dit toe om besonderhede van aktiewe pakketinstallasies te sien."</string>
+ <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Laat \'n app toe om installasiesessies te lees. Dit laat dit toe om besonderhede van aktiewe pakketinstallasies te sien."</string>
<string name="permlab_requestInstallPackages" msgid="7600020863445351154">"versoek installeerpakkette"</string>
- <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Laat \'n program toe om te versoek dat pakkette geïnstalleer word."</string>
+ <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Laat \'n app toe om te versoek dat pakkette geïnstalleer word."</string>
<string name="permlab_requestDeletePackages" msgid="2541172829260106795">"versoek uitvee van pakkette"</string>
- <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Laat \'n program toe om te versoek dat pakkette uitgevee word."</string>
+ <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Laat \'n app toe om te versoek dat pakkette uitgevee word."</string>
<string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"vra om batteryoptimerings te ignoreer"</string>
- <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Laat \'n program toe om toestemming te vra om batteryoptimerings vir daardie program ignoreer."</string>
+ <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Laat \'n app toe om toestemming te vra om batteryoptimerings vir daardie app te ignoreer."</string>
<string name="permlab_queryAllPackages" msgid="2928450604653281650">"navraag oor alle pakkette"</string>
<string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Laat \'n program toe om alle geïnstalleerde pakette te sien."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Klop twee keer vir zoembeheer"</string>
@@ -1561,7 +1561,7 @@
<string name="permission_request_notification_title" msgid="1810025922441048273">"Toestemming versoek"</string>
<string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"Toestemming versoek\nvir rekening <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
<string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"Toestemming versoek deur <xliff:g id="APP">%1$s</xliff:g>\nvir rekening <xliff:g id="ACCOUNT">%2$s</xliff:g>"</string>
- <string name="forward_intent_to_owner" msgid="4620359037192871015">"Jy gebruik hierdie program buite jou werkprofiel"</string>
+ <string name="forward_intent_to_owner" msgid="4620359037192871015">"Jy gebruik hierdie app buite jou werkprofiel"</string>
<string name="forward_intent_to_work" msgid="3620262405636021151">"Jy gebruik tans hierdie app in jou werkprofiel"</string>
<string name="input_method_binding_label" msgid="1166731601721983656">"Invoermetode"</string>
<string name="sync_binding_label" msgid="469249309424662147">"Sinkroniseer"</string>
@@ -2068,9 +2068,9 @@
<string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Hierdie app versoek tans bykomende toestemmings, maar toestemmings kan nie in ’n stromingsessie verleen word nie. Verleen eers die toestemming op jou Android TV-toestel."</string>
<string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Hierdie app versoek tans bykomende toestemmings, maar toestemmings kan nie in ’n stromingsessie verleen word nie. Verleen eers die toestemming op jou tablet."</string>
<string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Hierdie app versoek tans bykomende toestemmings, maar toestemmings kan nie in ’n stromingsessie verleen word nie. Verleen eers die toestemming op jou foon."</string>
- <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Hierdie program versoek tans bykomende sekuriteit. Probeer eerder op jou Android TV-toestel."</string>
- <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Hierdie program versoek tans bykomende sekuriteit. Probeer eerder op jou tablet."</string>
- <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Hierdie program versoek tans bykomende sekuriteit. Probeer eerder op jou foon."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Hierdie app versoek tans bykomende sekuriteit. Probeer eerder op jou Android TV-toestel."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Hierdie app versoek tans bykomende sekuriteit. Probeer eerder op jou tablet."</string>
+ <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Hierdie app versoek tans bykomende sekuriteit. Probeer eerder op jou foon."</string>
<string name="app_streaming_blocked_message_for_settings_dialog" product="tv" msgid="820334666354451145">"Jy kan nie op jou <xliff:g id="DEVICE">%1$s</xliff:g> toegang hiertoe kry nie. Probeer eerder op jou Android TV-toestel."</string>
<string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Jy kan nie op jou <xliff:g id="DEVICE">%1$s</xliff:g> toegang hiertoe kry nie. Probeer eerder op jou tablet."</string>
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Jy kan nie op jou <xliff:g id="DEVICE">%1$s</xliff:g> toegang hiertoe kry nie. Probeer eerder op jou foon."</string>
@@ -2157,7 +2157,7 @@
<string name="popup_window_default_title" msgid="6907717596694826919">"Opspringvenster"</string>
<string name="slice_more_content" msgid="3377367737876888459">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
<string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"Programweergawe is afgegradeer, of is nie met hierdie kortpad versoenbaar nie"</string>
- <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Kon nie die kortpad teruglaai nie omdat die program nie rugsteun en teruglaai steun nie"</string>
+ <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Kon nie die kortpad teruglaai nie omdat die app nie rugsteun en teruglaai steun nie"</string>
<string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Kon nie teruglaai nie omdat programondertekening nie ooreenstem nie"</string>
<string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Kon nie kortpad teruglaai nie"</string>
<string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Kortpad is gedeaktiveer"</string>
@@ -2403,8 +2403,8 @@
<string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> is vertaal."</string>
<string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Boodskap is vertaal uit <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> in <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
<string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Agtergrondaktiwiteit"</string>
- <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"’n Program maak tans die battery pap"</string>
- <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"’n Program is nog aktief"</string>
+ <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"’n App maak tans die battery pap"</string>
+ <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"’n App is nog aktief"</string>
<string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> loop tans op die agtergrond. Tik om batterygebruik te bestuur."</string>
<string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> kan batterylewe beïnvloed. Tik om aktiewe programme na te gaan."</string>
<string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Gaan aktiewe programme na"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index baa54bb..a212808 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1158,38 +1158,22 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"in <xliff:g id="COUNT">%d</xliff:g>h"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"in <xliff:g id="COUNT">%d</xliff:g>d"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"in <xliff:g id="COUNT">%d</xliff:g>y"</string>
- <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
- <skip />
- <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
- <skip />
- <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
- <skip />
- <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
- <skip />
- <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
- <skip />
- <!-- no translation found for duration_hours_medium (1465359726485910115) -->
- <skip />
- <!-- no translation found for duration_days_medium (5994225628248661388) -->
- <skip />
- <!-- no translation found for duration_years_medium (734023884353592526) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
- <skip />
- <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
- <skip />
- <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
- <skip />
- <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
- <skip />
- <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
- <skip />
- <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
- <skip />
- <!-- no translation found for duration_years_medium_past (893797065424596243) -->
- <skip />
+ <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"<xliff:g id="COUNT">%d</xliff:g>m ago"</string>
+ <string name="duration_hours_shortest_past" msgid="2098397414186628489">"<xliff:g id="COUNT">%d</xliff:g>h ago"</string>
+ <string name="duration_days_shortest_past" msgid="1832006037955897625">"<xliff:g id="COUNT">%d</xliff:g>d ago"</string>
+ <string name="duration_years_shortest_past" msgid="6168256514200469291">"<xliff:g id="COUNT">%d</xliff:g>y ago"</string>
+ <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g>min"</string>
+ <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g>hr"</string>
+ <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g>d"</string>
+ <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g>yr"</string>
+ <string name="duration_minutes_medium_future" msgid="2750894988731934402">"in <xliff:g id="COUNT">%d</xliff:g>min"</string>
+ <string name="duration_hours_medium_future" msgid="6050833881463849764">"in <xliff:g id="COUNT">%d</xliff:g>hr"</string>
+ <string name="duration_days_medium_future" msgid="1700821545602729963">"in <xliff:g id="COUNT">%d</xliff:g>d"</string>
+ <string name="duration_years_medium_future" msgid="3281018940397120166">"in <xliff:g id="COUNT">%d</xliff:g>yr"</string>
+ <string name="duration_minutes_medium_past" msgid="7400424340181947714">"<xliff:g id="COUNT">%d</xliff:g>min ago"</string>
+ <string name="duration_hours_medium_past" msgid="6709441336035202617">"<xliff:g id="COUNT">%d</xliff:g>hr ago"</string>
+ <string name="duration_days_medium_past" msgid="5748156261134344532">"<xliff:g id="COUNT">%d</xliff:g>d ago"</string>
+ <string name="duration_years_medium_past" msgid="893797065424596243">"<xliff:g id="COUNT">%d</xliff:g>yr ago"</string>
<string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# minute ago}other{# minutes ago}}"</string>
<string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# hour ago}other{# hours ago}}"</string>
<string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# day ago}other{# days ago}}"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 07fa8bf..3d7c91c 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1158,38 +1158,22 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"<xliff:g id="COUNT">%d</xliff:g> 時間後"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"<xliff:g id="COUNT">%d</xliff:g> 日後"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"<xliff:g id="COUNT">%d</xliff:g> 年後"</string>
- <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
- <skip />
- <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
- <skip />
- <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
- <skip />
- <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
- <skip />
- <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
- <skip />
- <!-- no translation found for duration_hours_medium (1465359726485910115) -->
- <skip />
- <!-- no translation found for duration_days_medium (5994225628248661388) -->
- <skip />
- <!-- no translation found for duration_years_medium (734023884353592526) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
- <skip />
- <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
- <skip />
- <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
- <skip />
- <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
- <skip />
- <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
- <skip />
- <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
- <skip />
- <!-- no translation found for duration_years_medium_past (893797065424596243) -->
- <skip />
+ <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"<xliff:g id="COUNT">%d</xliff:g> 分前"</string>
+ <string name="duration_hours_shortest_past" msgid="2098397414186628489">"<xliff:g id="COUNT">%d</xliff:g> 時間前"</string>
+ <string name="duration_days_shortest_past" msgid="1832006037955897625">"<xliff:g id="COUNT">%d</xliff:g> 日前"</string>
+ <string name="duration_years_shortest_past" msgid="6168256514200469291">"<xliff:g id="COUNT">%d</xliff:g> 年前"</string>
+ <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g> 分"</string>
+ <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g> 時間"</string>
+ <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> 日"</string>
+ <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> 年"</string>
+ <string name="duration_minutes_medium_future" msgid="2750894988731934402">"あと <xliff:g id="COUNT">%d</xliff:g> 分"</string>
+ <string name="duration_hours_medium_future" msgid="6050833881463849764">"あと <xliff:g id="COUNT">%d</xliff:g> 時間"</string>
+ <string name="duration_days_medium_future" msgid="1700821545602729963">"あと <xliff:g id="COUNT">%d</xliff:g> 日"</string>
+ <string name="duration_years_medium_future" msgid="3281018940397120166">"あと <xliff:g id="COUNT">%d</xliff:g> 年"</string>
+ <string name="duration_minutes_medium_past" msgid="7400424340181947714">"<xliff:g id="COUNT">%d</xliff:g> 分前"</string>
+ <string name="duration_hours_medium_past" msgid="6709441336035202617">"<xliff:g id="COUNT">%d</xliff:g> 時間前"</string>
+ <string name="duration_days_medium_past" msgid="5748156261134344532">"<xliff:g id="COUNT">%d</xliff:g> 日前"</string>
+ <string name="duration_years_medium_past" msgid="893797065424596243">"<xliff:g id="COUNT">%d</xliff:g> 年前"</string>
<string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# 分前}other{# 分前}}"</string>
<string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# 時間前}other{# 時間前}}"</string>
<string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# 日前}other{# 日前}}"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 3849690..49b4bfc 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1158,38 +1158,22 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"<xliff:g id="COUNT">%d</xliff:g> сағ кейін"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"<xliff:g id="COUNT">%d</xliff:g> күннен кейін"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"<xliff:g id="COUNT">%d</xliff:g> жылдан кейін"</string>
- <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
- <skip />
- <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
- <skip />
- <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
- <skip />
- <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
- <skip />
- <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
- <skip />
- <!-- no translation found for duration_hours_medium (1465359726485910115) -->
- <skip />
- <!-- no translation found for duration_days_medium (5994225628248661388) -->
- <skip />
- <!-- no translation found for duration_years_medium (734023884353592526) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
- <skip />
- <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
- <skip />
- <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
- <skip />
- <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
- <skip />
- <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
- <skip />
- <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
- <skip />
- <!-- no translation found for duration_years_medium_past (893797065424596243) -->
- <skip />
+ <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"<xliff:g id="COUNT">%d</xliff:g> мин бұрын"</string>
+ <string name="duration_hours_shortest_past" msgid="2098397414186628489">"<xliff:g id="COUNT">%d</xliff:g> сағ бұрын"</string>
+ <string name="duration_days_shortest_past" msgid="1832006037955897625">"<xliff:g id="COUNT">%d</xliff:g> күн бұрын"</string>
+ <string name="duration_years_shortest_past" msgid="6168256514200469291">"<xliff:g id="COUNT">%d</xliff:g> жыл бұрын"</string>
+ <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g> мин"</string>
+ <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g> сағ"</string>
+ <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> күн"</string>
+ <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> жыл"</string>
+ <string name="duration_minutes_medium_future" msgid="2750894988731934402">"<xliff:g id="COUNT">%d</xliff:g> минуттан кейін"</string>
+ <string name="duration_hours_medium_future" msgid="6050833881463849764">"<xliff:g id="COUNT">%d</xliff:g> сағаттан кейін"</string>
+ <string name="duration_days_medium_future" msgid="1700821545602729963">"<xliff:g id="COUNT">%d</xliff:g> күннен кейін"</string>
+ <string name="duration_years_medium_future" msgid="3281018940397120166">"<xliff:g id="COUNT">%d</xliff:g> жылдан кейін"</string>
+ <string name="duration_minutes_medium_past" msgid="7400424340181947714">"<xliff:g id="COUNT">%d</xliff:g> мин бұрын"</string>
+ <string name="duration_hours_medium_past" msgid="6709441336035202617">"<xliff:g id="COUNT">%d</xliff:g> сағ бұрын"</string>
+ <string name="duration_days_medium_past" msgid="5748156261134344532">"<xliff:g id="COUNT">%d</xliff:g> күн бұрын"</string>
+ <string name="duration_years_medium_past" msgid="893797065424596243">"<xliff:g id="COUNT">%d</xliff:g> жыл бұрын"</string>
<string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# минут бұрын}other{# минут бұрын}}"</string>
<string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# сағат бұрын}other{# сағат бұрын}}"</string>
<string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# күн бұрын}other{# күн бұрын}}"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 85352bc..ad62f42 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -561,13 +561,13 @@
<string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"ಟ್ಯಾಬ್ಲೆಟ್ನ ಇನ್ಫ್ರಾರೆಡ್ ಸಂವಾಹಕವನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"ನಿಮ್ಮ Android TV ಸಾಧನದ ಇನ್ಫ್ರಾರೆಡ್ ಟ್ರಾನ್ಸ್ಮೀಟರ್ ಅನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"ಫೋನ್ನ ಇನ್ಫ್ರಾರೆಡ್ ಸಂವಾಹಕವನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <string name="permlab_setWallpaper" msgid="6959514622698794511">"ವಾಲ್ಪೇಪರ್ ಹೊಂದಿಸಿ"</string>
+ <string name="permlab_setWallpaper" msgid="6959514622698794511">"ವಾಲ್ಪೇಪರ್ ಸೆಟ್ ಮಾಡಿ"</string>
<string name="permdesc_setWallpaper" msgid="2973996714129021397">"ಸಿಸ್ಟಂ ವಾಲ್ಪೇಪರ್ ಹೊಂದಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_accessHiddenProfile" msgid="8607094418491556823">"ಮರೆಮಾಡಲಾದ ಪ್ರೊಫೈಲ್ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಿ"</string>
<string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"ಮರೆಮಾಡಲಾದ ಪ್ರೊಫೈಲ್ಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_setWallpaperHints" msgid="1153485176642032714">"ನಿಮ್ಮ ವಾಲ್ಪೇಪರ್ ಗಾತ್ರವನ್ನು ಸರಿಹೊಂದಿಸಿ"</string>
<string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"ಸಿಸ್ಟಂ ವಾಲ್ಪೇಪರ್ ಗಾತ್ರದ ಸುಳಿವುಗಳನ್ನು ಹೊಂದಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <string name="permlab_setTimeZone" msgid="7922618798611542432">"ಸಮಯದ ವಲಯವನ್ನು ಹೊಂದಿಸಿ"</string>
+ <string name="permlab_setTimeZone" msgid="7922618798611542432">"ಸಮಯದ ವಲಯವನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
<string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"ಟ್ಯಾಬ್ಲೆಟ್ನ ಸಮಯ ವಲಯವನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"ನಿಮ್ಮ Android TV ಸಾಧನದ ಸಮಯವಲಯವನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"ಫೋನ್ನ ಸಮಯ ವಲಯವನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
@@ -837,7 +837,7 @@
<string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"ಬಳಕೆದಾರರ ಕ್ರಿಯೆಯಿಲ್ಲದೆ ಈ ಹಿಂದೆ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್ ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲು ಹೋಲ್ಡರ್ ಅನ್ನು ಅನುಮತಿಸುತ್ತದೆ"</string>
<string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"ಇತರ ಆ್ಯಪ್ಗಳ ಮಾಲೀಕತ್ವದ E2EE ಸಂಪರ್ಕ ಕೀಗಳ ಪರಿಶೀಲನೆಯ ಸ್ಥಿತಿಗಳನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಿ"</string>
<string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"ಇತರ ಆ್ಯಪ್ಗಳ ಮಾಲೀಕತ್ವದ E2EE ಸಂಪರ್ಕ ಕೀಗಳ ಪರಿಶೀಲನೆಯ ಸ್ಥಿತಿಗಳನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
- <string name="policylab_limitPassword" msgid="4851829918814422199">"ಪಾಸ್ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
+ <string name="policylab_limitPassword" msgid="4851829918814422199">"ಪಾಸ್ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
<string name="policydesc_limitPassword" msgid="4105491021115793793">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ನಲ್ಲಿನ ಪಾಸ್ವರ್ಡ್ಗಳು ಮತ್ತು ಪಿನ್ಗಳ ಅನುಮತಿಸಲಾದ ಅಕ್ಷರಗಳ ಪ್ರಮಾಣವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
<string name="policylab_watchLogin" msgid="7599669460083719504">"ಪರದೆಯ ಅನ್ಲಾಕ್ ಪ್ರಯತ್ನಗಳನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"ಸ್ಕ್ರೀನ್ ಅನ್ಲಾಕ್ ಮಾಡುವಾಗ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿದ ಪಾಸ್ವರ್ಡ್ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ, ಮತ್ತು ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು ಟೈಪ್ ಮಾಡಿದ್ದರೆ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಲಾಕ್ ಮಾಡಿ ಅಥವಾ ಟ್ಯಾಬ್ಲೆಟ್ನ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
@@ -863,11 +863,11 @@
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2293713284515865200">"ಎಚ್ಚರಿಕೆ ಇಲ್ಲದೆ ಈ Android TV ಸಾಧನದಲ್ಲಿನ ಈ ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕುತ್ತದೆ."</string>
<string name="policydesc_wipeData_secondaryUser" product="automotive" msgid="4658832487305780879">"ಎಚ್ಚರಿಕೆಯಿಲ್ಲದೆ ಈ ಇನ್ಫೋಟೈನ್ಮೆಂಟ್ ಸಿಸ್ಟಂನಲ್ಲಿ ಈ ಪ್ರೊಫೈಲ್ನ ಡೇಟಾವನ್ನು ಅಳಿಸಿ."</string>
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="2788325512167208654">"ಯಾವುದೇ ಸೂಚನೆ ಇಲ್ಲದೆ ಈ ಫೋನ್ನಲ್ಲಿ ಈ ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಅಳಿಸಿ."</string>
- <string name="policylab_setGlobalProxy" msgid="215332221188670221">"ಸಾಧನವನ್ನು ಜಾಗತಿಕ ಪ್ರಾಕ್ಸಿಗೆ ಹೊಂದಿಸಿ"</string>
- <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"ನೀತಿಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿದಾಗ ಬಳಸಬೇಕಾದ ಸಾಧನದ ಜಾಗತಿಕ ಪ್ರಾಕ್ಸಿಯನ್ನು ಹೊಂದಿಸಿ. ಸಾಧನದ ಮಾಲೀಕರು ಮಾತ್ರ ಜಾಗತಿಕ ಪ್ರಾಕ್ಸಿಯನ್ನು ಹೊಂದಿಸಬಹುದಾಗಿರುತ್ತದೆ."</string>
- <string name="policylab_expirePassword" msgid="6015404400532459169">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಪಾಸ್ವರ್ಡ್ ಮುಕ್ತಾಯವನ್ನು ಹೊಂದಿಸಿ"</string>
+ <string name="policylab_setGlobalProxy" msgid="215332221188670221">"ಸಾಧನವನ್ನು ಜಾಗತಿಕ ಪ್ರಾಕ್ಸಿಗೆ ಸೆಟ್ ಮಾಡಿ"</string>
+ <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"ನೀತಿಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿದಾಗ ಬಳಸಬೇಕಾದ ಸಾಧನದ ಜಾಗತಿಕ ಪ್ರಾಕ್ಸಿಯನ್ನು ಸೆಟ್ ಮಾಡಿ. ಸಾಧನದ ಮಾಲೀಕರು ಮಾತ್ರ ಜಾಗತಿಕ ಪ್ರಾಕ್ಸಿಯನ್ನು ಹೊಂದಿಸಬಹುದಾಗಿರುತ್ತದೆ."</string>
+ <string name="policylab_expirePassword" msgid="6015404400532459169">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಪಾಸ್ವರ್ಡ್ ಮುಕ್ತಾಯವನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
<string name="policydesc_expirePassword" msgid="9136524319325960675">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಪಾಸ್ವರ್ಡ್, ಪಿನ್, ಅಥವಾ ನಮೂನೆಯನ್ನು ಹೆಚ್ಚು ಪದೆ ಪದೇ ಬದಲಾಯಿಸಬೇಕಾಗಿರುತ್ತದೆ ಎಂಬುದನ್ನು ಬದಲಾಯಿಸಿ."</string>
- <string name="policylab_encryptedStorage" msgid="9012936958126670110">"ಸಂಗ್ರಹಣೆ ಎನ್ಕ್ರಿಪ್ಶನ್ ಹೊಂದಿಸಿ"</string>
+ <string name="policylab_encryptedStorage" msgid="9012936958126670110">"ಸಂಗ್ರಹಣೆ ಎನ್ಕ್ರಿಪ್ಶನ್ ಸೆಟ್ ಮಾಡಿ"</string>
<string name="policydesc_encryptedStorage" msgid="1102516950740375617">"ಸಂಗ್ರಹಿಸಿರುವ ಆ್ಯಪ್ ಡೇಟಾವನ್ನು ಎನ್ಕ್ರಿಪ್ಟ್ ಮಾಡಬೇಕಾದ ಅಗತ್ಯವಿದೆ."</string>
<string name="policylab_disableCamera" msgid="5749486347810162018">"ಕ್ಯಾಮರಾಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="policydesc_disableCamera" msgid="3204405908799676104">"ಎಲ್ಲಾ ಸಾಧನ ಕ್ಯಾಮರಾಗಳ ಬಳಕೆಯನ್ನು ತಡೆಯಿರಿ."</string>
@@ -1103,7 +1103,7 @@
<string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"ಈ ಪುಟದಲ್ಲಿಯೇ ಇರಿ"</string>
<string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nನೀವು ಈ ಪುಟದಿಂದಾಚೆಗೆ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಲು ಖಚಿತವಾಗಿ ಬಯಸುವಿರಾ?"</string>
<string name="autofill_window_title" msgid="4379134104008111961">"<xliff:g id="SERVICENAME">%1$s</xliff:g> ಸಹಾಯದಿಂದ ಸ್ವಯಂ-ಭರ್ತಿ"</string>
- <string name="permlab_setAlarm" msgid="1158001610254173567">"ಅಲಾರಮ್ ಹೊಂದಿಸಿ"</string>
+ <string name="permlab_setAlarm" msgid="1158001610254173567">"ಅಲಾರಮ್ ಸೆಟ್ ಮಾಡಿ"</string>
<string name="permdesc_setAlarm" msgid="2185033720060109640">"ಸ್ಥಾಪಿಸಲಾದ ಅಲಾರಮ್ ಗಡಿಯಾರ ಅಪ್ಲಿಕೇಶನ್ನಲ್ಲಿ ಅಲಾರಮ್ ಹೊಂದಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಕೆಲವು ಅಲಾರಮ್ ಗಡಿಯಾರ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಈ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸದಿರಬಹುದು."</string>
<string name="permlab_addVoicemail" msgid="4770245808840814471">"ಧ್ವನಿಮೇಲ್ ಸೇರಿಸಿ"</string>
<string name="permdesc_addVoicemail" msgid="5470312139820074324">"ನಿಮ್ಮ ದ್ವನಿಮೇಲ್ ಇನ್ಬಾಕ್ಸ್ಗೆ ಸಂದೇಶಗಳನ್ನು ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
@@ -1158,38 +1158,22 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"<xliff:g id="COUNT">%d</xliff:g>ಗಂ ಯಲ್ಲಿ"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"<xliff:g id="COUNT">%d</xliff:g>ದಿ ದಲ್ಲಿ"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"<xliff:g id="COUNT">%d</xliff:g>ವ ದಲ್ಲಿ"</string>
- <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
- <skip />
- <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
- <skip />
- <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
- <skip />
- <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
- <skip />
- <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
- <skip />
- <!-- no translation found for duration_hours_medium (1465359726485910115) -->
- <skip />
- <!-- no translation found for duration_days_medium (5994225628248661388) -->
- <skip />
- <!-- no translation found for duration_years_medium (734023884353592526) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
- <skip />
- <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
- <skip />
- <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
- <skip />
- <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
- <skip />
- <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
- <skip />
- <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
- <skip />
- <!-- no translation found for duration_years_medium_past (893797065424596243) -->
- <skip />
+ <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"<xliff:g id="COUNT">%d</xliff:g>ನಿಮಿಷದ ಹಿಂದೆ"</string>
+ <string name="duration_hours_shortest_past" msgid="2098397414186628489">"<xliff:g id="COUNT">%d</xliff:g>ಗಂಟೆ ಹಿಂದೆ"</string>
+ <string name="duration_days_shortest_past" msgid="1832006037955897625">"<xliff:g id="COUNT">%d</xliff:g>ದಿನಗಳ ಹಿಂದೆ"</string>
+ <string name="duration_years_shortest_past" msgid="6168256514200469291">"<xliff:g id="COUNT">%d</xliff:g>ವರ್ಷದ ಹಿಂದೆ"</string>
+ <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g>ನಿಮಿಷ"</string>
+ <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g>ಗಂಟೆ"</string>
+ <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g>ದಿನ"</string>
+ <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g>ವರ್ಷ"</string>
+ <string name="duration_minutes_medium_future" msgid="2750894988731934402">"<xliff:g id="COUNT">%d</xliff:g>ನಿಮಿಷದಲ್ಲಿ"</string>
+ <string name="duration_hours_medium_future" msgid="6050833881463849764">"<xliff:g id="COUNT">%d</xliff:g>ಗಂಟೆಯಲ್ಲಿ"</string>
+ <string name="duration_days_medium_future" msgid="1700821545602729963">"<xliff:g id="COUNT">%d</xliff:g>ದಿನದಲ್ಲಿ"</string>
+ <string name="duration_years_medium_future" msgid="3281018940397120166">"<xliff:g id="COUNT">%d</xliff:g>ವರ್ಷದಲ್ಲಿ"</string>
+ <string name="duration_minutes_medium_past" msgid="7400424340181947714">"<xliff:g id="COUNT">%d</xliff:g>ನಿಮಿಷದ ಹಿಂದೆ"</string>
+ <string name="duration_hours_medium_past" msgid="6709441336035202617">"<xliff:g id="COUNT">%d</xliff:g>ಗಂಟೆ ಹಿಂದೆ"</string>
+ <string name="duration_days_medium_past" msgid="5748156261134344532">"<xliff:g id="COUNT">%d</xliff:g>ದಿನಗಳ ಹಿಂದೆ"</string>
+ <string name="duration_years_medium_past" msgid="893797065424596243">"<xliff:g id="COUNT">%d</xliff:g>ವರ್ಷದ ಹಿಂದೆ"</string>
<string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# ನಿಮಿಷದ ಹಿಂದೆ}one{# ನಿಮಿಷಗಳ ಹಿಂದೆ}other{# ನಿಮಿಷಗಳ ಹಿಂದೆ}}"</string>
<string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# ಗಂಟೆಯ ಹಿಂದೆ}one{# ಗಂಟೆಗಳ ಹಿಂದೆ}other{# ಗಂಟೆಗಳ ಹಿಂದೆ}}"</string>
<string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# ದಿನದ ಹಿಂದೆ}one{# ದಿನಗಳ ಹಿಂದೆ}other{# ದಿನಗಳ ಹಿಂದೆ}}"</string>
@@ -1421,7 +1405,7 @@
<string name="install_carrier_app_notification_button" msgid="6257740533102594290">"ಆ್ಯಪ್ ಡೌನ್ಲೋಡ್ ಮಾಡಿ"</string>
<string name="carrier_app_notification_title" msgid="5815477368072060250">"ಹೊಸ ಸಿಮ್ ಸೇರಿಸಲಾಗಿದೆ"</string>
<string name="carrier_app_notification_text" msgid="6567057546341958637">"ಇದನ್ನು ಸ್ಥಾಪಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="time_picker_dialog_title" msgid="9053376764985220821">"ಸಮಯವನ್ನು ಹೊಂದಿಸಿ"</string>
+ <string name="time_picker_dialog_title" msgid="9053376764985220821">"ಸಮಯವನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
<string name="date_picker_dialog_title" msgid="5030520449243071926">"ದಿನಾಂಕವನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
<string name="date_time_set" msgid="4603445265164486816">"ಹೊಂದಿಸು"</string>
<string name="date_time_done" msgid="8363155889402873463">"ಆಯಿತು"</string>
@@ -1622,7 +1606,7 @@
<string name="time_picker_increment_hour_button" msgid="3063572723197178242">"ಗಂಟೆಯನ್ನು ಹೆಚ್ಚಿಸಿ"</string>
<string name="time_picker_decrement_hour_button" msgid="584101766855054412">"ಗಂಟೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</string>
<string name="time_picker_increment_set_pm_button" msgid="5889149366900376419">"PM ಹೊಂದಿಸು"</string>
- <string name="time_picker_decrement_set_am_button" msgid="1422608001541064087">"AM ಹೊಂದಿಸಿ"</string>
+ <string name="time_picker_decrement_set_am_button" msgid="1422608001541064087">"AM ಸೆಟ್ ಮಾಡಿ"</string>
<string name="date_picker_increment_month_button" msgid="3447263316096060309">"ತಿಂಗಳನ್ನು ಹೆಚ್ಚಿಸಿ"</string>
<string name="date_picker_decrement_month_button" msgid="6531888937036883014">"ತಿಂಗಳು ಕಡಿಮೆಮಾಡಿ"</string>
<string name="date_picker_increment_day_button" msgid="4349336637188534259">"ದಿನವನ್ನು ಹೆಚ್ಚಿಸಿ"</string>
@@ -2108,7 +2092,7 @@
<string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ"</string>
<string name="time_picker_hour_label" msgid="4208590187662336864">"ಗಂಟೆ"</string>
<string name="time_picker_minute_label" msgid="8307452311269824553">"ನಿಮಿಷ"</string>
- <string name="time_picker_header_text" msgid="9073802285051516688">"ಸಮಯವನ್ನು ಹೊಂದಿಸಿ"</string>
+ <string name="time_picker_header_text" msgid="9073802285051516688">"ಸಮಯವನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
<string name="time_picker_input_error" msgid="8386271930742451034">"ಮಾನ್ಯವಾದ ಸಮಯವನ್ನು ನಮೂದಿಸಿ"</string>
<string name="time_picker_prompt_label" msgid="303588544656363889">"ಸಮಯ ಟೈಪ್ ಮಾಡಿ"</string>
<string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"ಸಮಯವನ್ನು ನಮೂದಿಸಲು ಪಠ್ಯದ ನಮೂನೆಗೆ ಬದಲಿಸಿ."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 1fea243..21925f8 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1158,38 +1158,22 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"dalam <xliff:g id="COUNT">%d</xliff:g>j"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"dalam <xliff:g id="COUNT">%d</xliff:g>h"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"dalam <xliff:g id="COUNT">%d</xliff:g>t"</string>
- <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
- <skip />
- <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
- <skip />
- <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
- <skip />
- <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
- <skip />
- <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
- <skip />
- <!-- no translation found for duration_hours_medium (1465359726485910115) -->
- <skip />
- <!-- no translation found for duration_days_medium (5994225628248661388) -->
- <skip />
- <!-- no translation found for duration_years_medium (734023884353592526) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
- <skip />
- <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
- <skip />
- <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
- <skip />
- <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
- <skip />
- <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
- <skip />
- <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
- <skip />
- <!-- no translation found for duration_years_medium_past (893797065424596243) -->
- <skip />
+ <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"<xliff:g id="COUNT">%d</xliff:g>m yang lalu"</string>
+ <string name="duration_hours_shortest_past" msgid="2098397414186628489">"<xliff:g id="COUNT">%d</xliff:g>j yang lalu"</string>
+ <string name="duration_days_shortest_past" msgid="1832006037955897625">"<xliff:g id="COUNT">%d</xliff:g>h yang lalu"</string>
+ <string name="duration_years_shortest_past" msgid="6168256514200469291">"<xliff:g id="COUNT">%d</xliff:g>t yang lalu"</string>
+ <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g>min"</string>
+ <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g>jam"</string>
+ <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g>h"</string>
+ <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g>thn"</string>
+ <string name="duration_minutes_medium_future" msgid="2750894988731934402">"selepas <xliff:g id="COUNT">%d</xliff:g>minit"</string>
+ <string name="duration_hours_medium_future" msgid="6050833881463849764">"selepas <xliff:g id="COUNT">%d</xliff:g>jam"</string>
+ <string name="duration_days_medium_future" msgid="1700821545602729963">"dalam <xliff:g id="COUNT">%d</xliff:g>h"</string>
+ <string name="duration_years_medium_future" msgid="3281018940397120166">"selepas <xliff:g id="COUNT">%d</xliff:g>thn"</string>
+ <string name="duration_minutes_medium_past" msgid="7400424340181947714">"<xliff:g id="COUNT">%d</xliff:g>minit yang lalu"</string>
+ <string name="duration_hours_medium_past" msgid="6709441336035202617">"<xliff:g id="COUNT">%d</xliff:g>jam yang lalu"</string>
+ <string name="duration_days_medium_past" msgid="5748156261134344532">"<xliff:g id="COUNT">%d</xliff:g>h yang lalu"</string>
+ <string name="duration_years_medium_past" msgid="893797065424596243">"<xliff:g id="COUNT">%d</xliff:g>thn yang lalu"</string>
<string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# minit yang lalu}other{# minit yang lalu}}"</string>
<string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# jam yang lalu}other{# jam yang lalu}}"</string>
<string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# hari yang lalu}other{# hari yang lalu}}"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 8e943db..5ff383d 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1159,38 +1159,22 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"em <xliff:g id="COUNT">%d</xliff:g>h"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"em <xliff:g id="COUNT">%d</xliff:g> dias"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"em <xliff:g id="COUNT">%d</xliff:g>a"</string>
- <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
- <skip />
- <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
- <skip />
- <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
- <skip />
- <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
- <skip />
- <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
- <skip />
- <!-- no translation found for duration_hours_medium (1465359726485910115) -->
- <skip />
- <!-- no translation found for duration_days_medium (5994225628248661388) -->
- <skip />
- <!-- no translation found for duration_years_medium (734023884353592526) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
- <skip />
- <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
- <skip />
- <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
- <skip />
- <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
- <skip />
- <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
- <skip />
- <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
- <skip />
- <!-- no translation found for duration_years_medium_past (893797065424596243) -->
- <skip />
+ <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"há <xliff:g id="COUNT">%d</xliff:g>min"</string>
+ <string name="duration_hours_shortest_past" msgid="2098397414186628489">"há <xliff:g id="COUNT">%d</xliff:g>h"</string>
+ <string name="duration_days_shortest_past" msgid="1832006037955897625">"há <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_shortest_past" msgid="6168256514200469291">"há <xliff:g id="COUNT">%d</xliff:g> a"</string>
+ <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g>min"</string>
+ <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g>h"</string>
+ <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> a"</string>
+ <string name="duration_minutes_medium_future" msgid="2750894988731934402">"em <xliff:g id="COUNT">%d</xliff:g>min"</string>
+ <string name="duration_hours_medium_future" msgid="6050833881463849764">"em <xliff:g id="COUNT">%d</xliff:g>h"</string>
+ <string name="duration_days_medium_future" msgid="1700821545602729963">"em <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium_future" msgid="3281018940397120166">"em <xliff:g id="COUNT">%d</xliff:g> a"</string>
+ <string name="duration_minutes_medium_past" msgid="7400424340181947714">"há <xliff:g id="COUNT">%d</xliff:g>min"</string>
+ <string name="duration_hours_medium_past" msgid="6709441336035202617">"há <xliff:g id="COUNT">%d</xliff:g>h"</string>
+ <string name="duration_days_medium_past" msgid="5748156261134344532">"há <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium_past" msgid="893797065424596243">"há <xliff:g id="COUNT">%d</xliff:g> a"</string>
<string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# minuto atrás}one{# minuto atrás}many{# minutos atrás}other{# minutos atrás}}"</string>
<string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# hora atrás}one{# hora atrás}many{# horas atrás}other{# horas atrás}}"</string>
<string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# dia atrás}one{# dia atrás}many{# dias atrás}other{# dias atrás}}"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index b5ee460..38a071a 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1159,38 +1159,22 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"em <xliff:g id="COUNT">%d</xliff:g> h"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"em <xliff:g id="COUNT">%d</xliff:g> d"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"em <xliff:g id="COUNT">%d</xliff:g> a"</string>
- <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
- <skip />
- <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
- <skip />
- <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
- <skip />
- <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
- <skip />
- <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
- <skip />
- <!-- no translation found for duration_hours_medium (1465359726485910115) -->
- <skip />
- <!-- no translation found for duration_days_medium (5994225628248661388) -->
- <skip />
- <!-- no translation found for duration_years_medium (734023884353592526) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
- <skip />
- <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
- <skip />
- <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
- <skip />
- <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
- <skip />
- <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
- <skip />
- <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
- <skip />
- <!-- no translation found for duration_years_medium_past (893797065424596243) -->
- <skip />
+ <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"há <xliff:g id="COUNT">%d</xliff:g> min"</string>
+ <string name="duration_hours_shortest_past" msgid="2098397414186628489">"há <xliff:g id="COUNT">%d</xliff:g> h"</string>
+ <string name="duration_days_shortest_past" msgid="1832006037955897625">"há <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_shortest_past" msgid="6168256514200469291">"há <xliff:g id="COUNT">%d</xliff:g> ano(s)"</string>
+ <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g> min"</string>
+ <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g> h"</string>
+ <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> ano(s)"</string>
+ <string name="duration_minutes_medium_future" msgid="2750894988731934402">"dentro de <xliff:g id="COUNT">%d</xliff:g> min"</string>
+ <string name="duration_hours_medium_future" msgid="6050833881463849764">"dentro de <xliff:g id="COUNT">%d</xliff:g> h"</string>
+ <string name="duration_days_medium_future" msgid="1700821545602729963">"dentro de <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium_future" msgid="3281018940397120166">"dentro de <xliff:g id="COUNT">%d</xliff:g> ano(s)"</string>
+ <string name="duration_minutes_medium_past" msgid="7400424340181947714">"há <xliff:g id="COUNT">%d</xliff:g> min"</string>
+ <string name="duration_hours_medium_past" msgid="6709441336035202617">"há <xliff:g id="COUNT">%d</xliff:g> h"</string>
+ <string name="duration_days_medium_past" msgid="5748156261134344532">"há <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium_past" msgid="893797065424596243">"há <xliff:g id="COUNT">%d</xliff:g> ano(s)"</string>
<string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Há # minuto}many{Há # minutos}other{Há # minutos}}"</string>
<string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{há # hora}many{há # horas}other{há # horas}}"</string>
<string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Há # dia}many{Há # dias}other{Há # dias}}"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 8e943db..5ff383d 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1159,38 +1159,22 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"em <xliff:g id="COUNT">%d</xliff:g>h"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"em <xliff:g id="COUNT">%d</xliff:g> dias"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"em <xliff:g id="COUNT">%d</xliff:g>a"</string>
- <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
- <skip />
- <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
- <skip />
- <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
- <skip />
- <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
- <skip />
- <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
- <skip />
- <!-- no translation found for duration_hours_medium (1465359726485910115) -->
- <skip />
- <!-- no translation found for duration_days_medium (5994225628248661388) -->
- <skip />
- <!-- no translation found for duration_years_medium (734023884353592526) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
- <skip />
- <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
- <skip />
- <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
- <skip />
- <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
- <skip />
- <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
- <skip />
- <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
- <skip />
- <!-- no translation found for duration_years_medium_past (893797065424596243) -->
- <skip />
+ <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"há <xliff:g id="COUNT">%d</xliff:g>min"</string>
+ <string name="duration_hours_shortest_past" msgid="2098397414186628489">"há <xliff:g id="COUNT">%d</xliff:g>h"</string>
+ <string name="duration_days_shortest_past" msgid="1832006037955897625">"há <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_shortest_past" msgid="6168256514200469291">"há <xliff:g id="COUNT">%d</xliff:g> a"</string>
+ <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g>min"</string>
+ <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g>h"</string>
+ <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> a"</string>
+ <string name="duration_minutes_medium_future" msgid="2750894988731934402">"em <xliff:g id="COUNT">%d</xliff:g>min"</string>
+ <string name="duration_hours_medium_future" msgid="6050833881463849764">"em <xliff:g id="COUNT">%d</xliff:g>h"</string>
+ <string name="duration_days_medium_future" msgid="1700821545602729963">"em <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium_future" msgid="3281018940397120166">"em <xliff:g id="COUNT">%d</xliff:g> a"</string>
+ <string name="duration_minutes_medium_past" msgid="7400424340181947714">"há <xliff:g id="COUNT">%d</xliff:g>min"</string>
+ <string name="duration_hours_medium_past" msgid="6709441336035202617">"há <xliff:g id="COUNT">%d</xliff:g>h"</string>
+ <string name="duration_days_medium_past" msgid="5748156261134344532">"há <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium_past" msgid="893797065424596243">"há <xliff:g id="COUNT">%d</xliff:g> a"</string>
<string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# minuto atrás}one{# minuto atrás}many{# minutos atrás}other{# minutos atrás}}"</string>
<string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# hora atrás}one{# hora atrás}many{# horas atrás}other{# horas atrás}}"</string>
<string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# dia atrás}one{# dia atrás}many{# dias atrás}other{# dias atrás}}"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index dc61496..e7e96f5 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1160,38 +1160,22 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"čez <xliff:g id="COUNT">%d</xliff:g> h"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"čez <xliff:g id="COUNT">%d</xliff:g> d"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"čez <xliff:g id="COUNT">%d</xliff:g> l"</string>
- <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
- <skip />
- <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
- <skip />
- <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
- <skip />
- <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
- <skip />
- <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
- <skip />
- <!-- no translation found for duration_hours_medium (1465359726485910115) -->
- <skip />
- <!-- no translation found for duration_days_medium (5994225628248661388) -->
- <skip />
- <!-- no translation found for duration_years_medium (734023884353592526) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
- <skip />
- <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
- <skip />
- <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
- <skip />
- <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
- <skip />
- <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
- <skip />
- <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
- <skip />
- <!-- no translation found for duration_years_medium_past (893797065424596243) -->
- <skip />
+ <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"pred <xliff:g id="COUNT">%d</xliff:g> min"</string>
+ <string name="duration_hours_shortest_past" msgid="2098397414186628489">"pred <xliff:g id="COUNT">%d</xliff:g> h"</string>
+ <string name="duration_days_shortest_past" msgid="1832006037955897625">"pred <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_shortest_past" msgid="6168256514200469291">"pred <xliff:g id="COUNT">%d</xliff:g> l"</string>
+ <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g> min"</string>
+ <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g> h"</string>
+ <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> l"</string>
+ <string name="duration_minutes_medium_future" msgid="2750894988731934402">"čez <xliff:g id="COUNT">%d</xliff:g> min"</string>
+ <string name="duration_hours_medium_future" msgid="6050833881463849764">"čez <xliff:g id="COUNT">%d</xliff:g> h"</string>
+ <string name="duration_days_medium_future" msgid="1700821545602729963">"čez <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium_future" msgid="3281018940397120166">"čez <xliff:g id="COUNT">%d</xliff:g> l"</string>
+ <string name="duration_minutes_medium_past" msgid="7400424340181947714">"pred <xliff:g id="COUNT">%d</xliff:g> min"</string>
+ <string name="duration_hours_medium_past" msgid="6709441336035202617">"pred <xliff:g id="COUNT">%d</xliff:g> h"</string>
+ <string name="duration_days_medium_past" msgid="5748156261134344532">"pred <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium_past" msgid="893797065424596243">"pred <xliff:g id="COUNT">%d</xliff:g> l"</string>
<string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Pred # minuto}one{Pred # minuto}two{Pred # minutama}few{Pred # minutami}other{Pred # minutami}}"</string>
<string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{Pred # uro}one{Pred # uro}two{Pred # urama}few{Pred # urami}other{Pred # urami}}"</string>
<string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Pred # dnevom}one{Pred # dnevom}two{Pred # dnevoma}few{Pred # dnevi}other{Pred # dnevi}}"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index a7207ac..4b22b7d 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1158,38 +1158,22 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"om <xliff:g id="COUNT">%d</xliff:g> tim"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"om <xliff:g id="COUNT">%d</xliff:g> d"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"om <xliff:g id="COUNT">%d</xliff:g> år"</string>
- <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
- <skip />
- <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
- <skip />
- <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
- <skip />
- <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
- <skip />
- <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
- <skip />
- <!-- no translation found for duration_hours_medium (1465359726485910115) -->
- <skip />
- <!-- no translation found for duration_days_medium (5994225628248661388) -->
- <skip />
- <!-- no translation found for duration_years_medium (734023884353592526) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
- <skip />
- <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
- <skip />
- <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
- <skip />
- <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
- <skip />
- <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
- <skip />
- <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
- <skip />
- <!-- no translation found for duration_years_medium_past (893797065424596243) -->
- <skip />
+ <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"för <xliff:g id="COUNT">%d</xliff:g> m sedan"</string>
+ <string name="duration_hours_shortest_past" msgid="2098397414186628489">"för <xliff:g id="COUNT">%d</xliff:g> h sedan"</string>
+ <string name="duration_days_shortest_past" msgid="1832006037955897625">"för <xliff:g id="COUNT">%d</xliff:g> d sedan"</string>
+ <string name="duration_years_shortest_past" msgid="6168256514200469291">"för <xliff:g id="COUNT">%d</xliff:g> år sedan"</string>
+ <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g> min"</string>
+ <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g> h"</string>
+ <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> år"</string>
+ <string name="duration_minutes_medium_future" msgid="2750894988731934402">"om <xliff:g id="COUNT">%d</xliff:g> min"</string>
+ <string name="duration_hours_medium_future" msgid="6050833881463849764">"om <xliff:g id="COUNT">%d</xliff:g> h"</string>
+ <string name="duration_days_medium_future" msgid="1700821545602729963">"om <xliff:g id="COUNT">%d</xliff:g> d"</string>
+ <string name="duration_years_medium_future" msgid="3281018940397120166">"om <xliff:g id="COUNT">%d</xliff:g> år"</string>
+ <string name="duration_minutes_medium_past" msgid="7400424340181947714">"för <xliff:g id="COUNT">%d</xliff:g> min sedan"</string>
+ <string name="duration_hours_medium_past" msgid="6709441336035202617">"för <xliff:g id="COUNT">%d</xliff:g> h sedan"</string>
+ <string name="duration_days_medium_past" msgid="5748156261134344532">"för <xliff:g id="COUNT">%d</xliff:g> d sedan"</string>
+ <string name="duration_years_medium_past" msgid="893797065424596243">"för <xliff:g id="COUNT">%d</xliff:g> år sedan"</string>
<string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{För # minut sedan}other{För # minuter sedan}}"</string>
<string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{För # timme sedan}other{För # timmar sedan}}"</string>
<string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{För # dag sedan}other{För # dagar sedan}}"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 28f06ab..89e2e68 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1158,38 +1158,22 @@
<string name="duration_hours_shortest_future" msgid="2979276794547981674">"<xliff:g id="COUNT">%d</xliff:g> soatdan keyin"</string>
<string name="duration_days_shortest_future" msgid="3392722163935571543">"<xliff:g id="COUNT">%d</xliff:g> kundan keyin"</string>
<string name="duration_years_shortest_future" msgid="5537464088352970388">"<xliff:g id="COUNT">%d</xliff:g> yildan keyin"</string>
- <!-- no translation found for duration_minutes_shortest_past (1740022450020492407) -->
- <skip />
- <!-- no translation found for duration_hours_shortest_past (2098397414186628489) -->
- <skip />
- <!-- no translation found for duration_days_shortest_past (1832006037955897625) -->
- <skip />
- <!-- no translation found for duration_years_shortest_past (6168256514200469291) -->
- <skip />
- <!-- no translation found for duration_minutes_medium (5891933490342643944) -->
- <skip />
- <!-- no translation found for duration_hours_medium (1465359726485910115) -->
- <skip />
- <!-- no translation found for duration_days_medium (5994225628248661388) -->
- <skip />
- <!-- no translation found for duration_years_medium (734023884353592526) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_future (2750894988731934402) -->
- <skip />
- <!-- no translation found for duration_hours_medium_future (6050833881463849764) -->
- <skip />
- <!-- no translation found for duration_days_medium_future (1700821545602729963) -->
- <skip />
- <!-- no translation found for duration_years_medium_future (3281018940397120166) -->
- <skip />
- <!-- no translation found for duration_minutes_medium_past (7400424340181947714) -->
- <skip />
- <!-- no translation found for duration_hours_medium_past (6709441336035202617) -->
- <skip />
- <!-- no translation found for duration_days_medium_past (5748156261134344532) -->
- <skip />
- <!-- no translation found for duration_years_medium_past (893797065424596243) -->
- <skip />
+ <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"<xliff:g id="COUNT">%d</xliff:g> daq oldin"</string>
+ <string name="duration_hours_shortest_past" msgid="2098397414186628489">"<xliff:g id="COUNT">%d</xliff:g> soat oldin"</string>
+ <string name="duration_days_shortest_past" msgid="1832006037955897625">"<xliff:g id="COUNT">%d</xliff:g> kun oldin"</string>
+ <string name="duration_years_shortest_past" msgid="6168256514200469291">"<xliff:g id="COUNT">%d</xliff:g> yil oldin"</string>
+ <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g>daq"</string>
+ <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g>st"</string>
+ <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> k"</string>
+ <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g>yil"</string>
+ <string name="duration_minutes_medium_future" msgid="2750894988731934402">"<xliff:g id="COUNT">%d</xliff:g> daqiqadan keyin"</string>
+ <string name="duration_hours_medium_future" msgid="6050833881463849764">"<xliff:g id="COUNT">%d</xliff:g> soatdan keyin"</string>
+ <string name="duration_days_medium_future" msgid="1700821545602729963">"<xliff:g id="COUNT">%d</xliff:g> kundan keyin"</string>
+ <string name="duration_years_medium_future" msgid="3281018940397120166">"<xliff:g id="COUNT">%d</xliff:g> yildan keyin"</string>
+ <string name="duration_minutes_medium_past" msgid="7400424340181947714">"<xliff:g id="COUNT">%d</xliff:g> daqiqa oldin"</string>
+ <string name="duration_hours_medium_past" msgid="6709441336035202617">"<xliff:g id="COUNT">%d</xliff:g> soat oldin"</string>
+ <string name="duration_days_medium_past" msgid="5748156261134344532">"<xliff:g id="COUNT">%d</xliff:g> kun oldin"</string>
+ <string name="duration_years_medium_past" msgid="893797065424596243">"<xliff:g id="COUNT">%d</xliff:g> yil oldin"</string>
<string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{# daqiqa oldin}other{# daqiqa oldin}}"</string>
<string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{# soat oldin}other{# soat oldin}}"</string>
<string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{# kun oldin}other{# kun oldin}}"</string>
diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml
index 7ac1759..60aec53 100644
--- a/core/res/res/values-watch/themes_device_defaults.xml
+++ b/core/res/res/values-watch/themes_device_defaults.xml
@@ -226,52 +226,6 @@
<!-- Toolbar attributes -->
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</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="materialColorInverseOnSurface">@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="materialColorSecondaryFixed">@color/system_secondary_fixed</item>
- <item name="materialColorInverseSurface">@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="materialColorPrimaryFixed">@color/system_primary_fixed</item>
- <item name="materialColorOnSecondary">@color/system_on_secondary_dark</item>
- <item name="materialColorOnTertiary">@color/system_on_tertiary_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="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="materialColorSecondary">@color/system_secondary_dark</item>
- <item name="materialColorTertiary">@color/system_tertiary_dark</item>
- <item name="materialColorError">@color/system_error_dark</item>
</style>
<!-- DeviceDefault theme for a window that should look like the Settings app. -->
@@ -376,8 +330,8 @@
<item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
</style>
- <!-- DeviceDefault theme for a window that will be displayed either full-screen on smaller
- screens (small, normal) or as a dialog on larger screens (large, xlarge). -->
+ <!-- DeviceDefault theme for a window that will be displayed either full-screen on smaller
+ screens (small, normal) or as a dialog on larger screens (large, xlarge). -->
<style name="Theme.DeviceDefault.DialogWhenLarge" parent="Theme.Material.DialogWhenLarge">
<!-- Color palette Dark -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 238aca5..792974d 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1217,178 +1217,6 @@
a value of 'true' will not override any 'false' value in its parent chain nor will
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 -->
- <attr name="materialColorErrorContainer" format="color"/>
- <!-- @hide -->
- <attr name="materialColorInverseOnSurface" format="color"/>
- <!-- @hide -->
- <attr name="materialColorInversePrimary" format="color"/>
- <!-- @hide -->
- <attr name="materialColorInverseSurface" format="color"/>
- <!-- @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 -->
- <attr name="materialColorOnSecondary" format="color"/>
- <!-- @hide -->
- <attr name="materialColorOnSecondaryContainer" format="color"/>
- <!-- @hide -->
- <attr name="materialColorOnSurface" format="color"/>
- <!-- @hide -->
- <attr name="materialColorOnSurfaceVariant" format="color"/>
- <!-- @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 -->
- <attr name="materialColorSecondary" format="color"/>
- <!-- @hide -->
- <attr name="materialColorSecondaryContainer" format="color"/>
- <!-- @hide -->
- <attr name="materialColorShadow" format="color"/>
- <!-- @hide -->
- <attr name="materialColorSurface" format="color"/>
- <!-- @hide -->
- <attr name="materialColorSurfaceBright" format="color"/>
- <!-- @hide -->
- <attr name="materialColorSurfaceContainer" format="color"/>
- <!-- @hide -->
- <attr name="materialColorSurfaceContainerHigh" format="color"/>
- <!-- @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 -->
- <attr name="materialColorTertiary" format="color"/>
- <!-- @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"/>
- <!-- @hide -->
- <attr name="materialColorOnTertiaryFixedVariant" format="color"/>
- <!-- @hide -->
- <attr name="materialColorPrimaryFixed" format="color"/>
- <!-- @hide -->
- <attr name="materialColorPrimaryFixedDim" format="color"/>
- <!-- @hide -->
- <attr name="materialColorSecondaryFixed" format="color"/>
- <!-- @hide -->
- <attr name="materialColorSecondaryFixedDim" format="color"/>
- <!-- @hide -->
- <attr name="materialColorTertiaryFixed" format="color"/>
- <!-- @hide -->
- <attr name="materialColorTertiaryFixedDim" format="color"/>
- <!-- @hide -->
- <attr name="customColorBrandA" format="color"/>
- <!-- @hide -->
- <attr name="customColorBrandB" format="color"/>
- <!-- @hide -->
- <attr name="customColorBrandC" format="color"/>
- <!-- @hide -->
- <attr name="customColorBrandD" format="color"/>
- <!-- @hide -->
- <attr name="customColorClockHour" format="color"/>
- <!-- @hide -->
- <attr name="customColorClockMinute" format="color"/>
- <!-- @hide -->
- <attr name="customColorClockSecond" format="color"/>
- <!-- @hide -->
- <attr name="customColorOnShadeActive" format="color"/>
- <!-- @hide -->
- <attr name="customColorOnShadeActiveVariant" 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"/>
-
</declare-styleable>
<!-- **************************************************************** -->
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index bb76b9f..196da29 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -496,4 +496,8 @@
not connected state. -->
<bool name="config_satellite_allow_check_message_in_not_connected">false</bool>
<java-symbol type="bool" name="config_satellite_allow_check_message_in_not_connected" />
+
+ <!-- Whether to allow TN scanning during satellite session. -->
+ <bool name="config_satellite_allow_tn_scanning_during_satellite_session">true</bool>
+ <java-symbol type="bool" name="config_satellite_allow_tn_scanning_during_satellite_session" />
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 28de553..71532bb 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -5445,133 +5445,51 @@
<java-symbol name="customColorWeatherTemp" type="color"/>
<java-symbol name="customColorWidgetBackground" type="color"/>
- <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="system_widget_background_light" type="color"/>
- <java-symbol name="system_clock_hour_light" type="color"/>
- <java-symbol name="system_clock_minute_light" type="color"/>
- <java-symbol name="system_clock_second_light" type="color"/>
- <java-symbol name="system_theme_app_light" type="color"/>
- <java-symbol name="system_on_theme_app_light" type="color"/>
- <java-symbol name="system_theme_app_ring_light" type="color"/>
- <java-symbol name="system_theme_notif_light" type="color"/>
<java-symbol name="system_brand_a_light" type="color"/>
<java-symbol name="system_brand_b_light" type="color"/>
<java-symbol name="system_brand_c_light" type="color"/>
<java-symbol name="system_brand_d_light" type="color"/>
- <java-symbol name="system_under_surface_light" type="color"/>
- <java-symbol name="system_shade_active_light" type="color"/>
+ <java-symbol name="system_clock_hour_light" type="color"/>
+ <java-symbol name="system_clock_minute_light" type="color"/>
+ <java-symbol name="system_clock_second_light" type="color"/>
<java-symbol name="system_on_shade_active_light" type="color"/>
<java-symbol name="system_on_shade_active_variant_light" type="color"/>
- <java-symbol name="system_shade_inactive_light" type="color"/>
<java-symbol name="system_on_shade_inactive_light" type="color"/>
<java-symbol name="system_on_shade_inactive_variant_light" type="color"/>
- <java-symbol name="system_shade_disabled_light" type="color"/>
+ <java-symbol name="system_on_theme_app_light" type="color"/>
<java-symbol name="system_overview_background_light" type="color"/>
- <java-symbol name="system_widget_background_dark" type="color"/>
- <java-symbol name="system_clock_hour_dark" type="color"/>
- <java-symbol name="system_clock_minute_dark" type="color"/>
- <java-symbol name="system_clock_second_dark" type="color"/>
- <java-symbol name="system_theme_app_dark" type="color"/>
- <java-symbol name="system_on_theme_app_dark" type="color"/>
- <java-symbol name="system_theme_app_ring_dark" type="color"/>
- <java-symbol name="system_theme_notif_dark" type="color"/>
+ <java-symbol name="system_shade_active_light" type="color"/>
+ <java-symbol name="system_shade_disabled_light" type="color"/>
+ <java-symbol name="system_shade_inactive_light" type="color"/>
+ <java-symbol name="system_theme_app_light" type="color"/>
+ <java-symbol name="system_theme_app_ring_light" type="color"/>
+ <java-symbol name="system_theme_notif_light" type="color"/>
+ <java-symbol name="system_under_surface_light" type="color"/>
+ <java-symbol name="system_weather_temp_light" type="color"/>
+ <java-symbol name="system_widget_background_light" type="color"/>
+
<java-symbol name="system_brand_a_dark" type="color"/>
<java-symbol name="system_brand_b_dark" type="color"/>
<java-symbol name="system_brand_c_dark" type="color"/>
<java-symbol name="system_brand_d_dark" type="color"/>
- <java-symbol name="system_under_surface_dark" type="color"/>
- <java-symbol name="system_shade_active_dark" type="color"/>
+ <java-symbol name="system_clock_hour_dark" type="color"/>
+ <java-symbol name="system_clock_minute_dark" type="color"/>
+ <java-symbol name="system_clock_second_dark" type="color"/>
<java-symbol name="system_on_shade_active_dark" type="color"/>
<java-symbol name="system_on_shade_active_variant_dark" type="color"/>
- <java-symbol name="system_shade_inactive_dark" type="color"/>
<java-symbol name="system_on_shade_inactive_dark" type="color"/>
<java-symbol name="system_on_shade_inactive_variant_dark" type="color"/>
- <java-symbol name="system_shade_disabled_dark" type="color"/>
+ <java-symbol name="system_on_theme_app_dark" type="color"/>
<java-symbol name="system_overview_background_dark" type="color"/>
+ <java-symbol name="system_shade_active_dark" type="color"/>
+ <java-symbol name="system_shade_disabled_dark" type="color"/>
+ <java-symbol name="system_shade_inactive_dark" type="color"/>
+ <java-symbol name="system_theme_app_dark" type="color"/>
+ <java-symbol name="system_theme_app_ring_dark" type="color"/>
+ <java-symbol name="system_theme_notif_dark" type="color"/>
+ <java-symbol name="system_under_surface_dark" type="color"/>
+ <java-symbol name="system_weather_temp_dark" type="color"/>
+ <java-symbol name="system_widget_background_dark" type="color"/>
<java-symbol type="attr" name="actionModeUndoDrawable" />
<java-symbol type="attr" name="actionModeRedoDrawable" />
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index d8346d8..6b3d427 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -131,7 +131,7 @@
<item name="progressBarStyleSmallInverse">@style/Widget.DeviceDefault.ProgressBar.Small.Inverse</item>
<item name="progressBarStyleLargeInverse">@style/Widget.DeviceDefault.ProgressBar.Large.Inverse</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="seekBarStyle">@style/Widget.DeviceDefault.SeekBar</item>
<item name="ratingBarStyle">@style/Widget.DeviceDefault.RatingBar</item>
<item name="ratingBarStyleIndicator">@style/Widget.DeviceDefault.RatingBar.Indicator</item>
@@ -238,91 +238,6 @@
<item name="textColorOnAccent">@color/system_on_primary_dark</item>
<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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault" parent="Theme.DeviceDefaultBase" />
@@ -368,96 +283,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar. This theme
@@ -502,96 +332,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar and
@@ -638,96 +383,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault} that has no title bar and translucent
@@ -773,96 +433,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault theme for dialog windows and activities. This changes the window to be
@@ -916,96 +491,11 @@
<item name="alertDialogTheme">@style/Theme.DeviceDefault.Dialog.Alert</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Dialog} that has a nice minimum width for a
@@ -1050,96 +540,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Dialog} without an action bar -->
@@ -1183,96 +588,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Dialog_NoActionBar} that has a nice minimum width
@@ -1317,96 +637,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -1467,96 +702,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault theme for a window without an action bar that will be displayed either
@@ -1602,96 +752,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault theme for a presentation window on a secondary display. -->
@@ -1735,96 +800,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault theme for panel windows. This removes all extraneous window
@@ -1870,96 +850,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -2004,96 +899,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -2138,96 +948,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault style for input methods, which is used by the
@@ -2272,96 +997,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault style for input methods, which is used by the
@@ -2406,96 +1046,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Material.Dialog.Alert">
@@ -2540,96 +1095,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Theme for the dialog shown when an app crashes or ANRs. -->
@@ -2679,96 +1149,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.Dialog.NoFrame" parent="Theme.Material.Dialog.NoFrame">
@@ -2811,96 +1196,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault} with a light-colored style -->
@@ -2982,7 +1282,7 @@
<item name="progressBarStyleSmallInverse">@style/Widget.DeviceDefault.Light.ProgressBar.Small.Inverse</item>
<item name="progressBarStyleLargeInverse">@style/Widget.DeviceDefault.Light.ProgressBar.Large.Inverse</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="seekBarStyle">@style/Widget.DeviceDefault.Light.SeekBar</item>
<item name="ratingBarStyle">@style/Widget.DeviceDefault.Light.RatingBar</item>
<item name="ratingBarStyleIndicator">@style/Widget.DeviceDefault.Light.RatingBar.Indicator</item>
@@ -3086,91 +1386,6 @@
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
<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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of the DeviceDefault (light) theme that has a solid (opaque) action bar with an
@@ -3215,96 +1430,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar -->
@@ -3348,96 +1478,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar.
@@ -3482,96 +1527,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar
@@ -3618,96 +1578,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light} that has no title bar and translucent
@@ -3753,96 +1628,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault light theme for dialog windows and activities. This changes the window to be
@@ -3894,96 +1684,11 @@
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} that has a nice minimum width for a
@@ -4031,96 +1736,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} without an action bar -->
@@ -4167,96 +1787,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog_NoActionBar} that has a nice minimum
@@ -4304,96 +1839,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -4427,91 +1877,6 @@
<item name="textColorOnAccent">@color/system_on_primary_dark</item>
<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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of Theme.DeviceDefault.Dialog.NoActionBar that has a fixed size. -->
@@ -4545,91 +1910,6 @@
<item name="textColorOnAccent">@color/system_on_primary_dark</item>
<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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault light theme for a window that will be displayed either full-screen on smaller
@@ -4677,96 +1957,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault light theme for a window without an action bar that will be displayed either
@@ -4815,96 +2010,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault light theme for a presentation window on a secondary display. -->
@@ -4951,96 +2061,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault light theme for panel windows. This removes all extraneous window
@@ -5086,96 +2111,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Material.Light.Dialog.Alert">
@@ -5220,96 +2160,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.Dialog.Alert.DayNight" parent="Theme.DeviceDefault.Light.Dialog.Alert" />
@@ -5354,96 +2209,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.Light.Voice" parent="Theme.Material.Light.Voice">
@@ -5486,96 +2256,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- DeviceDefault theme for a window that should look like the Settings app. -->
@@ -5631,90 +2316,6 @@
<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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.SystemUI" parent="Theme.DeviceDefault.Light">
@@ -5745,96 +2346,12 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.SystemUI.Dialog" parent="Theme.DeviceDefault.Light.Dialog">
@@ -5857,96 +2374,12 @@
<item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Settings_Dark} with no action bar -->
@@ -5991,96 +2424,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.Settings.DialogBase" parent="Theme.Material.Light.BaseDialog">
@@ -6114,91 +2462,6 @@
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.Settings.Dialog" parent="Theme.DeviceDefault.Settings.DialogBase">
@@ -6216,7 +2479,7 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- Toolbar attributes -->
@@ -6267,96 +2530,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.Alert">
@@ -6403,96 +2581,11 @@
<item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
<!-- Progress bar attributes -->
- <item name="colorProgressBackgroundNormal">?attr/materialColorOutline</item>
+ <item name="colorProgressBackgroundNormal">@color/materialColorOutline</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
<!-- 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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.Settings.Dialog.NoActionBar" parent="Theme.DeviceDefault.Light.Dialog.NoActionBar" />
@@ -6570,91 +2663,6 @@
<item name="colorAccentPrimary">@color/accent_primary_device_default</item>
<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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="ThemeOverlay.DeviceDefault.Accent.Light">
@@ -6662,91 +2670,6 @@
<item name="colorAccentPrimary">@color/accent_primary_device_default</item>
<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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<!-- Theme overlay that replaces colorAccent with the colorAccent from {@link #Theme_DeviceDefault_DayNight}. -->
@@ -6758,91 +2681,6 @@
<item name="colorAccentPrimary">@color/accent_primary_device_default</item>
<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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.Light.Dialog.Alert.UserSwitchingDialog" parent="Theme.DeviceDefault.NoActionBar.Fullscreen">
@@ -6850,91 +2688,6 @@
<item name="colorBackgroundFloating">@color/background_device_default_light</item>
<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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_light</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</style>
<style name="Theme.DeviceDefault.Notification" parent="@style/Theme.Material.Notification">
@@ -6953,91 +2706,6 @@
<item name="colorAccentPrimary">@color/system_accent1_100</item>
<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="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="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="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="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="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="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="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
- <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_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>
</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/res/res/xml/bookmarks.xml b/core/res/res/xml/bookmarks.xml
index e735784..17860ef 100644
--- a/core/res/res/xml/bookmarks.xml
+++ b/core/res/res/xml/bookmarks.xml
@@ -20,14 +20,10 @@
Typical shortcuts (not necessarily defined here):
'b': Browser
- 'c': Contacts
+ 'p': Contacts
'e': Email
- 'g': GMail
- 'k': Calendar
+ 'c': Calendar
'm': Maps
- 'p': Music
- 's': SMS
- 't': Talk
'u': Calculator
'y': YouTube
-->
@@ -38,7 +34,7 @@
androidprv:modifierState="META" />
<bookmark
category="android.intent.category.APP_CONTACTS"
- androidprv:keycode="KEYCODE_C"
+ androidprv:keycode="KEYCODE_P"
androidprv:modifierState="META" />
<bookmark
category="android.intent.category.APP_EMAIL"
@@ -46,21 +42,13 @@
androidprv:modifierState="META" />
<bookmark
category="android.intent.category.APP_CALENDAR"
- androidprv:keycode="KEYCODE_K"
+ androidprv:keycode="KEYCODE_C"
androidprv:modifierState="META" />
<bookmark
category="android.intent.category.APP_MAPS"
androidprv:keycode="KEYCODE_M"
androidprv:modifierState="META" />
<bookmark
- category="android.intent.category.APP_MUSIC"
- androidprv:keycode="KEYCODE_P"
- androidprv:modifierState="META" />
- <bookmark
- role="android.app.role.SMS"
- androidprv:keycode="KEYCODE_S"
- androidprv:modifierState="META" />
- <bookmark
category="android.intent.category.APP_CALCULATOR"
androidprv:keycode="KEYCODE_U"
androidprv:modifierState="META" />
diff --git a/core/tests/coretests/src/android/app/NotificationManagerTest.java b/core/tests/coretests/src/android/app/NotificationManagerTest.java
new file mode 100644
index 0000000..3213abe
--- /dev/null
+++ b/core/tests/coretests/src/android/app/NotificationManagerTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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 org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.Instant;
+import java.time.InstantSource;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class NotificationManagerTest {
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+ private Context mContext;
+ private NotificationManagerWithMockService mNotificationManager;
+ private final FakeClock mClock = new FakeClock();
+
+ @Before
+ public void setUp() {
+ mContext = ApplicationProvider.getApplicationContext();
+ mNotificationManager = new NotificationManagerWithMockService(mContext, mClock);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+ public void notify_rapidUpdate_isThrottled() throws Exception {
+ Notification n = exampleNotification();
+
+ for (int i = 0; i < 100; i++) {
+ mNotificationManager.notify(1, n);
+ mClock.advanceByMillis(5);
+ }
+
+ verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(any(),
+ any(), any(), anyInt(), any(), anyInt());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+ public void notify_reasonableUpdate_isNotThrottled() throws Exception {
+ Notification n = exampleNotification();
+
+ for (int i = 0; i < 100; i++) {
+ mNotificationManager.notify(1, n);
+ mClock.advanceByMillis(300);
+ }
+
+ verify(mNotificationManager.mBackendService, times(100)).enqueueNotificationWithTag(any(),
+ any(), any(), anyInt(), any(), anyInt());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+ public void notify_rapidAdd_isNotThrottled() throws Exception {
+ Notification n = exampleNotification();
+
+ for (int i = 0; i < 100; i++) {
+ mNotificationManager.notify(i, n);
+ mClock.advanceByMillis(5);
+ }
+
+ verify(mNotificationManager.mBackendService, times(100)).enqueueNotificationWithTag(any(),
+ any(), any(), anyInt(), any(), anyInt());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+ public void notify_rapidAddAndCancel_isNotThrottled() throws Exception {
+ Notification n = exampleNotification();
+
+ for (int i = 0; i < 100; i++) {
+ mNotificationManager.notify(1, n);
+ mNotificationManager.cancel(1);
+ mClock.advanceByMillis(5);
+ }
+
+ verify(mNotificationManager.mBackendService, times(100)).enqueueNotificationWithTag(any(),
+ any(), any(), anyInt(), any(), anyInt());
+ }
+
+ private Notification exampleNotification() {
+ return new Notification.Builder(mContext, "channel")
+ .setSmallIcon(android.R.drawable.star_big_on)
+ .build();
+ }
+
+ private static class NotificationManagerWithMockService extends NotificationManager {
+
+ private final INotificationManager mBackendService;
+
+ NotificationManagerWithMockService(Context context, InstantSource clock) {
+ super(context, clock);
+ mBackendService = mock(INotificationManager.class);
+ }
+
+ @Override
+ public INotificationManager service() {
+ return mBackendService;
+ }
+ }
+
+ private static class FakeClock implements InstantSource {
+
+ private long mNowMillis = 441644400000L;
+
+ @Override
+ public Instant instant() {
+ return Instant.ofEpochMilli(mNowMillis);
+ }
+
+ private void advanceByMillis(long millis) {
+ mNowMillis += millis;
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java b/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java
index 6d2dd53..ff3abae 100644
--- a/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java
+++ b/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java
@@ -33,7 +33,6 @@
import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsEnabled;
import android.util.ArraySet;
import android.util.PackageUtils;
@@ -62,7 +61,6 @@
import java.util.Set;
@Presubmit
-@RequiresFlagsEnabled(android.content.pm.Flags.FLAG_SDK_DEPENDENCY_INSTALLER)
public class ApkLiteParseUtilsTest {
@Rule
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java
index 6dad3b7..13b12fc 100644
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java
@@ -1010,6 +1010,7 @@
mDatabase.beginTransaction();
try {
mDatabase.execSQL("CREATE TABLE t1 (i int, j int);");
+ mDatabase.execSQL("INSERT INTO t1 (i, j) VALUES (2, 20)");
mDatabase.setTransactionSuccessful();
} finally {
mDatabase.endTransaction();
@@ -1017,13 +1018,35 @@
mDatabase.beginTransactionReadOnly();
try (SQLiteRawStatement s = mDatabase.createRawStatement("SELECT * from t1")) {
- s.step();
- s.getColumnText(5); // out-of-range column
+ assertTrue(s.step());
+ s.getColumnText(5); // out-of-range column: the range is [0,2).
fail("JNI exception not thrown");
} catch (SQLiteBindOrColumnIndexOutOfRangeException e) {
// Passing case.
} finally {
mDatabase.endTransaction();
}
+
+ mDatabase.beginTransactionReadOnly();
+ try (SQLiteRawStatement s = mDatabase.createRawStatement("SELECT * from t1")) {
+ // Do not step the statement. The column count will be zero.
+ s.getColumnText(5); // out-of-range column: never stepped.
+ fail("JNI exception not thrown");
+ } catch (SQLiteMisuseException e) {
+ // Passing case.
+ } finally {
+ mDatabase.endTransaction();
+ }
+
+ mDatabase.beginTransactionReadOnly();
+ try (SQLiteRawStatement s = mDatabase.createRawStatement("SELECT * from t1")) {
+ // Do not step the statement. The column count will be zero.
+ s.getColumnText(0); // out-of-range column: never stepped.
+ fail("JNI exception not thrown");
+ } catch (SQLiteMisuseException e) {
+ // Passing case.
+ } finally {
+ mDatabase.endTransaction();
+ }
}
}
diff --git a/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt b/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt
index 18e4fde..4a227d8 100644
--- a/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt
+++ b/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt
@@ -318,11 +318,11 @@
verifyDisplay(actualDisplay2, id = 2, width = 200f, height = 600f, POSITION_RIGHT,
offset = 0f, noOfChildren = 2)
- val actualDisplay3 = actualDisplay2.children[1]
+ val actualDisplay3 = actualDisplay2.children[0]
verifyDisplay(actualDisplay3, id = 3, width = 600f, height = 200f, POSITION_RIGHT,
offset = 10f, noOfChildren = 0)
- val actualDisplay4 = actualDisplay2.children[0]
+ val actualDisplay4 = actualDisplay2.children[1]
verifyDisplay(actualDisplay4, id = 4, width = 200f, height = 600f, POSITION_RIGHT,
offset = 210f, noOfChildren = 0)
}
@@ -402,42 +402,46 @@
@Test
fun rearrange_twoDisplays() {
- val nodes = rearrangeRects(
+ val root = 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))
+ verifyDisplay(root, id = 0, width = 150f, height = 100f, noOfChildren = 1)
+ val node = root.children[0]
+ verifyDisplay(
+ node, id = 1, width = 150f, height = 100f, POSITION_BOTTOM, offset = 50f,
+ noOfChildren = 0)
}
@Test
fun rearrange_reverseOrderOfSeveralDisplays() {
- val nodes = rearrangeRects(
+ val root = 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()
+ verifyDisplay(root, id = 0, width = 150f, height = 100f, noOfChildren = 1)
+ var node = root.children[0]
+ verifyDisplay(
+ node, id = 1, width = 150f, height = 100f, POSITION_LEFT, offset = 0f,
+ noOfChildren = 1)
+ node = node.children[0]
+ verifyDisplay(
+ node, id = 2, width = 150f, height = 100f, POSITION_LEFT, offset = 0f,
+ noOfChildren = 1)
+ node = node.children[0]
+ verifyDisplay(
+ node, id = 3, width = 150f, height = 100f, POSITION_LEFT, offset = 0f,
+ noOfChildren = 0)
}
@Test
fun rearrange_crossWithRootInCenter() {
- val nodes = rearrangeRects(
+ val root = rearrangeRects(
RectF(0f, 0f, 150f, 100f),
RectF(-150f, 0f, 0f, 100f),
RectF(0f, -100f, 150f, 0f),
@@ -445,21 +449,24 @@
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])
+ verifyDisplay(root, id = 0, width = 150f, height = 100f, noOfChildren = 4)
+ verifyDisplay(
+ root.children[0], id = 1, width = 150f, height = 100f, POSITION_LEFT, offset = 0f,
+ noOfChildren = 0)
+ verifyDisplay(
+ root.children[1], id = 2, width = 150f, height = 100f, POSITION_TOP, offset = 0f,
+ noOfChildren = 0)
+ verifyDisplay(
+ root.children[2], id = 3, width = 150f, height = 100f, POSITION_RIGHT, offset = 0f,
+ noOfChildren = 0)
+ verifyDisplay(
+ root.children[3], id = 4, width = 150f, height = 100f, POSITION_BOTTOM, offset = 0f,
+ noOfChildren = 0)
}
@Test
fun rearrange_elbowArrangementDoesNotUseCornerAdjacency1() {
- val nodes = rearrangeRects(
+ val root = rearrangeRects(
// 2
// |
// 0 - 1
@@ -469,20 +476,20 @@
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),
- )
+ verifyDisplay(root, id = 0, width = 100f, height = 100f, noOfChildren = 1)
+ var node = root.children[0]
+ verifyDisplay(
+ node, id = 1, width = 100f, height = 100f, POSITION_RIGHT, offset = 0f,
+ noOfChildren = 1)
+ node = node.children[0]
+ verifyDisplay(
+ node, id = 2, width = 100f, height = 100f, POSITION_TOP,
+ offset = 0f, noOfChildren = 0)
}
@Test
fun rearrange_elbowArrangementDoesNotUseCornerAdjacency2() {
- val nodes = rearrangeRects(
+ val root = rearrangeRects(
// 0
// |
// 1
@@ -495,22 +502,24 @@
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),
- )
+ verifyDisplay(root, id = 0, width = 100f, height = 100f, noOfChildren = 1)
+ var node = root.children[0]
+ verifyDisplay(
+ node, id = 1, width = 100f, height = 100f, POSITION_BOTTOM, offset = 0f,
+ noOfChildren = 1)
+ node = node.children[0]
+ verifyDisplay(
+ node, id = 2, width = 100f, height = 100f, POSITION_BOTTOM, offset = 0f,
+ noOfChildren = 1)
+ node = node.children[0]
+ verifyDisplay(
+ node, id = 3, width = 100f, height = 100f, POSITION_LEFT, offset = 0f,
+ noOfChildren = 0)
}
@Test
fun rearrange_useLargerEdge() {
- val nodes = rearrangeRects(
+ val root = rearrangeRects(
// 444111
// 444111
// 444111
@@ -527,23 +536,24 @@
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() }
+ verifyDisplay(root, id = 0, width = 30f, height = 30f, noOfChildren = 2)
+ verifyDisplay(
+ root.children[0], id = 1, width = 30f, height = 30f, POSITION_TOP,
+ offset = 10f, noOfChildren = 1)
+ verifyDisplay(
+ root.children[0].children[0], id = 4, width = 30f, height = 30f, POSITION_LEFT,
+ offset = 0f, noOfChildren = 0)
+ verifyDisplay(
+ root.children[1], id = 2, width = 30f, height = 30f, POSITION_RIGHT,
+ offset = 0f, noOfChildren = 1)
+ verifyDisplay(
+ root.children[1].children[0], id = 3, width = 30f, height = 30f, POSITION_BOTTOM,
+ offset = -10f, noOfChildren = 0)
}
@Test
fun rearrange_closeGaps() {
- val nodes = rearrangeRects(
+ val root = rearrangeRects(
// 000
// 000 111
// 000 111
@@ -558,16 +568,14 @@
// TOP/BOTTOM attach
)
- assertPositioning(
- nodes,
- // In the case of corner adjacency, we prefer a left/right attachment.
- Pair(POSITION_RIGHT, 10f),
- Pair(POSITION_BOTTOM, 30f),
- )
-
- assertThat(nodes[0].children).containsExactly(nodes[1])
- assertThat(nodes[1].children).containsExactly(nodes[2])
- assertThat(nodes[2].children).isEmpty()
+ verifyDisplay(root, id = 0, width = 30f, height = 30f, noOfChildren = 1)
+ verifyDisplay(
+ root.children[0], id = 1, width = 30f, height = 30f, POSITION_RIGHT, offset = 10f,
+ noOfChildren = 1)
+ // In the case of corner adjacency, we prefer a left/right attachment.
+ verifyDisplay(
+ root.children[0].children[0], id = 2, width = 29.5f, height = 30f, POSITION_BOTTOM,
+ offset = 30f, noOfChildren = 0)
}
@Test
@@ -612,8 +620,10 @@
/**
* 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.
+ *
+ * Returns the root node.
*/
- private fun rearrangeRects(vararg pos: RectF): List<DisplayTopology.TreeNode> {
+ private fun rearrangeRects(vararg pos: RectF): 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.
@@ -631,7 +641,7 @@
PointF(pos[it].left, pos[it].top)
})
- return nodes
+ return nodes[0]
}
private fun verifyDisplay(display: DisplayTopology.TreeNode, id: Int, width: Float,
@@ -644,11 +654,4 @@
assertThat(display.offset).isEqualTo(offset)
assertThat(display.children).hasSize(noOfChildren)
}
-
- 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/TestLooperManagerTest.java b/core/tests/coretests/src/android/os/TestLooperManagerTest.java
deleted file mode 100644
index 4d64a3a..0000000
--- a/core/tests/coretests/src/android/os/TestLooperManagerTest.java
+++ /dev/null
@@ -1,91 +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.os;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.platform.test.ravenwood.RavenwoodRule;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-public class TestLooperManagerTest {
- private static final String TAG = "TestLooperManagerTest";
-
- @Rule
- public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
- .setProvideMainThread(true)
- .build();
-
- @Test
- public void testMainThread() throws Exception {
- doTest(Looper.getMainLooper());
- }
-
- @Test
- public void testCustomThread() throws Exception {
- final HandlerThread thread = new HandlerThread(TAG);
- thread.start();
- doTest(thread.getLooper());
- }
-
- private void doTest(Looper looper) throws Exception {
- final TestLooperManager tlm =
- InstrumentationRegistry.getInstrumentation().acquireLooperManager(looper);
-
- final Handler handler = new Handler(looper);
- final CountDownLatch latch = new CountDownLatch(1);
-
- assertFalse(tlm.hasMessages(handler, null, 42));
-
- handler.sendEmptyMessage(42);
- handler.post(() -> {
- latch.countDown();
- });
- assertTrue(tlm.hasMessages(handler, null, 42));
- assertFalse(latch.await(100, TimeUnit.MILLISECONDS));
-
- final Message first = tlm.next();
- assertEquals(42, first.what);
- assertNull(first.callback);
- tlm.execute(first);
- assertFalse(tlm.hasMessages(handler, null, 42));
- assertFalse(latch.await(100, TimeUnit.MILLISECONDS));
- tlm.recycle(first);
-
- final Message second = tlm.next();
- assertNotNull(second.callback);
- tlm.execute(second);
- assertFalse(tlm.hasMessages(handler, null, 42));
- assertTrue(latch.await(100, TimeUnit.MILLISECONDS));
- tlm.recycle(second);
-
- tlm.release();
- }
-}
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
index 402b92a..26806b1 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
@@ -16,16 +16,23 @@
package android.view.textclassifier;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.mock;
+import android.Manifest;
import android.content.Context;
+import android.permission.flags.Flags;
+import android.platform.test.annotations.RequiresFlagsEnabled;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -61,4 +68,28 @@
assertThat(mTcm.getTextClassifier(TextClassifier.SYSTEM))
.isInstanceOf(SystemTextClassifier.class);
}
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ public void testGetClassifier() {
+ Assume.assumeTrue(Flags.textClassifierChoiceApiEnabled());
+ assertThrows(SecurityException.class,
+ () -> mTcm.getClassifier(TextClassifier.CLASSIFIER_TYPE_DEVICE_DEFAULT));
+ assertThrows(SecurityException.class,
+ () -> mTcm.getClassifier(TextClassifier.CLASSIFIER_TYPE_ANDROID_DEFAULT));
+ assertThrows(SecurityException.class,
+ () -> mTcm.getClassifier(TextClassifier.CLASSIFIER_TYPE_SELF_PROVIDED));
+
+ runWithShellPermissionIdentity(() -> {
+ assertThat(
+ mTcm.getClassifier(TextClassifier.CLASSIFIER_TYPE_DEVICE_DEFAULT)).isInstanceOf(
+ SystemTextClassifier.class);
+ assertThat(mTcm.getClassifier(
+ TextClassifier.CLASSIFIER_TYPE_ANDROID_DEFAULT)).isInstanceOf(
+ SystemTextClassifier.class);
+ assertThat(mTcm.getClassifier(
+ TextClassifier.CLASSIFIER_TYPE_SELF_PROVIDED)).isSameInstanceAs(
+ TextClassifier.NO_OP);
+ }, Manifest.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE);
+ }
}
diff --git a/core/tests/coretests/src/android/window/WindowContextTest.java b/core/tests/coretests/src/android/window/WindowContextTest.java
index 21930d1..b934426 100644
--- a/core/tests/coretests/src/android/window/WindowContextTest.java
+++ b/core/tests/coretests/src/android/window/WindowContextTest.java
@@ -33,7 +33,9 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.app.Activity;
import android.app.EmptyActivity;
@@ -48,7 +50,9 @@
import android.hardware.display.DisplayManager;
import android.os.Binder;
import android.os.IBinder;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.view.Display;
import android.view.IWindowManager;
import android.view.View;
@@ -64,6 +68,7 @@
import androidx.test.rule.ActivityTestRule;
import com.android.frameworks.coretests.R;
+import com.android.window.flags.Flags;
import org.junit.After;
import org.junit.Before;
@@ -91,6 +96,8 @@
public ActivityTestRule<EmptyActivity> mActivityRule =
new ActivityTestRule<>(EmptyActivity.class, false /* initialTouchMode */,
false /* launchActivity */);
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
private final WindowContext mWindowContext = createWindowContext();
@@ -340,17 +347,35 @@
}
@Test
- public void updateDisplay_wasAttached_detachThenAttachedPropagatedToTokenController() {
+ @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+ public void reparentToDisplayId_wasAttached_reparentToDisplayAreaPropagatedToTokenController() {
final WindowTokenClientController mockWindowTokenClientController =
mock(WindowTokenClientController.class);
+ when(mockWindowTokenClientController.attachToDisplayArea(any(), anyInt(), anyInt(),
+ any())).thenReturn(true);
WindowTokenClientController.overrideForTesting(mockWindowTokenClientController);
- mWindowContext.updateDisplay(DEFAULT_DISPLAY + 1);
+ mWindowContext.reparentToDisplay(DEFAULT_DISPLAY + 1);
- verify(mockWindowTokenClientController).detachIfNeeded(any());
- verify(mockWindowTokenClientController).attachToDisplayArea(any(),
- anyInt(), /* displayId= */ eq(DEFAULT_DISPLAY + 1),
- any());
+ verify(mockWindowTokenClientController).reparentToDisplayArea(any(),
+ /* displayId= */ eq(DEFAULT_DISPLAY + 1)
+ );
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+ public void reparentToDisplayId_sameDisplayId_noReparenting() {
+ final WindowTokenClientController mockWindowTokenClientController =
+ mock(WindowTokenClientController.class);
+ when(mockWindowTokenClientController.attachToDisplayArea(any(), anyInt(), anyInt(),
+ any())).thenReturn(true);
+ WindowTokenClientController.overrideForTesting(mockWindowTokenClientController);
+
+ mWindowContext.reparentToDisplay(DEFAULT_DISPLAY);
+
+ verify(mockWindowTokenClientController, never()).reparentToDisplayArea(any(),
+ /* displayId= */ eq(DEFAULT_DISPLAY)
+ );
}
private WindowContext createWindowContext() {
diff --git a/core/tests/coretests/src/com/android/internal/view/ScrollCaptureInternalTest.java b/core/tests/coretests/src/com/android/internal/view/ScrollCaptureInternalTest.java
new file mode 100644
index 0000000..5f6d806
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/view/ScrollCaptureInternalTest.java
@@ -0,0 +1,243 @@
+/*
+ * 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.internal.view;
+
+import static android.view.flags.Flags.FLAG_SCROLL_CAPTURE_RELAX_SCROLL_VIEW_CRITERIA;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.android.internal.view.ScrollCaptureInternal.TYPE_FIXED;
+import static com.android.internal.view.ScrollCaptureInternal.TYPE_OPAQUE;
+import static com.android.internal.view.ScrollCaptureInternal.TYPE_RECYCLING;
+import static com.android.internal.view.ScrollCaptureInternal.TYPE_SCROLLING;
+import static com.android.internal.view.ScrollCaptureInternal.detectScrollingType;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.testing.AndroidTestingRunner;
+import android.view.ViewGroup;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests scrolling detection.
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class ScrollCaptureInternalTest {
+
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+ /**
+ * Tests the effect of padding on scroll capture search dispatch.
+ * <p>
+ * Verifies computation of child visible bounds with padding.
+ */
+ @Test
+ public void testDetectScrollingType_scrolling_notScrollable() {
+ MockScrollable scrollable = new MockScrollable.Builder()
+ .bounds(0, 0, 200, 200)
+ .childCount(1)
+ .canScrollUp(false)
+ .canScrollDown(false)
+ .scrollToEnabled(false)
+ .build(getInstrumentation().getContext());
+
+ assertEquals(TYPE_FIXED, detectScrollingType(scrollable));
+ }
+
+ @Test
+ public void testDetectScrollingType_scrolling_noChildren() {
+ MockScrollable scrollable = new MockScrollable.Builder()
+ .bounds(0, 0, 200, 200)
+ .childCount(0)
+ .canScrollUp(false)
+ .canScrollDown(true)
+ .scrollToEnabled(true)
+ .build(getInstrumentation().getContext());
+
+ assertEquals(TYPE_OPAQUE, detectScrollingType(scrollable));
+ }
+
+ @Test
+ public void testDetectScrollingType_scrolling() {
+ MockScrollable scrollable = new MockScrollable.Builder()
+ .bounds(0, 0, 200, 200)
+ .childCount(1)
+ .canScrollUp(false)
+ .canScrollDown(true)
+ .scrollToEnabled(true)
+ .build(getInstrumentation().getContext());
+
+ assertEquals(TYPE_SCROLLING, detectScrollingType(scrollable));
+ }
+
+ @Test
+ public void testDetectScrollingType_scrolling_partiallyScrolled() {
+ MockScrollable scrollable = new MockScrollable.Builder()
+ .bounds(0, 0, 200, 200)
+ .childCount(1)
+ .canScrollUp(true)
+ .canScrollDown(true)
+ .scrollToEnabled(true)
+ .build(getInstrumentation().getContext());
+ scrollable.scrollTo(0, 100);
+
+ assertEquals(TYPE_SCROLLING, detectScrollingType(scrollable));
+ }
+
+ @Test
+ @EnableFlags(FLAG_SCROLL_CAPTURE_RELAX_SCROLL_VIEW_CRITERIA)
+ public void testDetectScrollingType_scrolling_multipleChildren() {
+ MockScrollable scrollable = new MockScrollable.Builder()
+ .bounds(0, 0, 200, 200)
+ .childCount(10)
+ .canScrollUp(false)
+ .canScrollDown(true)
+ .scrollToEnabled(true)
+ .build(getInstrumentation().getContext());
+
+ assertEquals(TYPE_SCROLLING, detectScrollingType(scrollable));
+ }
+
+ @Test
+ public void testDetectScrollingType_recycling() {
+ MockScrollable scrollable = new MockScrollable.Builder()
+ .bounds(0, 0, 200, 200)
+ .childCount(10)
+ .canScrollUp(false)
+ .canScrollDown(true)
+ .scrollToEnabled(false)
+ .build(getInstrumentation().getContext());
+
+ assertEquals(TYPE_RECYCLING, detectScrollingType(scrollable));
+ }
+
+ @Test
+ public void testDetectScrollingType_noChildren() {
+ MockScrollable scrollable = new MockScrollable.Builder()
+ .bounds(0, 0, 200, 200)
+ .childCount(0)
+ .canScrollUp(true)
+ .canScrollDown(true)
+ .scrollToEnabled(false)
+ .build(getInstrumentation().getContext());
+
+ assertEquals(TYPE_OPAQUE, detectScrollingType(scrollable));
+ }
+
+
+ /**
+ * A mock which can exhibit some attributes and behaviors used to detect different types
+ * of scrolling content.
+ */
+ private static class MockScrollable extends ViewGroup {
+ private final int mChildCount;
+ private final boolean mCanScrollUp;
+ private final boolean mCanScrollDown;
+ private final boolean mScrollToEnabled;
+
+ MockScrollable(Context context, Rect bounds, int childCount, boolean canScrollUp,
+ boolean canScrollDown, boolean scrollToEnabled) {
+ super(context);
+ setFrame(bounds.left, bounds.top, bounds.right, bounds.bottom);
+ mCanScrollUp = canScrollUp;
+ mCanScrollDown = canScrollDown;
+ mScrollToEnabled = scrollToEnabled;
+ mChildCount = childCount;
+ }
+
+ private static class Builder {
+ private int mChildCount;
+ private boolean mCanScrollUp;
+ private boolean mCanScrollDown;
+ private boolean mScrollToEnabled = true;
+
+ private final Rect mBounds = new Rect();
+
+ public MockScrollable build(Context context) {
+ return new MockScrollable(context,
+ mBounds, mChildCount, mCanScrollUp, mCanScrollDown,
+ mScrollToEnabled);
+ }
+
+ public Builder canScrollUp(boolean canScrollUp) {
+ mCanScrollUp = canScrollUp;
+ return this;
+ }
+
+ public Builder canScrollDown(boolean canScrollDown) {
+ mCanScrollDown = canScrollDown;
+ return this;
+ }
+
+ public Builder scrollToEnabled(boolean enabled) {
+ mScrollToEnabled = enabled;
+ return this;
+ }
+
+ public Builder childCount(int childCount) {
+ mChildCount = childCount;
+ return this;
+ }
+
+ public Builder bounds(int left, int top, int right, int bottom) {
+ mBounds.set(left, top, right, bottom);
+ return this;
+ }
+ }
+
+ @Override
+ public boolean canScrollVertically(int direction) {
+ if (direction > 0) {
+ return mCanScrollDown;
+ } else if (direction < 0) {
+ return mCanScrollUp;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int getChildCount() {
+ return mChildCount;
+ }
+
+ @Override
+ public void scrollTo(int x, int y) {
+ if (mScrollToEnabled) {
+ super.scrollTo(x, y);
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ // We don't layout this view.
+ }
+ }
+}
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 9bf4d65..2e88514 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -34,6 +34,7 @@
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
+import android.graphics.fonts.FontStyle;
import android.graphics.fonts.FontVariationAxis;
import android.graphics.text.TextRunShaper;
import android.os.Build;
@@ -2141,6 +2142,14 @@
* @see FontVariationAxis
*/
public boolean setFontVariationSettings(String fontVariationSettings) {
+ return setFontVariationSettings(fontVariationSettings, 0 /* wght adjust */);
+ }
+
+ /**
+ * Set font variation settings with weight adjustment
+ * @hide
+ */
+ public boolean setFontVariationSettings(String fontVariationSettings, int wghtAdjust) {
final boolean useFontVariationStore = Flags.typefaceRedesignReadonly()
&& CompatChanges.isChangeEnabled(NEW_FONT_VARIATION_MANAGEMENT);
if (useFontVariationStore) {
@@ -2154,8 +2163,13 @@
long builderPtr = nCreateFontVariationBuilder(axes.length);
for (int i = 0; i < axes.length; ++i) {
- nAddFontVariationToBuilder(builderPtr, axes[i].getOpenTypeTagValue(),
- axes[i].getStyleValue());
+ int tag = axes[i].getOpenTypeTagValue();
+ float value = axes[i].getStyleValue();
+ if (tag == 0x77676874 /* wght */) {
+ value = Math.clamp(value + wghtAdjust,
+ FontStyle.FONT_WEIGHT_MIN, FontStyle.FONT_WEIGHT_MAX);
+ }
+ nAddFontVariationToBuilder(builderPtr, tag, value);
}
nSetFontVariationOverride(mNativePaint, builderPtr);
mFontVariationSettings = fontVariationSettings;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
index 9ea2943..f0613ce 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -398,27 +398,23 @@
new TaskFragmentAnimationParams.Builder();
final int animationBackgroundColor = getAnimationBackgroundColor(splitAttributes);
builder.setAnimationBackgroundColor(animationBackgroundColor);
- if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- final int openAnimationResId =
- splitAttributes.getAnimationParams().getOpenAnimationResId();
- builder.setOpenAnimationResId(openAnimationResId);
- final int closeAnimationResId =
- splitAttributes.getAnimationParams().getCloseAnimationResId();
- builder.setCloseAnimationResId(closeAnimationResId);
- final int changeAnimationResId =
- splitAttributes.getAnimationParams().getChangeAnimationResId();
- builder.setChangeAnimationResId(changeAnimationResId);
- }
+ final int openAnimationResId =
+ splitAttributes.getAnimationParams().getOpenAnimationResId();
+ builder.setOpenAnimationResId(openAnimationResId);
+ final int closeAnimationResId =
+ splitAttributes.getAnimationParams().getCloseAnimationResId();
+ builder.setCloseAnimationResId(closeAnimationResId);
+ final int changeAnimationResId =
+ splitAttributes.getAnimationParams().getChangeAnimationResId();
+ builder.setChangeAnimationResId(changeAnimationResId);
return builder.build();
}
@ColorInt
private static int getAnimationBackgroundColor(@NonNull SplitAttributes splitAttributes) {
int animationBackgroundColor = DEFAULT_ANIMATION_BACKGROUND_COLOR;
- AnimationBackground animationBackground = splitAttributes.getAnimationBackground();
- if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- animationBackground = splitAttributes.getAnimationParams().getAnimationBackground();
- }
+ final AnimationBackground animationBackground =
+ splitAttributes.getAnimationParams().getAnimationBackground();
if (animationBackground instanceof AnimationBackground.ColorBackground colorBackground) {
animationBackgroundColor = colorBackground.getColor();
}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
index b38d00da..1d0c505 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
@@ -602,8 +602,72 @@
testGetBubbleBarExpandedViewBounds(onLeft = false, isOverflow = true)
}
+ @Test
+ fun getExpandedViewContainerPadding_largeScreen_fitsMaxViewWidth() {
+ val expandedViewWidth = context.resources.getDimensionPixelSize(
+ R.dimen.bubble_expanded_view_largescreen_width
+ )
+ // set the screen size so that it is wide enough to fit the maximum width size
+ val screenWidth = expandedViewWidth * 2
+ positioner.update(
+ defaultDeviceConfig.copy(
+ windowBounds = Rect(0, 0, screenWidth, 2000),
+ isLargeScreen = true,
+ isLandscape = false
+ )
+ )
+ val paddings =
+ positioner.getExpandedViewContainerPadding(/* onLeft= */ true, /* isOverflow= */ false)
+
+ val padding = context.resources.getDimensionPixelSize(
+ R.dimen.bubble_expanded_view_largescreen_landscape_padding
+ )
+ val right = screenWidth - expandedViewWidth - padding
+ assertThat(paddings).isEqualTo(intArrayOf(padding - positioner.pointerSize, 0, right, 0))
+ }
+
+ @Test
+ fun getExpandedViewContainerPadding_largeScreen_doesNotFitMaxViewWidth() {
+ positioner.update(
+ defaultDeviceConfig.copy(
+ windowBounds = Rect(0, 0, 600, 2000),
+ isLargeScreen = true,
+ isLandscape = false
+ )
+ )
+ val paddings =
+ positioner.getExpandedViewContainerPadding(/* onLeft= */ true, /* isOverflow= */ false)
+
+ val padding = context.resources.getDimensionPixelSize(
+ R.dimen.bubble_expanded_view_largescreen_landscape_padding
+ )
+ // the screen is not wide enough to fit the maximum width size, so the view fills the screen
+ // minus left and right padding
+ assertThat(paddings).isEqualTo(intArrayOf(padding - positioner.pointerSize, 0, padding, 0))
+ }
+
+ @Test
+ fun getExpandedViewContainerPadding_smallTablet() {
+ val screenWidth = 500
+ positioner.update(
+ defaultDeviceConfig.copy(
+ windowBounds = Rect(0, 0, screenWidth, 2000),
+ isLargeScreen = true,
+ isSmallTablet = true,
+ isLandscape = false
+ )
+ )
+ val paddings =
+ positioner.getExpandedViewContainerPadding(/* onLeft= */ true, /* isOverflow= */ false)
+
+ // for small tablets, the view width is set to be 0.72 * screen width
+ val viewWidth = (screenWidth * 0.72).toInt()
+ val padding = (screenWidth - viewWidth) / 2
+ assertThat(paddings).isEqualTo(intArrayOf(padding - positioner.pointerSize, 0, padding, 0))
+ }
+
private fun testGetBubbleBarExpandedViewBounds(onLeft: Boolean, isOverflow: Boolean) {
- positioner.setShowingInBubbleBar(true)
+ positioner.isShowingInBubbleBar = true
val windowBounds = Rect(0, 0, 2000, 2600)
val insets = Insets.of(10, 20, 5, 15)
val deviceConfig =
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt
new file mode 100644
index 0000000..0d8f809
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt
@@ -0,0 +1,228 @@
+/*
+ * 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.bubbles.bar
+
+import android.content.Context
+import android.graphics.Insets
+import android.graphics.Rect
+import android.view.View
+import android.view.ViewGroup
+import android.view.WindowManager
+import android.widget.FrameLayout
+import androidx.core.animation.AnimatorTestRule
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.bubbles.Bubble
+import com.android.wm.shell.bubbles.BubbleExpandedViewManager
+import com.android.wm.shell.bubbles.BubbleLogger
+import com.android.wm.shell.bubbles.BubbleOverflow
+import com.android.wm.shell.bubbles.BubblePositioner
+import com.android.wm.shell.bubbles.DeviceConfig
+import com.android.wm.shell.bubbles.FakeBubbleExpandedViewManager
+import com.android.wm.shell.bubbles.FakeBubbleFactory
+import com.android.wm.shell.bubbles.FakeBubbleTaskViewFactory
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Semaphore
+import java.util.concurrent.TimeUnit
+import org.junit.After
+import org.junit.Before
+import org.junit.ClassRule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Tests for [BubbleBarAnimationHelper] */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BubbleBarAnimationHelperTest {
+
+ companion object {
+ @JvmField @ClassRule val animatorTestRule: AnimatorTestRule = AnimatorTestRule()
+
+ const val SCREEN_WIDTH = 2000
+ const val SCREEN_HEIGHT = 1000
+ }
+
+ private val context = ApplicationProvider.getApplicationContext<Context>()
+
+ private lateinit var animationHelper: BubbleBarAnimationHelper
+ private lateinit var bubblePositioner: BubblePositioner
+ private lateinit var expandedViewManager: BubbleExpandedViewManager
+ private lateinit var bubbleLogger: BubbleLogger
+ private lateinit var mainExecutor: TestShellExecutor
+ private lateinit var bgExecutor: TestShellExecutor
+ private lateinit var container: FrameLayout
+
+ @Before
+ fun setUp() {
+ ProtoLog.REQUIRE_PROTOLOGTOOL = false
+ ProtoLog.init()
+ val windowManager = context.getSystemService(WindowManager::class.java)
+ bubblePositioner = BubblePositioner(context, windowManager)
+ bubblePositioner.setShowingInBubbleBar(true)
+ val deviceConfig =
+ DeviceConfig(
+ windowBounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
+ isLargeScreen = true,
+ isSmallTablet = false,
+ isLandscape = true,
+ isRtl = false,
+ insets = Insets.of(10, 20, 30, 40),
+ )
+ bubblePositioner.update(deviceConfig)
+ expandedViewManager = FakeBubbleExpandedViewManager()
+ bubbleLogger = BubbleLogger(UiEventLoggerFake())
+
+ mainExecutor = TestShellExecutor()
+ bgExecutor = TestShellExecutor()
+
+ container = FrameLayout(context)
+
+ animationHelper = BubbleBarAnimationHelper(context, bubblePositioner)
+ }
+
+ @After
+ fun tearDown() {
+ bgExecutor.flushAll()
+ mainExecutor.flushAll()
+ }
+
+ @Test
+ fun animateSwitch_bubbleToBubble_oldHiddenNewShown() {
+ val fromBubble = createBubble(key = "from").initialize(container)
+ val toBubble = createBubble(key = "to").initialize(container)
+
+ val semaphore = Semaphore(0)
+ val after = Runnable { semaphore.release() }
+
+ getInstrumentation().runOnMainSync {
+ animationHelper.animateSwitch(fromBubble, toBubble, after)
+ animatorTestRule.advanceTimeBy(1000)
+ }
+ getInstrumentation().waitForIdleSync()
+
+ assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue()
+ assertThat(fromBubble.bubbleBarExpandedView?.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(fromBubble.bubbleBarExpandedView?.alpha).isEqualTo(0f)
+ assertThat(fromBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse()
+
+ assertThat(toBubble.bubbleBarExpandedView?.visibility).isEqualTo(View.VISIBLE)
+ assertThat(toBubble.bubbleBarExpandedView?.alpha).isEqualTo(1f)
+ assertThat(toBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse()
+ }
+
+ @Test
+ fun animateSwitch_bubbleToBubble_handleColorTransferred() {
+ val fromBubble = createBubble(key = "from").initialize(container)
+ fromBubble.bubbleBarExpandedView!!
+ .handleView
+ .updateHandleColor(/* isRegionDark= */ true, /* animated= */ false)
+ val toBubble = createBubble(key = "to").initialize(container)
+
+ getInstrumentation().runOnMainSync {
+ animationHelper.animateSwitch(fromBubble, toBubble, /* afterAnimation= */ null)
+ animatorTestRule.advanceTimeBy(1000)
+ }
+ getInstrumentation().waitForIdleSync()
+
+ assertThat(toBubble.bubbleBarExpandedView!!.handleView.handleColor)
+ .isEqualTo(fromBubble.bubbleBarExpandedView!!.handleView.handleColor)
+ }
+
+ @Test
+ fun animateSwitch_bubbleToOverflow_oldHiddenNewShown() {
+ val fromBubble = createBubble(key = "from").initialize(container)
+ val overflow = createOverflow().initialize(container)
+
+ val semaphore = Semaphore(0)
+ val after = Runnable { semaphore.release() }
+
+ getInstrumentation().runOnMainSync {
+ animationHelper.animateSwitch(fromBubble, overflow, after)
+ animatorTestRule.advanceTimeBy(1000)
+ }
+ getInstrumentation().waitForIdleSync()
+
+ assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue()
+ assertThat(fromBubble.bubbleBarExpandedView?.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(fromBubble.bubbleBarExpandedView?.alpha).isEqualTo(0f)
+ assertThat(fromBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse()
+
+ assertThat(overflow.bubbleBarExpandedView?.visibility).isEqualTo(View.VISIBLE)
+ assertThat(overflow.bubbleBarExpandedView?.alpha).isEqualTo(1f)
+ }
+
+ @Test
+ fun animateSwitch_overflowToBubble_oldHiddenNewShown() {
+ val overflow = createOverflow().initialize(container)
+ val toBubble = createBubble(key = "to").initialize(container)
+
+ val semaphore = Semaphore(0)
+ val after = Runnable { semaphore.release() }
+
+ getInstrumentation().runOnMainSync {
+ animationHelper.animateSwitch(overflow, toBubble, after)
+ animatorTestRule.advanceTimeBy(1000)
+ }
+ getInstrumentation().waitForIdleSync()
+
+ assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue()
+ assertThat(overflow.bubbleBarExpandedView?.visibility).isEqualTo(View.INVISIBLE)
+ assertThat(overflow.bubbleBarExpandedView?.alpha).isEqualTo(0f)
+
+ assertThat(toBubble.bubbleBarExpandedView?.visibility).isEqualTo(View.VISIBLE)
+ assertThat(toBubble.bubbleBarExpandedView?.alpha).isEqualTo(1f)
+ assertThat(toBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse()
+ }
+
+ private fun createBubble(key: String): Bubble {
+ val bubbleBarExpandedView =
+ FakeBubbleFactory.createExpandedView(
+ context,
+ bubblePositioner,
+ expandedViewManager,
+ FakeBubbleTaskViewFactory(context, mainExecutor).create(),
+ mainExecutor,
+ bgExecutor,
+ bubbleLogger,
+ )
+ val viewInfo = FakeBubbleFactory.createViewInfo(bubbleBarExpandedView)
+ return FakeBubbleFactory.createChatBubble(context, key, viewInfo)
+ }
+
+ private fun createOverflow(): BubbleOverflow {
+ val overflow = BubbleOverflow(context, bubblePositioner)
+ overflow.initializeForBubbleBar(expandedViewManager, bubblePositioner, bubbleLogger)
+ return overflow
+ }
+
+ private fun Bubble.initialize(container: ViewGroup): Bubble {
+ getInstrumentation().runOnMainSync { container.addView(bubbleBarExpandedView) }
+ // Mark taskView's visible
+ bubbleBarExpandedView!!.onContentVisibilityChanged(true)
+ return this
+ }
+
+ private fun BubbleOverflow.initialize(container: ViewGroup): BubbleOverflow {
+ getInstrumentation().runOnMainSync { container.addView(bubbleBarExpandedView) }
+ return this
+ }
+}
diff --git a/libs/WindowManager/Shell/res/color/bubble_drop_target_background_color.xml b/libs/WindowManager/Shell/res/color/bubble_drop_target_background_color.xml
index ab1ab98..87d3628 100644
--- a/libs/WindowManager/Shell/res/color/bubble_drop_target_background_color.xml
+++ b/libs/WindowManager/Shell/res/color/bubble_drop_target_background_color.xml
@@ -16,5 +16,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:alpha="0.35" android:color="?androidprv:attr/materialColorPrimaryContainer" />
+ <item android:alpha="0.35" android:color="@androidprv:color/materialColorPrimaryContainer" />
</selector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_color_selector.xml b/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_color_selector.xml
index 640d184..047f22f 100644
--- a/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_color_selector.xml
+++ b/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_color_selector.xml
@@ -22,5 +22,5 @@
android:color="?androidprv:attr/colorAccentPrimary"/>
<item android:state_selected="true"
android:color="?androidprv:attr/colorAccentPrimary"/>
- <item android:color="?androidprv:attr/materialColorOutlineVariant"/>
+ <item android:color="@androidprv:color/materialColorOutlineVariant"/>
</selector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/color/open_by_default_settings_dialog_radio_button_color.xml b/libs/WindowManager/Shell/res/color/open_by_default_settings_dialog_radio_button_color.xml
index 0f9b28a..9741b94 100644
--- a/libs/WindowManager/Shell/res/color/open_by_default_settings_dialog_radio_button_color.xml
+++ b/libs/WindowManager/Shell/res/color/open_by_default_settings_dialog_radio_button_color.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:state_checked="true"
- android:color="?androidprv:attr/materialColorPrimaryContainer"/>
- <item android:color="?androidprv:attr/materialColorSurfaceContainer"/>
+ android:color="@androidprv:color/materialColorPrimaryContainer"/>
+ <item android:color="@androidprv:color/materialColorSurfaceContainer"/>
</selector>
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_drop_target_background.xml b/libs/WindowManager/Shell/res/drawable/bubble_drop_target_background.xml
index b928a0b..20e00e1 100644
--- a/libs/WindowManager/Shell/res/drawable/bubble_drop_target_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/bubble_drop_target_background.xml
@@ -21,6 +21,6 @@
<solid android:color="@color/bubble_drop_target_background_color" />
<stroke
android:width="1dp"
- android:color="?androidprv:attr/materialColorPrimaryContainer" />
+ android:color="@androidprv:color/materialColorPrimaryContainer" />
</shape>
</inset>
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_manage_btn_bg.xml b/libs/WindowManager/Shell/res/drawable/bubble_manage_btn_bg.xml
index 657720e..5acca45 100644
--- a/libs/WindowManager/Shell/res/drawable/bubble_manage_btn_bg.xml
+++ b/libs/WindowManager/Shell/res/drawable/bubble_manage_btn_bg.xml
@@ -19,7 +19,7 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
<solid
- android:color="?androidprv:attr/materialColorSurfaceContainerHigh"
+ android:color="@androidprv:color/materialColorSurfaceContainerHigh"
/>
<corners android:radius="18sp" />
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_bg.xml b/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_bg.xml
index 8fd2e68..f4d1de8 100644
--- a/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_bg.xml
+++ b/libs/WindowManager/Shell/res/drawable/bubble_manage_menu_bg.xml
@@ -17,7 +17,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceBright" />
+ <solid android:color="@androidprv:color/materialColorSurfaceBright" />
<corners
android:bottomLeftRadius="?android:attr/dialogCornerRadius"
android:topLeftRadius="?android:attr/dialogCornerRadius"
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml
index 15837ad..5769a85 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml
@@ -18,5 +18,5 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<corners android:radius="@dimen/desktop_mode_handle_menu_corner_radius" />
- <solid android:color="?androidprv:attr/materialColorSurfaceBright" />
+ <solid android:color="@androidprv:color/materialColorSurfaceBright" />
</shape>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_background.xml
index 9566f2f..bab2c95 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_background.xml
@@ -17,6 +17,6 @@
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerLow" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerLow" />
<corners android:radius="@dimen/desktop_mode_maximize_menu_corner_radius" />
</shape>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background.xml
index a30cfb7..b03b134 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background.xml
@@ -20,6 +20,6 @@
android:shape="rectangle">
<corners
android:radius="@dimen/desktop_mode_maximize_menu_buttons_outline_radius"/>
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerLow"/>
- <stroke android:width="1dp" android:color="?androidprv:attr/materialColorOutlineVariant"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerLow"/>
+ <stroke android:width="1dp" android:color="@androidprv:color/materialColorOutlineVariant"/>
</shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_windowing_education_promo_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_windowing_education_promo_background.xml
index 645d24d..b24d432 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_windowing_education_promo_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_windowing_education_promo_background.xml
@@ -17,6 +17,6 @@
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerLow" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerLow" />
<corners android:radius="@dimen/desktop_windowing_education_promo_corner_radius" />
</shape>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml
index 4e673e6..dd1a1b1 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml
@@ -18,7 +18,7 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:id="@+id/indicator_solid">
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorPrimaryContainer" />
+ <solid android:color="@androidprv:color/materialColorPrimaryContainer" />
<corners android:radius="28dp" />
</shape>
</item>
@@ -26,7 +26,7 @@
<shape android:shape="rectangle">
<corners android:radius="28dp" />
<stroke android:width="1dp"
- android:color="?androidprv:attr/materialColorPrimaryContainer"/>
+ android:color="@androidprv:color/materialColorPrimaryContainer"/>
</shape>
</item>
</layer-list>
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_dialog_background.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dialog_background.xml
index f37fb8d..527cc31 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_dialog_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_dialog_background.xml
@@ -17,6 +17,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh"/>
<corners android:radius="@dimen/letterbox_education_dialog_corner_radius"/>
</shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
index 3fdd059..5336b3a 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_dismiss_button_background_ripple.xml
@@ -32,7 +32,7 @@
</item>
<item>
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorPrimary"/>
+ <solid android:color="@androidprv:color/materialColorPrimary"/>
<corners android:radius="@dimen/letterbox_education_dialog_button_radius"/>
<padding android:left="@dimen/letterbox_education_dialog_horizontal_padding"
android:top="@dimen/letterbox_education_dialog_vertical_padding"
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_light_bulb.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_light_bulb.xml
index 67929df..f45d704 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_light_bulb.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_light_bulb.xml
@@ -25,6 +25,6 @@
android:pathData="M0,0h32v32h-32z"/>
<path
android:pathData="M5.867,22.667C4.489,21.844 3.389,20.733 2.567,19.333C1.744,17.933 1.333,16.378 1.333,14.667C1.333,12.067 2.233,9.867 4.033,8.067C5.856,6.244 8.067,5.333 10.667,5.333C13.267,5.333 15.467,6.244 17.267,8.067C19.089,9.867 20,12.067 20,14.667C20,16.378 19.589,17.933 18.767,19.333C17.944,20.733 16.844,21.844 15.467,22.667H5.867ZM6.667,20H14.667C15.511,19.356 16.167,18.578 16.633,17.667C17.1,16.733 17.333,15.733 17.333,14.667C17.333,12.822 16.678,11.256 15.367,9.967C14.078,8.656 12.511,8 10.667,8C8.822,8 7.244,8.656 5.933,9.967C4.644,11.256 4,12.822 4,14.667C4,15.733 4.233,16.733 4.7,17.667C5.167,18.578 5.822,19.356 6.667,20ZM7.2,26.667C6.822,26.667 6.5,26.544 6.233,26.3C5.989,26.033 5.867,25.711 5.867,25.333C5.867,24.956 5.989,24.644 6.233,24.4C6.5,24.133 6.822,24 7.2,24H14.133C14.511,24 14.822,24.133 15.067,24.4C15.333,24.644 15.467,24.956 15.467,25.333C15.467,25.711 15.333,26.033 15.067,26.3C14.822,26.544 14.511,26.667 14.133,26.667H7.2ZM10.667,30.667C9.933,30.667 9.3,30.411 8.767,29.9C8.256,29.367 8,28.733 8,28H13.333C13.333,28.733 13.067,29.367 12.533,29.9C12.022,30.411 11.4,30.667 10.667,30.667ZM24.667,13.367C24.667,11.7 24.078,10.278 22.9,9.1C21.722,7.922 20.3,7.333 18.633,7.333C20.3,7.333 21.722,6.756 22.9,5.6C24.078,4.422 24.667,3 24.667,1.333C24.667,3 25.244,4.422 26.4,5.6C27.578,6.756 29,7.333 30.667,7.333C29,7.333 27.578,7.922 26.4,9.1C25.244,10.278 24.667,11.7 24.667,13.367Z"
- android:fillColor="?androidprv:attr/materialColorPrimary"/>
+ android:fillColor="@androidprv:color/materialColorPrimary"/>
</group>
</vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background_ripple.xml
index 4207482..4e77720 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background_ripple.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_restart_button_background_ripple.xml
@@ -32,7 +32,7 @@
</item>
<item>
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorPrimary"/>
+ <solid android:color="@androidprv:color/materialColorPrimary"/>
<corners android:radius="@dimen/letterbox_restart_dialog_button_radius"/>
<padding android:left="@dimen/letterbox_restart_dialog_horizontal_padding"
android:top="@dimen/letterbox_restart_dialog_vertical_padding"
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_restart_dialog_background.xml b/libs/WindowManager/Shell/res/drawable/letterbox_restart_dialog_background.xml
index 72cfeef..90b314a 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_restart_dialog_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_restart_dialog_background.xml
@@ -17,6 +17,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh"/>
<corners android:radius="@dimen/letterbox_restart_dialog_corner_radius"/>
</shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background_ripple.xml b/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background_ripple.xml
index 816b350..d64e632 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background_ripple.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_restart_dismiss_button_background_ripple.xml
@@ -32,9 +32,9 @@
</item>
<item>
<shape android:shape="rectangle">
- <stroke android:color="?androidprv:attr/materialColorOutlineVariant"
+ <stroke android:color="@androidprv:color/materialColorOutlineVariant"
android:width="1dp"/>
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh"/>
<corners android:radius="@dimen/letterbox_restart_dialog_button_radius"/>
<padding android:left="@dimen/letterbox_restart_dialog_horizontal_padding"
android:top="@dimen/letterbox_restart_dialog_vertical_padding"
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_restart_header_ic_arrows.xml b/libs/WindowManager/Shell/res/drawable/letterbox_restart_header_ic_arrows.xml
index f13d26c..53b4a4b 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_restart_header_ic_arrows.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_restart_header_ic_arrows.xml
@@ -25,6 +25,6 @@
android:pathData="M0,0h32v32h-32z"/>
<path
android:pathData="M8.533,25.333H10.667C11.044,25.333 11.356,25.467 11.6,25.733C11.867,25.978 12,26.289 12,26.667C12,27.044 11.867,27.367 11.6,27.633C11.356,27.878 11.044,28 10.667,28H5.333C4.956,28 4.633,27.878 4.367,27.633C4.122,27.367 4,27.044 4,26.667V21.333C4,20.956 4.122,20.644 4.367,20.4C4.633,20.133 4.956,20 5.333,20C5.711,20 6.022,20.133 6.267,20.4C6.533,20.644 6.667,20.956 6.667,21.333V23.467L9.867,20.267C10.111,20.022 10.422,19.9 10.8,19.9C11.178,19.9 11.489,20.022 11.733,20.267C11.978,20.511 12.1,20.822 12.1,21.2C12.1,21.578 11.978,21.889 11.733,22.133L8.533,25.333ZM23.467,25.333L20.267,22.133C20.022,21.889 19.9,21.578 19.9,21.2C19.9,20.822 20.022,20.511 20.267,20.267C20.511,20.022 20.822,19.9 21.2,19.9C21.578,19.9 21.889,20.022 22.133,20.267L25.333,23.467V21.333C25.333,20.956 25.456,20.644 25.7,20.4C25.967,20.133 26.289,20 26.667,20C27.044,20 27.356,20.133 27.6,20.4C27.867,20.644 28,20.956 28,21.333V26.667C28,27.044 27.867,27.367 27.6,27.633C27.356,27.878 27.044,28 26.667,28H21.333C20.956,28 20.633,27.878 20.367,27.633C20.122,27.367 20,27.044 20,26.667C20,26.289 20.122,25.978 20.367,25.733C20.633,25.467 20.956,25.333 21.333,25.333H23.467ZM6.667,8.533V10.667C6.667,11.044 6.533,11.367 6.267,11.633C6.022,11.878 5.711,12 5.333,12C4.956,12 4.633,11.878 4.367,11.633C4.122,11.367 4,11.044 4,10.667V5.333C4,4.956 4.122,4.644 4.367,4.4C4.633,4.133 4.956,4 5.333,4H10.667C11.044,4 11.356,4.133 11.6,4.4C11.867,4.644 12,4.956 12,5.333C12,5.711 11.867,6.033 11.6,6.3C11.356,6.544 11.044,6.667 10.667,6.667H8.533L11.733,9.867C11.978,10.111 12.1,10.422 12.1,10.8C12.1,11.178 11.978,11.489 11.733,11.733C11.489,11.978 11.178,12.1 10.8,12.1C10.422,12.1 10.111,11.978 9.867,11.733L6.667,8.533ZM25.333,8.533L22.133,11.733C21.889,11.978 21.578,12.1 21.2,12.1C20.822,12.1 20.511,11.978 20.267,11.733C20.022,11.489 19.9,11.178 19.9,10.8C19.9,10.422 20.022,10.111 20.267,9.867L23.467,6.667H21.333C20.956,6.667 20.633,6.544 20.367,6.3C20.122,6.033 20,5.711 20,5.333C20,4.956 20.122,4.644 20.367,4.4C20.633,4.133 20.956,4 21.333,4H26.667C27.044,4 27.356,4.133 27.6,4.4C27.867,4.644 28,4.956 28,5.333V10.667C28,11.044 27.867,11.367 27.6,11.633C27.356,11.878 27.044,12 26.667,12C26.289,12 25.967,11.878 25.7,11.633C25.456,11.367 25.333,11.044 25.333,10.667V8.533Z"
- android:fillColor="?androidprv:attr/materialColorPrimary"/>
+ android:fillColor="@androidprv:color/materialColorPrimary"/>
</group>
</vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_background.xml b/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_background.xml
index 4eb2271..d1a510a 100644
--- a/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_background.xml
@@ -17,6 +17,6 @@
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainer"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceContainer"/>
<corners android:radius="28dp"/>
</shape>
diff --git a/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_confirm_button_background.xml b/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_confirm_button_background.xml
index 2b2e9df..20e2e7e 100644
--- a/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_confirm_button_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/open_by_default_settings_dialog_confirm_button_background.xml
@@ -17,6 +17,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorPrimary"/>
+ <solid android:color="@androidprv:color/materialColorPrimary"/>
<corners android:radius="50dp"/>
</shape>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
index 4c7d1c7..7347fbad 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
@@ -29,7 +29,7 @@
<ImageView
android:layout_width="@dimen/bubble_popup_icon_size"
android:layout_height="@dimen/bubble_popup_icon_size"
- android:tint="?androidprv:attr/materialColorOutline"
+ android:tint="@androidprv:color/materialColorOutline"
android:contentDescription="@null"
android:src="@drawable/pip_ic_settings"/>
@@ -41,7 +41,7 @@
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Headline"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:text="@string/bubble_bar_education_manage_title"/>
<TextView
@@ -51,7 +51,7 @@
android:paddingBottom="@dimen/bubble_popup_padding_bottom"
android:maxWidth="@dimen/bubble_popup_content_max_width"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
android:textAlignment="center"
android:text="@string/bubble_bar_education_manage_text"/>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_menu_item.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_item.xml
index e3217811..5750ed7 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_menu_item.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_item.xml
@@ -36,7 +36,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault" />
</com.android.wm.shell.bubbles.bar.BubbleBarMenuItemView>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml
index 7aca921..27e3b00 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_menu_view.xml
@@ -50,7 +50,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="1"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault" />
<ImageView
@@ -60,7 +60,7 @@
android:layout_marginStart="8dp"
android:contentDescription="@null"
android:src="@drawable/ic_expand_less"
- app:tint="?androidprv:attr/materialColorOnSurface" />
+ app:tint="@androidprv:color/materialColorOnSurface" />
</LinearLayout>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml
index 345c399..f0e18711 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml
@@ -29,7 +29,7 @@
<ImageView
android:layout_width="@dimen/bubble_popup_icon_size"
android:layout_height="@dimen/bubble_popup_icon_size"
- android:tint="?androidprv:attr/materialColorOutline"
+ android:tint="@androidprv:color/materialColorOutline"
android:contentDescription="@null"
android:src="@drawable/ic_floating_landscape"/>
@@ -41,7 +41,7 @@
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Headline"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:text="@string/bubble_bar_education_stack_title"/>
<TextView
@@ -51,7 +51,7 @@
android:paddingBottom="@dimen/bubble_popup_padding_bottom"
android:maxWidth="@dimen/bubble_popup_content_max_width"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
android:textAlignment="center"
android:text="@string/bubble_bar_education_stack_text"/>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_flyout.xml b/libs/WindowManager/Shell/res/layout/bubble_flyout.xml
index 65a07a7..deabd56 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_flyout.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_flyout.xml
@@ -49,7 +49,7 @@
android:fontFamily="@*android:string/config_bodyFontFamilyMedium"
android:maxLines="1"
android:ellipsize="end"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/>
<TextView
@@ -59,7 +59,7 @@
android:fontFamily="@*android:string/config_bodyFontFamily"
android:maxLines="2"
android:ellipsize="end"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/>
</LinearLayout>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_manage_button.xml b/libs/WindowManager/Shell/res/layout/bubble_manage_button.xml
index f88d63d..0c446df 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_manage_button.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_manage_button.xml
@@ -28,6 +28,6 @@
android:focusable="true"
android:text="@string/manage_bubbles_text"
android:textSize="@*android:dimen/text_size_body_2_material"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:background="@drawable/bubble_manage_btn_bg"
/>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
index d8ae9c8..4daaf9c 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
@@ -43,7 +43,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault"
android:text="@string/bubble_dismiss_text" />
@@ -70,7 +70,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault"
android:text="@string/bubbles_dont_bubble_conversation" />
@@ -98,7 +98,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault" />
</LinearLayout>
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
index bfd9c81..b69563b 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
@@ -52,7 +52,7 @@
android:layout_height="wrap_content"
tools:text="Gmail"
android:importantForAccessibility="no"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textSize="14sp"
android:textFontWeight="500"
android:lineHeight="20dp"
@@ -69,7 +69,7 @@
android:contentDescription="@string/collapse_menu_text"
android:src="@drawable/ic_baseline_expand_more_24"
android:rotation="180"
- android:tint="?androidprv:attr/materialColorOnSurface"
+ android:tint="@androidprv:color/materialColorOnSurface"
android:background="?android:selectableItemBackgroundBorderless"/>
</LinearLayout>
@@ -89,7 +89,7 @@
android:layout_marginEnd="4dp"
android:contentDescription="@string/fullscreen_text"
android:src="@drawable/desktop_mode_ic_handle_menu_fullscreen"
- android:tint="?androidprv:attr/materialColorOnSurface"
+ android:tint="@androidprv:color/materialColorOnSurface"
android:layout_weight="1"
style="@style/DesktopModeHandleMenuWindowingButton"/>
@@ -99,7 +99,7 @@
android:layout_marginEnd="4dp"
android:contentDescription="@string/split_screen_text"
android:src="@drawable/desktop_mode_ic_handle_menu_splitscreen"
- android:tint="?androidprv:attr/materialColorOnSurface"
+ android:tint="@androidprv:color/materialColorOnSurface"
android:layout_weight="1"
style="@style/DesktopModeHandleMenuWindowingButton"/>
@@ -109,7 +109,7 @@
android:layout_marginEnd="4dp"
android:contentDescription="@string/float_button_text"
android:src="@drawable/desktop_mode_ic_handle_menu_floating"
- android:tint="?androidprv:attr/materialColorOnSurface"
+ android:tint="@androidprv:color/materialColorOnSurface"
android:layout_weight="1"
style="@style/DesktopModeHandleMenuWindowingButton"/>
@@ -118,7 +118,7 @@
android:layout_marginStart="4dp"
android:contentDescription="@string/desktop_text"
android:src="@drawable/desktop_mode_ic_handle_menu_desktop"
- android:tint="?androidprv:attr/materialColorOnSurface"
+ android:tint="@androidprv:color/materialColorOnSurface"
android:layout_weight="1"
style="@style/DesktopModeHandleMenuWindowingButton"/>
@@ -139,7 +139,7 @@
android:contentDescription="@string/screenshot_text"
android:text="@string/screenshot_text"
android:drawableStart="@drawable/desktop_mode_ic_handle_menu_screenshot"
- android:drawableTint="?androidprv:attr/materialColorOnSurface"
+ android:drawableTint="@androidprv:color/materialColorOnSurface"
style="@style/DesktopModeHandleMenuActionButton"/>
<Button
@@ -147,7 +147,7 @@
android:contentDescription="@string/new_window_text"
android:text="@string/new_window_text"
android:drawableStart="@drawable/desktop_mode_ic_handle_menu_new_window"
- android:drawableTint="?androidprv:attr/materialColorOnSurface"
+ android:drawableTint="@androidprv:color/materialColorOnSurface"
style="@style/DesktopModeHandleMenuActionButton" />
<Button
@@ -155,7 +155,7 @@
android:contentDescription="@string/manage_windows_text"
android:text="@string/manage_windows_text"
android:drawableStart="@drawable/desktop_mode_ic_handle_menu_manage_windows"
- android:drawableTint="?androidprv:attr/materialColorOnSurface"
+ android:drawableTint="@androidprv:color/materialColorOnSurface"
style="@style/DesktopModeHandleMenuActionButton" />
<Button
@@ -163,7 +163,7 @@
android:contentDescription="@string/change_aspect_ratio_text"
android:text="@string/change_aspect_ratio_text"
android:drawableStart="@drawable/desktop_mode_ic_handle_menu_change_aspect_ratio"
- android:drawableTint="?androidprv:attr/materialColorOnSurface"
+ android:drawableTint="@androidprv:color/materialColorOnSurface"
style="@style/DesktopModeHandleMenuActionButton" />
</LinearLayout>
@@ -183,7 +183,7 @@
android:contentDescription="@string/open_in_browser_text"
android:text="@string/open_in_browser_text"
android:drawableStart="@drawable/desktop_mode_ic_handle_menu_open_in_browser"
- android:drawableTint="?androidprv:attr/materialColorOnSurface"
+ android:drawableTint="@androidprv:color/materialColorOnSurface"
style="@style/DesktopModeHandleMenuActionButton"/>
<ImageButton
@@ -195,7 +195,7 @@
android:layout_marginStart="10dp"
android:contentDescription="@string/open_by_default_settings_text"
android:src="@drawable/desktop_mode_ic_handle_menu_open_by_default_settings"
- android:tint="?androidprv:attr/materialColorOnSurface"/>
+ android:tint="@androidprv:color/materialColorOnSurface"/>
</LinearLayout>
</LinearLayout>
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
index 375968a..8d7e5fd 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
@@ -58,7 +58,7 @@
android:fontFamily="google-sans-text"
android:importantForAccessibility="no"
android:text="@string/desktop_mode_maximize_menu_immersive_button_text"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:alpha="0"/>
</LinearLayout>
@@ -89,7 +89,7 @@
android:fontFamily="google-sans-text"
android:importantForAccessibility="no"
android:text="@string/desktop_mode_maximize_menu_maximize_text"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:alpha="0"/>
</LinearLayout>
@@ -140,7 +140,7 @@
android:importantForAccessibility="no"
android:fontFamily="google-sans-text"
android:text="@string/desktop_mode_maximize_menu_snap_text"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:alpha="0"/>
</LinearLayout>
</LinearLayout>
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
index bda087b..0a44cd4 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
@@ -37,7 +37,7 @@
android:layout_height="wrap_content"
android:lineSpacingExtra="4sp"
android:textAlignment="center"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textSize="14sp"/>
</LinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
index 488123a..cd36983 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
@@ -64,7 +64,7 @@
android:lineSpacingExtra="4sp"
android:text="@string/letterbox_education_dialog_title"
android:textAlignment="center"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:fontFamily="@*android:string/config_headlineFontFamily"
android:textSize="24sp"/>
@@ -104,7 +104,7 @@
android:background=
"@drawable/letterbox_education_dismiss_button_background_ripple"
android:text="@string/letterbox_education_got_it"
- android:textColor="?androidprv:attr/materialColorOnPrimary"
+ android:textColor="@androidprv:color/materialColorOnPrimary"
android:textAlignment="center"
android:contentDescription="@string/letterbox_education_got_it"/>
diff --git a/libs/WindowManager/Shell/res/layout/open_by_default_settings_dialog.xml b/libs/WindowManager/Shell/res/layout/open_by_default_settings_dialog.xml
index b5bceda..f6256e6 100644
--- a/libs/WindowManager/Shell/res/layout/open_by_default_settings_dialog.xml
+++ b/libs/WindowManager/Shell/res/layout/open_by_default_settings_dialog.xml
@@ -64,7 +64,7 @@
android:lineHeight="32dp"
android:textFontWeight="400"
android:textSize="24sp"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
tools:text="Gmail" />
<TextView
@@ -75,7 +75,7 @@
android:lineHeight="16dp"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="16dp"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
android:text="@string/open_by_default_dialog_subheader_text"/>
<RadioGroup
@@ -121,7 +121,7 @@
android:layout_marginBottom="24dp"
android:textSize="14sp"
android:textFontWeight="500"
- android:textColor="?androidprv:attr/materialColorOnPrimary"
+ android:textColor="@androidprv:color/materialColorOnPrimary"
android:background="@drawable/open_by_default_settings_dialog_confirm_button_background"/>
</LinearLayout>
</ScrollView>
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index b7aa158..d754243 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -43,7 +43,7 @@
<color name="compat_controls_text">@android:color/system_neutral1_50</color>
<!-- Letterbox Education -->
- <color name="letterbox_education_text_secondary">?androidprv:attr/materialColorSecondary</color>
+ <color name="letterbox_education_text_secondary">@androidprv:color/materialColorSecondary</color>
<!-- Letterbox Dialog -->
<color name="letterbox_dialog_background">@android:color/system_neutral1_900</color>
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index 597a921..8a4a702 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -48,7 +48,7 @@
<item name="android:paddingEnd">0dp</item>
<item name="android:textSize">14sp</item>
<item name="android:textFontWeight">500</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:drawablePadding">16dp</item>
<item name="android:background">?android:selectableItemBackground</item>
</style>
@@ -92,7 +92,7 @@
<style name="RestartDialogTitleText">
<item name="android:textSize">24sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:lineSpacingExtra">8sp</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
</style>
@@ -104,23 +104,23 @@
<style name="RestartDialogBodyText" parent="RestartDialogBodyStyle">
<item name="android:letterSpacing">0.02</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
<item name="android:lineSpacingExtra">6sp</item>
</style>
<style name="RestartDialogCheckboxText" parent="RestartDialogBodyStyle">
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:lineSpacingExtra">6sp</item>
</style>
<style name="RestartDialogDismissButton" parent="RestartDialogBodyStyle">
<item name="android:lineSpacingExtra">2sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorPrimary</item>
+ <item name="android:textColor">@androidprv:color/materialColorPrimary</item>
</style>
<style name="RestartDialogConfirmButton" parent="RestartDialogBodyStyle">
<item name="android:lineSpacingExtra">2sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnPrimary</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnPrimary</item>
</style>
<style name="ReachabilityEduHandLayout" parent="Theme.AppCompat.Light">
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
index 04c17e5..4c77eaf 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
@@ -91,6 +91,9 @@
/** The maximum override density allowed for tasks inside the desktop. */
private static final int DESKTOP_DENSITY_MAX = 1000;
+ /** The number of [WindowDecorViewHost] instances to warm up on system start. */
+ private static final int WINDOW_DECOR_PRE_WARM_SIZE = 2;
+
/**
* Sysprop declaring whether to enters desktop mode by default when the windowing mode of the
* display's root TaskDisplayArea is set to WINDOWING_MODE_FREEFORM.
@@ -122,6 +125,14 @@
private static final String MAX_TASK_LIMIT_SYS_PROP = "persist.wm.debug.desktop_max_task_limit";
/**
+ * Sysprop declaring the number of [WindowDecorViewHost] instances to warm up on system start.
+ *
+ * <p>If it is not defined, then [WINDOW_DECOR_PRE_WARM_SIZE] is used.
+ */
+ private static final String WINDOW_DECOR_PRE_WARM_SIZE_SYS_PROP =
+ "persist.wm.debug.desktop_window_decor_pre_warm_size";
+
+ /**
* Return {@code true} if veiled resizing is active. If false, fluid resizing is used.
*/
public static boolean isVeiledResizeEnabled() {
@@ -162,6 +173,27 @@
}
/**
+ * Return the maximum size of the window decoration surface control view host pool, or zero if
+ * there should be no pooling.
+ */
+ public static int getWindowDecorScvhPoolSize(@NonNull Context context) {
+ if (!Flags.enableDesktopWindowingScvhCacheBugFix()) return 0;
+ final int maxTaskLimit = getMaxTaskLimit(context);
+ if (maxTaskLimit > 0) {
+ return maxTaskLimit;
+ }
+ // TODO: b/368032552 - task limit equal to 0 means unlimited. Figure out what the pool
+ // size should be in that case.
+ return 0;
+ }
+
+ /** The number of [WindowDecorViewHost] instances to warm up on system start. */
+ public static int getWindowDecorPreWarmSize() {
+ return SystemProperties.getInt(WINDOW_DECOR_PRE_WARM_SIZE_SYS_PROP,
+ WINDOW_DECOR_PRE_WARM_SIZE);
+ }
+
+ /**
* Return {@code true} if the current device supports desktop mode.
*/
@VisibleForTesting
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index d2cef4b..f269b38 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -268,10 +268,7 @@
final Animation animation =
animationProvider.get(info, change, openingWholeScreenBounds);
if (shouldUseJumpCutForAnimation(animation)) {
- if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- return new ArrayList<>();
- }
- continue;
+ return new ArrayList<>();
}
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
info, change, animation, openingWholeScreenBounds);
@@ -296,10 +293,7 @@
final Animation animation =
animationProvider.get(info, change, closingWholeScreenBounds);
if (shouldUseJumpCutForAnimation(animation)) {
- if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- return new ArrayList<>();
- }
- continue;
+ return new ArrayList<>();
}
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
info, change, animation, closingWholeScreenBounds);
@@ -455,11 +449,9 @@
final Animation[] animations =
mAnimationSpec.createChangeBoundsChangeAnimations(info, change, parentBounds);
// Jump cut if either animation has zero for duration.
- if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- for (Animation animation : animations) {
- if (shouldUseJumpCutForAnimation(animation)) {
- return new ArrayList<>();
- }
+ for (Animation animation : animations) {
+ if (shouldUseJumpCutForAnimation(animation)) {
+ return new ArrayList<>();
}
}
// Keep track as we might need to add background color for the animation.
@@ -516,10 +508,8 @@
mAnimationSpec.createChangeBoundsOpenAnimation(info, change, parentBounds);
shouldShowBackgroundColor = false;
}
- if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- if (shouldUseJumpCutForAnimation(animation)) {
- return new ArrayList<>();
- }
+ if (shouldUseJumpCutForAnimation(animation)) {
+ return new ArrayList<>();
}
adapters.add(new ActivityEmbeddingAnimationAdapter(animation, change,
TransitionUtil.getRootFor(change, info)));
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
index 3046307..77799e9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
@@ -96,11 +96,9 @@
@NonNull
Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
- if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
- if (customAnimation != null) {
- return customAnimation;
- }
+ final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
+ if (customAnimation != null) {
+ return customAnimation;
}
// Use end bounds for opening.
final Rect bounds = change.getEndAbsBounds();
@@ -130,11 +128,9 @@
@NonNull
Animation createChangeBoundsCloseAnimation(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
- if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
- if (customAnimation != null) {
- return customAnimation;
- }
+ final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
+ if (customAnimation != null) {
+ return customAnimation;
}
// Use start bounds for closing.
final Rect bounds = change.getStartAbsBounds();
@@ -168,14 +164,12 @@
@NonNull
Animation[] createChangeBoundsChangeAnimations(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
- if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- // TODO(b/293658614): Support more complicated animations that may need more than a noop
- // animation as the start leash.
- final Animation noopAnimation = createNoopAnimation(change);
- final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
- if (customAnimation != null) {
- return new Animation[]{noopAnimation, customAnimation};
- }
+ // TODO(b/293658614): Support more complicated animations that may need more than a noop
+ // animation as the start leash.
+ final Animation noopAnimation = createNoopAnimation(change);
+ final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
+ if (customAnimation != null) {
+ return new Animation[]{noopAnimation, customAnimation};
}
// Both start bounds and end bounds are in screen coordinates. We will post translate
// to the local coordinates in ActivityEmbeddingAnimationAdapter#onAnimationUpdate
@@ -320,13 +314,9 @@
}
final Animation anim;
- if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
- // TODO(b/293658614): Consider allowing custom animations from non-default packages.
- // Enforce limiting to animations from the default "android" package for now.
- anim = mTransitionAnimation.loadDefaultAnimationRes(resId);
- } else {
- anim = mTransitionAnimation.loadAnimationRes(options.getPackageName(), resId);
- }
+ // TODO(b/293658614): Consider allowing custom animations from non-default packages.
+ // Enforce limiting to animations from the default "android" package for now.
+ anim = mTransitionAnimation.loadDefaultAnimationRes(resId);
if (anim != null) {
return anim;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index c024840..60a52a8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -214,6 +214,10 @@
}
ProtoLog.i(WM_SHELL_BACK_PREVIEW, "Navigation window gone.");
setTriggerBack(false);
+ // Trigger close transition if necessary.
+ if (Flags.migratePredictiveBackTransition()) {
+ mBackTransitionHandler.onAnimationFinished();
+ }
resetTouchTracker();
// Don't wait for animation start
mShellExecutor.removeCallbacks(mAnimationTimeoutRunnable);
@@ -731,6 +735,8 @@
callback.onBackStarted(backEvent);
if (mBackTransitionHandler.canHandOffAnimation()) {
callback.setHandoffHandler(mHandoffHandler);
+ } else {
+ callback.setHandoffHandler(null);
}
mOnBackStartDispatched = true;
} catch (RemoteException e) {
@@ -1273,14 +1279,6 @@
@NonNull SurfaceControl.Transaction st,
@NonNull SurfaceControl.Transaction ft,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
- final boolean isPrepareTransition =
- info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION;
- if (isPrepareTransition) {
- if (checkTakeoverFlags()) {
- mTakeoverHandler = mTransitions.getHandlerForTakeover(transition, info);
- }
- kickStartAnimation();
- }
// Both mShellExecutor and Transitions#mMainExecutor are ShellMainThread, so we don't
// need to post to ShellExecutor when called.
if (info.getType() == WindowManager.TRANSIT_CLOSE_PREPARE_BACK_NAVIGATION) {
@@ -1308,7 +1306,8 @@
// animation never start, consume directly
applyAndFinish(st, ft, finishCallback);
return true;
- } else if (mClosePrepareTransition == null && isPrepareTransition) {
+ } else if (mClosePrepareTransition == null
+ && info.getType() == WindowManager.TRANSIT_PREPARE_BACK_NAVIGATION) {
// Gesture animation was cancelled before prepare transition ready, create
// the close prepare transition
createClosePrepareTransition();
@@ -1316,6 +1315,10 @@
}
if (handlePrepareTransition(info, st, ft, finishCallback)) {
+ if (checkTakeoverFlags()) {
+ mTakeoverHandler = mTransitions.getHandlerForTakeover(transition, info);
+ }
+ kickStartAnimation();
return true;
}
return handleCloseTransition(info, st, ft, finishCallback);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index 5295526..47032fd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -38,7 +38,6 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
-import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Outline;
import android.graphics.Paint;
@@ -543,15 +542,15 @@
void applyThemeAttrs() {
final TypedArray ta = mContext.obtainStyledAttributes(new int[]{
- android.R.attr.dialogCornerRadius,
- com.android.internal.R.attr.materialColorSurfaceBright,
- com.android.internal.R.attr.materialColorSurfaceContainerHigh});
+ android.R.attr.dialogCornerRadius});
boolean supportsRoundedCorners = ScreenDecorationsUtils.supportsRoundedCornersOnWindows(
mContext.getResources());
mCornerRadius = supportsRoundedCorners ? ta.getDimensionPixelSize(0, 0) : 0;
- mBackgroundColorFloating = ta.getColor(1, Color.WHITE);
+ mBackgroundColorFloating = mContext.getColor(
+ com.android.internal.R.color.materialColorSurfaceBright);
mExpandedViewContainer.setBackgroundColor(mBackgroundColorFloating);
- final int manageMenuBg = ta.getColor(2, Color.WHITE);
+ final int manageMenuBg = mContext.getColor(
+ com.android.internal.R.color.materialColorSurfaceContainerHigh);
ta.recycle();
if (mManageButton != null) {
mManageButton.getBackground().setColorFilter(manageMenuBg, PorterDuff.Mode.SRC_IN);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
index 1711dca..da6948d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
@@ -28,7 +28,6 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
@@ -209,7 +208,7 @@
mPointerSize, mPointerSize, false /* isPointingLeft */));
mRightTriangleShape.setBounds(0, 0, mPointerSize, mPointerSize);
- applyConfigurationColors(getResources().getConfiguration());
+ applyConfigurationColors();
}
@Override
@@ -440,29 +439,23 @@
boolean flagsChanged = nightModeFlags != mNightModeFlags;
if (flagsChanged) {
mNightModeFlags = nightModeFlags;
- applyConfigurationColors(configuration);
+ applyConfigurationColors();
}
return flagsChanged;
}
- private void applyConfigurationColors(Configuration configuration) {
- int nightModeFlags = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
- boolean isNightModeOn = nightModeFlags == Configuration.UI_MODE_NIGHT_YES;
- try (TypedArray ta = mContext.obtainStyledAttributes(
- new int[]{
- com.android.internal.R.attr.materialColorSurfaceContainer,
- com.android.internal.R.attr.materialColorOnSurface,
- com.android.internal.R.attr.materialColorOnSurfaceVariant})) {
- mFloatingBackgroundColor = ta.getColor(0,
- isNightModeOn ? Color.BLACK : Color.WHITE);
- mSenderText.setTextColor(ta.getColor(1,
- isNightModeOn ? Color.WHITE : Color.BLACK));
- mMessageText.setTextColor(ta.getColor(2,
- isNightModeOn ? Color.WHITE : Color.BLACK));
- mBgPaint.setColor(mFloatingBackgroundColor);
- mLeftTriangleShape.getPaint().setColor(mFloatingBackgroundColor);
- mRightTriangleShape.getPaint().setColor(mFloatingBackgroundColor);
- }
+ private void applyConfigurationColors() {
+ mFloatingBackgroundColor = mContext.getColor(
+ com.android.internal.R.color.materialColorSurfaceContainer);
+ mSenderText.setTextColor(
+ mContext.getColor(com.android.internal.R.color.materialColorOnSurface));
+ mMessageText.setTextColor(
+ mContext.getColor(com.android.internal.R.color.materialColorOnSurfaceVariant));
+
+ mBgPaint.setColor(mFloatingBackgroundColor);
+ mLeftTriangleShape.getPaint().setColor(mFloatingBackgroundColor);
+ mRightTriangleShape.getPaint().setColor(mFloatingBackgroundColor);
+
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
index c74412b..862906a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
@@ -19,7 +19,6 @@
import android.app.ActivityTaskManager.INVALID_TASK_ID
import android.content.Context
import android.graphics.Bitmap
-import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Path
import android.graphics.drawable.AdaptiveIconDrawable
@@ -117,18 +116,8 @@
val res = context.resources
// Set overflow button accent color, dot color
-
- val typedArray =
- context.obtainStyledAttributes(
- intArrayOf(
- com.android.internal.R.attr.materialColorPrimaryFixed,
- com.android.internal.R.attr.materialColorOnPrimaryFixed
- )
- )
-
- val colorAccent = typedArray.getColor(0, Color.WHITE)
- val shapeColor = typedArray.getColor(1, Color.BLACK)
- typedArray.recycle()
+ val colorAccent = context.getColor(com.android.internal.R.color.materialColorPrimaryFixed)
+ val shapeColor = context.getColor(com.android.internal.R.color.materialColorOnPrimaryFixed)
dotColor = colorAccent
overflowBtn?.iconDrawable?.setTint(shapeColor)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
index bf98ef8..64f54b8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
@@ -226,13 +226,11 @@
? res.getColor(R.color.bubbles_dark)
: res.getColor(R.color.bubbles_light));
- final TypedArray typedArray = getContext().obtainStyledAttributes(new int[] {
- com.android.internal.R.attr.materialColorSurfaceBright,
- com.android.internal.R.attr.materialColorOnSurface});
- int bgColor = typedArray.getColor(0, isNightMode ? Color.BLACK : Color.WHITE);
- int textColor = typedArray.getColor(1, isNightMode ? Color.WHITE : Color.BLACK);
- textColor = ContrastColorUtil.ensureTextContrast(textColor, bgColor, isNightMode);
- typedArray.recycle();
+
+ int bgColor = getContext().getColor(
+ com.android.internal.R.color.materialColorSurfaceBright);
+ int textColor = getContext().getColor(com.android.internal.R.color.materialColorOnSurface);
+
setBackgroundColor(bgColor);
mEmptyStateTitle.setTextColor(textColor);
mEmptyStateSubtitle.setTextColor(textColor);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt
index 9b3054e..a65466f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePopupViewExt.kt
@@ -15,7 +15,6 @@
*/
package com.android.wm.shell.bubbles
-import android.graphics.Color
import com.android.wm.shell.R
import com.android.wm.shell.shared.bubbles.BubblePopupDrawable
import com.android.wm.shell.shared.bubbles.BubblePopupView
@@ -27,7 +26,6 @@
val attrs =
context.obtainStyledAttributes(
intArrayOf(
- com.android.internal.R.attr.materialColorSurfaceContainer,
android.R.attr.dialogCornerRadius
)
)
@@ -35,8 +33,8 @@
val res = context.resources
val config =
BubblePopupDrawable.Config(
- color = attrs.getColor(0, Color.WHITE),
- cornerRadius = attrs.getDimension(1, 0f),
+ color = context.getColor(com.android.internal.R.color.materialColorSurfaceContainer),
+ cornerRadius = attrs.getDimension(0, 0f),
contentPadding = res.getDimensionPixelSize(R.dimen.bubble_popup_padding),
arrowWidth = res.getDimension(R.dimen.bubble_popup_arrow_width),
arrowHeight = res.getDimension(R.dimen.bubble_popup_arrow_height),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 0fd4206..de85d9a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -163,8 +163,11 @@
mExpandedViewLargeScreenWidth = (int) (bounds.width()
* EXPANDED_VIEW_SMALL_TABLET_WIDTH_PERCENT);
} else {
- mExpandedViewLargeScreenWidth =
- res.getDimensionPixelSize(R.dimen.bubble_expanded_view_largescreen_width);
+ int expandedViewLargeScreenSpacing = res.getDimensionPixelSize(
+ R.dimen.bubble_expanded_view_largescreen_landscape_padding);
+ mExpandedViewLargeScreenWidth = Math.min(
+ res.getDimensionPixelSize(R.dimen.bubble_expanded_view_largescreen_width),
+ bounds.width() - expandedViewLargeScreenSpacing * 2);
}
if (mDeviceConfig.isLargeScreen()) {
if (mDeviceConfig.isSmallTablet()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 88f55b8..249a218 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -40,7 +40,6 @@
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.PointF;
import android.graphics.PorterDuff;
@@ -1326,10 +1325,9 @@
R.layout.bubble_manage_menu, this, false);
mManageMenu.setVisibility(View.INVISIBLE);
- final TypedArray ta = mContext.obtainStyledAttributes(new int[]{
- com.android.internal.R.attr.materialColorSurfaceBright});
- final int menuBackgroundColor = ta.getColor(0, Color.WHITE);
- ta.recycle();
+ final int menuBackgroundColor = mContext.getColor(
+ com.android.internal.R.color.materialColorSurfaceBright);
+
mManageMenu.getBackground().setColorFilter(menuBackgroundColor, PorterDuff.Mode.SRC_IN);
PhysicsAnimator.getInstance(mManageMenu).setDefaultSpringConfig(mManageSpringConfig);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
index 4d7c7fa..3e8a9b6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
@@ -272,6 +272,7 @@
final float startTx = getSwitchAnimationInitialTx(endTx);
toBbev.setTranslationX(startTx);
toBbev.getHandleView().setAlpha(0f);
+ toBbev.getHandleView().setHandleInitialColor(fromBbev.getHandleView().getHandleColor());
toBbev.animateExpansionWhenTaskViewVisible(() -> {
AnimatorSet switchAnim = new AnimatorSet();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index 2c0483c..65c929a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -606,6 +606,11 @@
mTaskView.setZOrderedOnTop(onTop, true /* allowDynamicChange */);
}
+ @VisibleForTesting
+ boolean isSurfaceZOrderedOnTop() {
+ return mTaskView != null && mTaskView.isZOrderedOnTop();
+ }
+
/**
* Sets whether the view is animating, in this case we won't change the content visibility
* until the animation is done.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
index 712e41b..9cf0d2d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleView.java
@@ -65,6 +65,7 @@
@Nullable
private ObjectAnimator mColorChangeAnim;
private @ColorInt int mRegionSamplerColor;
+ private boolean mHasSampledColor;
public BubbleBarHandleView(Context context) {
this(context, null /* attrs */);
@@ -102,7 +103,11 @@
invalidate();
}
- private int getHandleColor() {
+ /**
+ * Get current color value for the handle
+ */
+ @ColorInt
+ public int getHandleColor() {
return mHandlePaint.getColor();
}
@@ -128,6 +133,16 @@
}
/**
+ * Set initial color for the handle. Takes effect if the
+ * {@link #updateHandleColor(boolean, boolean)} has not been called.
+ */
+ public void setHandleInitialColor(@ColorInt int color) {
+ if (!mHasSampledColor) {
+ setHandleColor(color);
+ }
+ }
+
+ /**
* Updates the handle color.
*
* @param isRegionDark Whether the background behind the handle is dark, and thus the handle
@@ -139,6 +154,7 @@
if (newColor == mRegionSamplerColor) {
return;
}
+ mHasSampledColor = true;
mRegionSamplerColor = newColor;
if (mColorChangeAnim != null) {
mColorChangeAnim.cancel();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java
index 1c71ef4..6c14d83 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java
@@ -17,7 +17,6 @@
import android.annotation.ColorInt;
import android.content.Context;
-import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Icon;
import android.util.AttributeSet;
@@ -63,9 +62,8 @@
*/
void update(Icon icon, String title, @ColorInt int tint) {
if (tint == Color.TRANSPARENT) {
- final TypedArray typedArray = getContext().obtainStyledAttributes(
- new int[]{com.android.internal.R.attr.materialColorOnSurface});
- mTextView.setTextColor(typedArray.getColor(0, Color.BLACK));
+ mTextView.setTextColor(
+ getContext().getColor(com.android.internal.R.color.materialColorOnSurface));
} else {
icon.setTint(tint);
mTextView.setTextColor(tint);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
index 99e2009..dfbf655 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
@@ -18,7 +18,6 @@
import android.annotation.ColorInt;
import android.content.Context;
import android.content.res.ColorStateList;
-import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Icon;
import android.util.AttributeSet;
@@ -91,14 +90,11 @@
}
private void updateThemeColors() {
- try (TypedArray ta = mContext.obtainStyledAttributes(new int[]{
- com.android.internal.R.attr.materialColorSurfaceBright,
- com.android.internal.R.attr.materialColorOnSurface
- })) {
- mActionsSectionView.getBackground().setTint(ta.getColor(0, Color.WHITE));
- ImageViewCompat.setImageTintList(mBubbleDismissIconView,
- ColorStateList.valueOf(ta.getColor(1, Color.BLACK)));
- }
+ mActionsSectionView.getBackground().setTint(
+ mContext.getColor(com.android.internal.R.color.materialColorSurfaceBright));
+ ImageViewCompat.setImageTintList(mBubbleDismissIconView,
+ ColorStateList.valueOf(
+ mContext.getColor(com.android.internal.R.color.materialColorOnSurface)));
}
/** Animates the menu from the specified start scale. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
index 9dd0cae..5f437d4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
@@ -22,8 +22,6 @@
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Color;
import android.graphics.drawable.Icon;
import android.view.LayoutInflater;
import android.view.View;
@@ -169,12 +167,7 @@
int handleHeight = mHandleView.getHandleHeight();
float targetWidth = mHandleView.getHandleWidth() + widthDiff * WIDTH_SWAP_FRACTION;
float targetHeight = targetWidth * mMenuView.getTitleItemHeight() / mMenuView.getWidth();
- int menuColor;
- try (TypedArray ta = mContext.obtainStyledAttributes(new int[]{
- com.android.internal.R.attr.materialColorSurfaceBright,
- })) {
- menuColor = ta.getColor(0, Color.WHITE);
- }
+ int menuColor = mContext.getColor(com.android.internal.R.color.materialColorSurfaceBright);
// Calculating deltas
float swapScale = targetWidth / mMenuView.getWidth();
float handleWidthDelta = targetWidth - mHandleView.getHandleWidth();
@@ -227,11 +220,8 @@
private ArrayList<BubbleBarMenuView.MenuAction> createMenuActions(Bubble bubble) {
ArrayList<BubbleBarMenuView.MenuAction> menuActions = new ArrayList<>();
Resources resources = mContext.getResources();
- int tintColor;
- try (TypedArray ta = mContext.obtainStyledAttributes(new int[]{
- com.android.internal.R.attr.materialColorOnSurface})) {
- tintColor = ta.getColor(0, Color.TRANSPARENT);
- }
+ int tintColor = mContext.getColor(com.android.internal.R.color.materialColorOnSurface);
+
if (bubble.isConversation()) {
// Don't bubble conversation action
menuActions.add(new BubbleBarMenuView.MenuAction(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/BoostExecutor.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/BoostExecutor.kt
new file mode 100644
index 0000000..498d0e4
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/BoostExecutor.kt
@@ -0,0 +1,47 @@
+/*
+ * 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.common
+
+import android.os.Looper
+import java.util.concurrent.Executor
+
+/** Executor implementation which can be boosted temporarily to a different thread priority. */
+interface BoostExecutor : Executor {
+ /**
+ * Requests that the executor is boosted until {@link #resetBoost()} is called.
+ */
+ fun setBoost() {}
+
+ /**
+ * Requests that the executor is not boosted (only resets if there are no other boost requests
+ * in progress).
+ */
+ fun resetBoost() {}
+
+ /**
+ * Returns whether the executor is boosted.
+ */
+ fun isBoosted() : Boolean {
+ return false
+ }
+
+ /**
+ * Returns the looper for this executor.
+ */
+ fun getLooper() : Looper? {
+ return Looper.myLooper()
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index ec3c0b8..5129d83 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -414,9 +414,14 @@
// already (e.g., when focussing an editText in activity B, while and editText in
// activity A is focussed), we will not get a call of #insetsControlChanged, and
// therefore have to start the show animation from here
- startAnimation(mImeRequestedVisible /* show */, false /* forceRestart */);
+ startAnimation(mImeRequestedVisible /* show */, false /* forceRestart */,
+ statsToken);
- setVisibleDirectly(mImeRequestedVisible || mAnimation != null, statsToken);
+ // In case of a hide, the statsToken should not been send yet (as the animation
+ // is still ongoing). It will be sent at the end of the animation
+ boolean hideAnimOngoing = !mImeRequestedVisible && mAnimation != null;
+ setVisibleDirectly(mImeRequestedVisible || mAnimation != null,
+ hideAnimOngoing ? null : statsToken);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java
index 736d954..803f16c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java
@@ -16,15 +16,50 @@
package com.android.wm.shell.common;
+import static android.os.Process.THREAD_PRIORITY_DEFAULT;
+import static android.os.Process.setThreadPriority;
+
import android.annotation.NonNull;
import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+
+import androidx.annotation.VisibleForTesting;
+
+import java.util.function.BiConsumer;
/** Executor implementation which is backed by a Handler. */
public class HandlerExecutor implements ShellExecutor {
+ @NonNull
private final Handler mHandler;
+ // See android.os.Process#THREAD_PRIORITY_*
+ private final int mDefaultThreadPriority;
+ private final int mBoostedThreadPriority;
+ // Number of current requests to boost thread priority
+ private int mBoostCount;
+ private final Object mBoostLock = new Object();
+ // Default function for setting thread priority (tid, priority)
+ private BiConsumer<Integer, Integer> mSetThreadPriorityFn =
+ HandlerExecutor::setThreadPriorityInternal;
public HandlerExecutor(@NonNull Handler handler) {
+ this(handler, THREAD_PRIORITY_DEFAULT, THREAD_PRIORITY_DEFAULT);
+ }
+
+ /**
+ * Used only if this executor can be boosted, if so, it can be boosted to the given
+ * {@param boostPriority}.
+ */
+ public HandlerExecutor(@NonNull Handler handler, int defaultThreadPriority,
+ int boostedThreadPriority) {
mHandler = handler;
+ mDefaultThreadPriority = defaultThreadPriority;
+ mBoostedThreadPriority = boostedThreadPriority;
+ }
+
+ @VisibleForTesting
+ void replaceSetThreadPriorityFn(BiConsumer<Integer, Integer> setThreadPriorityFn) {
+ mSetThreadPriorityFn = setThreadPriorityFn;
}
@Override
@@ -56,9 +91,54 @@
}
@Override
+ public void setBoost() {
+ synchronized (mBoostLock) {
+ if (mDefaultThreadPriority == mBoostedThreadPriority) {
+ // Nothing to boost
+ return;
+ }
+ if (mBoostCount == 0) {
+ mSetThreadPriorityFn.accept(
+ ((HandlerThread) mHandler.getLooper().getThread()).getThreadId(),
+ mBoostedThreadPriority);
+ }
+ mBoostCount++;
+ }
+ }
+
+ @Override
+ public void resetBoost() {
+ synchronized (mBoostLock) {
+ mBoostCount--;
+ if (mBoostCount == 0) {
+ mSetThreadPriorityFn.accept(
+ ((HandlerThread) mHandler.getLooper().getThread()).getThreadId(),
+ mDefaultThreadPriority);
+ }
+ }
+ }
+
+ @Override
+ public boolean isBoosted() {
+ synchronized (mBoostLock) {
+ return mBoostCount > 0;
+ }
+ }
+
+ @Override
+ @NonNull
+ public Looper getLooper() {
+ return mHandler.getLooper();
+ }
+
+ @Override
public void assertCurrentThread() {
if (!mHandler.getLooper().isCurrentThread()) {
throw new IllegalStateException("must be called on " + mHandler);
}
}
+
+ private static void setThreadPriorityInternal(Integer tid, Integer priority) {
+ setThreadPriority(tid, priority);
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java
index 2c2961f..9e5071e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java
@@ -18,15 +18,15 @@
import java.lang.reflect.Array;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
/**
* Super basic Executor interface that adds support for delayed execution and removing callbacks.
- * Intended to wrap Handler while better-supporting testing.
+ * Intended to wrap Handler while better-supporting testing. Not every ShellExecutor implementation
+ * may support boosting.
*/
-public interface ShellExecutor extends Executor {
+public interface ShellExecutor extends BoostExecutor {
/**
* Executes the given runnable. If the caller is running on the same looper as this executor,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 1852cda..e6b6ef7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -1560,7 +1560,9 @@
final int imeTargetPosition = getImeTargetPosition();
mHasImeFocus = imeTargetPosition != SPLIT_POSITION_UNDEFINED;
if (!mHasImeFocus) {
- return 0;
+ if (!android.view.inputmethod.Flags.refactorInsetsController() || showing) {
+ return 0;
+ }
}
mStartImeTop = showing ? hiddenTop : shownTop;
@@ -1613,7 +1615,11 @@
@Override
public void onImePositionChanged(int displayId, int imeTop, SurfaceControl.Transaction t) {
- if (displayId != mDisplayId || !mHasImeFocus) return;
+ if (displayId != mDisplayId || !mHasImeFocus) {
+ if (!android.view.inputmethod.Flags.refactorInsetsController() || mImeShown) {
+ return;
+ }
+ }
onProgress(getProgress(imeTop));
mSplitLayoutHandler.onLayoutPositionChanging(SplitLayout.this);
}
@@ -1621,7 +1627,12 @@
@Override
public void onImeEndPositioning(int displayId, boolean cancel,
SurfaceControl.Transaction t) {
- if (displayId != mDisplayId || !mHasImeFocus || cancel) return;
+ if (displayId != mDisplayId || cancel) return;
+ if (!mHasImeFocus) {
+ if (!android.view.inputmethod.Flags.refactorInsetsController() || mImeShown) {
+ return;
+ }
+ }
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
"Split IME animation ending, canceled=%b", cancel);
onProgress(1.0f);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxUtils.kt
index ef964f4..8e149ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxUtils.kt
@@ -66,3 +66,41 @@
other.dump()
}
}
+
+object LetterboxUtils {
+ // Utility methods about Maps usage in Letterbox.
+ object Maps {
+ /*
+ * Executes [onFound] on the [item] for a given [key] if present or
+ * [onMissed] if the [key] is not present.
+ */
+ fun <V, K> MutableMap<K, V>.runOnItem(
+ key: K,
+ onFound: (V) -> Unit = { _ -> },
+ onMissed: (
+ K,
+ MutableMap<K, V>
+ ) -> Unit = { _, _ -> }
+ ) {
+ this[key]?.let {
+ return onFound(it)
+ }
+ return onMissed(key, this)
+ }
+ }
+
+ // Utility methods about Transaction usage in Letterbox.
+ object Transactions {
+ // Sets position and crops in one method.
+ fun Transaction.moveAndCrop(
+ surface: SurfaceControl,
+ rect: Rect
+ ): Transaction =
+ setPosition(surface, rect.left.toFloat(), rect.top.toFloat())
+ .setWindowCrop(
+ surface,
+ rect.width(),
+ rect.height()
+ )
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/MultiSurfaceLetterboxController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/MultiSurfaceLetterboxController.kt
index 5129d03..6861aa3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/MultiSurfaceLetterboxController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/MultiSurfaceLetterboxController.kt
@@ -20,6 +20,8 @@
import android.view.SurfaceControl
import android.view.SurfaceControl.Transaction
import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Maps.runOnItem
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Transactions.moveAndCrop
import com.android.wm.shell.dagger.WMSingleton
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_APP_COMPAT
import javax.inject.Inject
@@ -101,23 +103,6 @@
ProtoLog.v(WM_SHELL_APP_COMPAT, "%s: %s", TAG, "${letterboxMap.keys}")
}
- /*
- * Executes [onFound] on the [LetterboxItem] if present or [onMissed] if not present.
- */
- private fun MutableMap<LetterboxKey, LetterboxSurfaces>.runOnItem(
- key: LetterboxKey,
- onFound: (LetterboxSurfaces) -> Unit = { _ -> },
- onMissed: (
- LetterboxKey,
- MutableMap<LetterboxKey, LetterboxSurfaces>
- ) -> Unit = { _, _ -> }
- ) {
- this[key]?.let {
- return onFound(it)
- }
- return onMissed(key, this)
- }
-
private fun SurfaceControl?.remove(
tx: Transaction
) = this?.let {
@@ -131,17 +116,6 @@
tx.setVisibility(this, visible)
}
- private fun Transaction.moveAndCrop(
- surface: SurfaceControl,
- rect: Rect
- ): Transaction =
- setPosition(surface, rect.left.toFloat(), rect.top.toFloat())
- .setWindowCrop(
- surface,
- rect.width(),
- rect.height()
- )
-
private fun LetterboxSurfaces.updateSurfacesBounds(
tx: Transaction,
taskBounds: Rect,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxController.kt
index a67f608..8e1cdee 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/SingleSurfaceLetterboxController.kt
@@ -20,6 +20,8 @@
import android.view.SurfaceControl
import android.view.SurfaceControl.Transaction
import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Maps.runOnItem
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Transactions.moveAndCrop
import com.android.wm.shell.dagger.WMSingleton
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_APP_COMPAT
import javax.inject.Inject
@@ -106,32 +108,4 @@
override fun dump() {
ProtoLog.v(WM_SHELL_APP_COMPAT, "%s: %s", TAG, "${letterboxMap.keys}")
}
-
- /*
- * Executes [onFound] on the [SurfaceControl] if present or [onMissed] if not present.
- */
- private fun MutableMap<LetterboxKey, SurfaceControl>.runOnItem(
- key: LetterboxKey,
- onFound: (SurfaceControl) -> Unit = { _ -> },
- onMissed: (
- LetterboxKey,
- MutableMap<LetterboxKey, SurfaceControl>
- ) -> Unit = { _, _ -> }
- ) {
- this[key]?.let {
- return onFound(it)
- }
- return onMissed(key, this)
- }
-
- private fun Transaction.moveAndCrop(
- surface: SurfaceControl,
- rect: Rect
- ): Transaction =
- setPosition(surface, rect.left.toFloat(), rect.top.toFloat())
- .setWindowCrop(
- surface,
- rect.width(),
- rect.height()
- )
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java
index c5644a8..d7ddbde 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java
@@ -18,6 +18,7 @@
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
import static android.os.Process.THREAD_PRIORITY_DISPLAY;
+import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST;
import android.content.Context;
@@ -205,13 +206,14 @@
}
/**
- * Provides a Shell background thread Executor for low priority background tasks.
+ * Provides a Shell background thread Executor for low priority background tasks. The thread
+ * may also be boosted to THREAD_PRIORITY_FOREGROUND if necessary.
*/
@WMSingleton
@Provides
@ShellBackgroundThread
public static ShellExecutor provideSharedBackgroundExecutor(
@ShellBackgroundThread Handler handler) {
- return new HandlerExecutor(handler);
+ return new HandlerExecutor(handler, THREAD_PRIORITY_BACKGROUND, THREAD_PRIORITY_FOREGROUND);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 86e0d08..0cd0f4a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -152,6 +152,7 @@
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer;
import com.android.wm.shell.windowdecor.common.viewhost.DefaultWindowDecorViewHostSupplier;
+import com.android.wm.shell.windowdecor.common.viewhost.PooledWindowDecorViewHostSupplier;
import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost;
import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier;
import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationPromoController;
@@ -347,7 +348,15 @@
@WMSingleton
@Provides
static WindowDecorViewHostSupplier<WindowDecorViewHost> provideWindowDecorViewHostSupplier(
- @ShellMainThread @NonNull CoroutineScope mainScope) {
+ @NonNull Context context,
+ @ShellMainThread @NonNull CoroutineScope mainScope,
+ @NonNull ShellInit shellInit) {
+ final int poolSize = DesktopModeStatus.getWindowDecorScvhPoolSize(context);
+ final int preWarmSize = DesktopModeStatus.getWindowDecorPreWarmSize();
+ if (DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context) && poolSize > 0) {
+ return new PooledWindowDecorViewHostSupplier(
+ context, mainScope, shellInit, poolSize, preWarmSize);
+ }
return new DefaultWindowDecorViewHostSupplier(mainScope);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
index 7764688..50187d5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt
@@ -77,6 +77,10 @@
override fun startMinimizedModeTransition(wct: WindowContainerTransaction?): IBinder =
freeformTaskTransitionHandler.startMinimizedModeTransition(wct)
+ /** Delegates starting PiP transition to [FreeformTaskTransitionHandler]. */
+ override fun startPipTransition(wct: WindowContainerTransaction?): IBinder =
+ freeformTaskTransitionHandler.startPipTransition(wct)
+
/** Starts close transition and handles or delegates desktop task close animation. */
override fun startRemoveTransition(wct: WindowContainerTransaction?): IBinder {
if (
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
index 80d8ecc..cd37113 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -53,6 +53,7 @@
import androidx.annotation.VisibleForTesting;
import com.android.internal.policy.SystemBarUtils;
+import com.android.window.flags.Flags;
import com.android.wm.shell.R;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.common.DisplayController;
@@ -245,9 +246,17 @@
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
final Resources resources = mContext.getResources();
final DisplayMetrics metrics = resources.getDisplayMetrics();
- final int screenWidth = metrics.widthPixels;
- final int screenHeight = metrics.heightPixels;
-
+ final int screenWidth;
+ final int screenHeight;
+ if (Flags.enableBugFixesForSecondaryDisplay()) {
+ final DisplayLayout displayLayout =
+ mDisplayController.getDisplayLayout(mTaskInfo.displayId);
+ screenWidth = displayLayout.width();
+ screenHeight = displayLayout.height();
+ } else {
+ screenWidth = metrics.widthPixels;
+ screenHeight = metrics.heightPixels;
+ }
mView = new View(mContext);
final SurfaceControl.Builder builder = new SurfaceControl.Builder();
mRootTdaOrganizer.attachToDisplayArea(mTaskInfo.displayId, builder);
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 d5a2a40..9a1abd5 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
@@ -50,6 +50,7 @@
import android.view.WindowManager.TRANSIT_CLOSE
import android.view.WindowManager.TRANSIT_NONE
import android.view.WindowManager.TRANSIT_OPEN
+import android.view.WindowManager.TRANSIT_PIP
import android.view.WindowManager.TRANSIT_TO_FRONT
import android.widget.Toast
import android.window.DesktopModeFlags
@@ -220,6 +221,7 @@
// Launch cookie used to identify a drag and drop transition to fullscreen after it has begun.
// Used to prevent handleRequest from moving the new fullscreen task to freeform.
private var dragAndDropFullscreenCookie: Binder? = null
+ private var pendingPipTransitionAndTask: Pair<IBinder, Int>? = null
init {
desktopMode = DesktopModeImpl()
@@ -361,8 +363,15 @@
}
val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)
- requireNotNull(tdaInfo) {
- "This method can only be called with the ID of a display having non-null DisplayArea."
+ // A non-organized display (e.g., non-trusted virtual displays used in CTS) doesn't have
+ // TDA.
+ if (tdaInfo == null) {
+ logW(
+ "forceEnterDesktop cannot find DisplayAreaInfo for displayId=%d. This could happen" +
+ " when the display is a non-trusted virtual display.",
+ displayId,
+ )
+ return false
}
val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode
val isFreeformDisplay = tdaWindowingMode == WINDOWING_MODE_FREEFORM
@@ -374,12 +383,13 @@
taskId: Int,
wct: WindowContainerTransaction = WindowContainerTransaction(),
transitionSource: DesktopModeTransitionSource,
+ remoteTransition: RemoteTransition? = null,
): Boolean {
val runningTask = shellTaskOrganizer.getRunningTaskInfo(taskId)
if (runningTask == null) {
- return moveBackgroundTaskToDesktop(taskId, wct, transitionSource)
+ return moveBackgroundTaskToDesktop(taskId, wct, transitionSource, remoteTransition)
}
- moveRunningTaskToDesktop(runningTask, wct, transitionSource)
+ moveRunningTaskToDesktop(runningTask, wct, transitionSource, remoteTransition)
return true
}
@@ -387,6 +397,7 @@
taskId: Int,
wct: WindowContainerTransaction,
transitionSource: DesktopModeTransitionSource,
+ remoteTransition: RemoteTransition? = null,
): Boolean {
if (recentTasksController?.findTaskInBackground(taskId) == null) {
logW("moveBackgroundTaskToDesktop taskId=%d not found", taskId)
@@ -409,8 +420,17 @@
.apply { launchWindowingMode = WINDOWING_MODE_FREEFORM }
.toBundle(),
)
- // TODO(343149901): Add DPI changes for task launch
- val transition = enterDesktopTaskTransitionHandler.moveToDesktop(wct, transitionSource)
+
+ val transition: IBinder
+ if (remoteTransition != null) {
+ val transitionType = transitionType(remoteTransition)
+ val remoteTransitionHandler = OneShotRemoteHandler(mainExecutor, remoteTransition)
+ transition = transitions.startTransition(transitionType, wct, remoteTransitionHandler)
+ remoteTransitionHandler.setTransition(transition)
+ } else {
+ // TODO(343149901): Add DPI changes for task launch
+ transition = enterDesktopTaskTransitionHandler.moveToDesktop(wct, transitionSource)
+ }
desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted(
FREEFORM_ANIMATION_DURATION
)
@@ -424,6 +444,7 @@
task: RunningTaskInfo,
wct: WindowContainerTransaction = WindowContainerTransaction(),
transitionSource: DesktopModeTransitionSource,
+ remoteTransition: RemoteTransition? = null,
) {
if (
DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue() &&
@@ -441,12 +462,21 @@
excludeTaskId = task.taskId,
reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
)
+
// Bring other apps to front first
val taskIdToMinimize =
bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId)
addMoveToDesktopChanges(wct, task)
- val transition = enterDesktopTaskTransitionHandler.moveToDesktop(wct, transitionSource)
+ val transition: IBinder
+ if (remoteTransition != null) {
+ val transitionType = transitionType(remoteTransition)
+ val remoteTransitionHandler = OneShotRemoteHandler(mainExecutor, remoteTransition)
+ transition = transitions.startTransition(transitionType, wct, remoteTransitionHandler)
+ remoteTransitionHandler.setTransition(transition)
+ } else {
+ transition = enterDesktopTaskTransitionHandler.moveToDesktop(wct, transitionSource)
+ }
desktopModeEnterExitTransitionListener?.onEnterDesktopModeTransitionStarted(
FREEFORM_ANIMATION_DURATION
)
@@ -557,6 +587,26 @@
}
fun minimizeTask(taskInfo: RunningTaskInfo) {
+ val wct = WindowContainerTransaction()
+
+ val isMinimizingToPip = taskInfo.pictureInPictureParams?.isAutoEnterEnabled() ?: false
+ // If task is going to PiP, start a PiP transition instead of a minimize transition
+ if (isMinimizingToPip) {
+ val requestInfo = TransitionRequestInfo(
+ TRANSIT_PIP, /* triggerTask= */ null, taskInfo, /* remoteTransition= */ null,
+ /* displayChange= */ null, /* flags= */ 0
+ )
+ val requestRes = transitions.dispatchRequest(Binder(), requestInfo, /* skip= */ null)
+ wct.merge(requestRes.second, true)
+ pendingPipTransitionAndTask =
+ freeformTaskTransitionStarter.startPipTransition(wct) to taskInfo.taskId
+ return
+ }
+
+ minimizeTaskInner(taskInfo)
+ }
+
+ private fun minimizeTaskInner(taskInfo: RunningTaskInfo) {
val taskId = taskInfo.taskId
val displayId = taskInfo.displayId
val wct = WindowContainerTransaction()
@@ -884,7 +934,10 @@
destinationBounds.height(),
displayController,
)
- toggleResizeDesktopTaskTransitionHandler.startTransition(wct)
+ toggleResizeDesktopTaskTransitionHandler.startTransition(
+ wct,
+ interaction.animationStartBounds,
+ )
}
private fun dragToMaximizeDesktopTask(
@@ -915,6 +968,7 @@
direction = ToggleTaskSizeInteraction.Direction.MAXIMIZE,
source = ToggleTaskSizeInteraction.Source.HEADER_DRAG_TO_TOP,
inputMethod = DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent),
+ animationStartBounds = currentDragBounds,
),
)
}
@@ -1202,9 +1256,12 @@
moveHomeTask(wct, toTop = true)
// Currently, we only handle the desktop on the default display really.
- if (displayId == DEFAULT_DISPLAY && ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY.isTrue()) {
+ if (
+ (displayId == DEFAULT_DISPLAY || Flags.enableBugFixesForSecondaryDisplay()) &&
+ ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY.isTrue()
+ ) {
// Add translucent wallpaper activity to show the wallpaper underneath
- addWallpaperActivity(wct)
+ addWallpaperActivity(displayId, wct)
}
val expandedTasksOrderedFrontToBack = taskRepository.getExpandedTasksOrdered(displayId)
@@ -1253,7 +1310,7 @@
?.let { homeTask -> wct.reorder(homeTask.getToken(), /* onTop= */ toTop) }
}
- private fun addWallpaperActivity(wct: WindowContainerTransaction) {
+ private fun addWallpaperActivity(displayId: Int, wct: WindowContainerTransaction) {
logV("addWallpaperActivity")
val userHandle = UserHandle.of(userId)
val userContext = context.createContextAsUser(userHandle, /* flags= */ 0)
@@ -1264,6 +1321,9 @@
launchWindowingMode = WINDOWING_MODE_FULLSCREEN
pendingIntentBackgroundActivityStartMode =
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS
+ if (Flags.enableBugFixesForSecondaryDisplay()) {
+ launchDisplayId = displayId
+ }
}
val pendingIntent =
PendingIntent.getActivityAsUser(
@@ -1329,6 +1389,21 @@
return false
}
+ override fun onTransitionConsumed(
+ transition: IBinder,
+ aborted: Boolean,
+ finishT: Transaction?
+ ) {
+ pendingPipTransitionAndTask?.let { (pipTransition, taskId) ->
+ if (transition == pipTransition) {
+ if (aborted) {
+ shellTaskOrganizer.getRunningTaskInfo(taskId)?.let { minimizeTaskInner(it) }
+ }
+ pendingPipTransitionAndTask = null
+ }
+ }
+ }
+
override fun handleRequest(
transition: IBinder,
request: TransitionRequestInfo,
@@ -2048,7 +2123,11 @@
syncQueue,
taskInfo,
displayController,
- context,
+ if (Flags.enableBugFixesForSecondaryDisplay()) {
+ displayController.getDisplayContext(taskInfo.displayId)
+ } else {
+ context
+ },
taskSurface,
rootTaskDisplayAreaOrganizer,
dragStartState,
@@ -2599,9 +2678,17 @@
}
}
- override fun moveToDesktop(taskId: Int, transitionSource: DesktopModeTransitionSource) {
+ override fun moveToDesktop(
+ taskId: Int,
+ transitionSource: DesktopModeTransitionSource,
+ remoteTransition: RemoteTransition?,
+ ) {
executeRemoteCallWithTaskPermission(controller, "moveTaskToDesktop") { c ->
- c.moveTaskToDesktop(taskId, transitionSource = transitionSource)
+ c.moveTaskToDesktop(
+ taskId,
+ transitionSource = transitionSource,
+ remoteTransition = remoteTransition,
+ )
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
index aac2361..fa383cb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl
@@ -53,7 +53,8 @@
oneway void setTaskListener(IDesktopTaskListener listener);
/** Move a task with given `taskId` to desktop */
- void moveToDesktop(int taskId, in DesktopModeTransitionSource transitionSource);
+ void moveToDesktop(int taskId, in DesktopModeTransitionSource transitionSource,
+ in @nullable RemoteTransition remoteTransition);
/** Remove desktop on the given display */
oneway void removeDesktop(int displayId);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt
index 7afd8d7..f6ebf72 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt
@@ -15,6 +15,7 @@
*/
package com.android.wm.shell.desktopmode.common
+import android.graphics.Rect
import com.android.internal.jank.Cuj
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
@@ -23,10 +24,13 @@
import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction.Source
/** Represents a user interaction to toggle a desktop task's size from to maximize or vice versa. */
-data class ToggleTaskSizeInteraction(
+data class ToggleTaskSizeInteraction
+@JvmOverloads
+constructor(
val direction: Direction,
val source: Source,
val inputMethod: InputMethod,
+ val animationStartBounds: Rect? = null,
) {
constructor(
isMaximized: Boolean,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
index c5fca02..45d1281 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
@@ -23,7 +23,6 @@
import android.graphics.Point
import android.os.SystemProperties
import android.util.Slog
-import androidx.core.content.withStyledAttributes
import com.android.window.flags.Flags
import com.android.wm.shell.R
import com.android.wm.shell.desktopmode.CaptionState
@@ -299,31 +298,12 @@
}
private fun tooltipColorScheme(captionState: CaptionState): TooltipColorScheme {
- context.withStyledAttributes(
- set = null,
- attrs =
- intArrayOf(
- com.android.internal.R.attr.materialColorOnTertiaryFixed,
- com.android.internal.R.attr.materialColorTertiaryFixed,
- com.android.internal.R.attr.materialColorTertiaryFixedDim,
- ),
- defStyleAttr = 0,
- defStyleRes = 0,
- ) {
- val onTertiaryFixed = getColor(/* index= */ 0, /* defValue= */ 0)
- val tertiaryFixed = getColor(/* index= */ 1, /* defValue= */ 0)
- val tertiaryFixedDim = getColor(/* index= */ 2, /* defValue= */ 0)
- val taskInfo = (captionState as CaptionState.AppHandle).runningTaskInfo
+ val onTertiaryFixed =
+ context.getColor(com.android.internal.R.color.materialColorOnTertiaryFixed)
+ val tertiaryFixed =
+ context.getColor(com.android.internal.R.color.materialColorTertiaryFixed)
- val tooltipContainerColor =
- if (decorThemeUtil.getAppTheme(taskInfo) == Theme.LIGHT) {
- tertiaryFixed
- } else {
- tertiaryFixedDim
- }
- return TooltipColorScheme(tooltipContainerColor, onTertiaryFixed, onTertiaryFixed)
- }
- return TooltipColorScheme(0, 0, 0)
+ return TooltipColorScheme(tertiaryFixed, onTertiaryFixed, onTertiaryFixed)
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md
index 9d01535..837a6dd3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/threading.md
@@ -36,7 +36,8 @@
thread)
- This is always another thread even if config_enableShellMainThread is not set true
- **Note**:
- - This thread runs with `THREAD_PRIORITY_BACKGROUND` priority
+ - This thread runs with `THREAD_PRIORITY_BACKGROUND` priority but can be requested to be boosted
+ to `THREAD_PRIORITY_FOREGROUND`
- `ShellAnimationThread` (currently only used for Transitions and Splitscreen, but potentially all
animations could be offloaded here)
- `ShellSplashScreenThread` (only for use with splashscreens)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java
index 2ae9828..52b6c62 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionHandler.java
@@ -18,6 +18,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.TRANSIT_PIP;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -99,6 +100,12 @@
return token;
}
+ @Override
+ public IBinder startPipTransition(WindowContainerTransaction wct) {
+ final IBinder token = mTransitions.startTransition(TRANSIT_PIP, wct, null);
+ mPendingTransitionTokens.add(token);
+ return token;
+ }
@Override
public IBinder startRemoveTransition(WindowContainerTransaction wct) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionStarter.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionStarter.java
index 5984d48..a874a5b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionStarter.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionStarter.java
@@ -51,4 +51,13 @@
* @return the started transition
*/
IBinder startRemoveTransition(WindowContainerTransaction wct);
+
+ /**
+ * Starts PiP transition
+ *
+ * @param wct the {@link WindowContainerTransaction} that launches the PiP
+ *
+ * @return the started transition
+ */
+ IBinder startPipTransition(WindowContainerTransaction wct);
}
\ No newline at end of file
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 1efe2ff..dae3c21 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
@@ -55,6 +55,7 @@
import androidx.annotation.Nullable;
import com.android.internal.util.Preconditions;
+import com.android.window.flags.Flags;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
import com.android.wm.shell.common.pip.PipBoundsState;
@@ -729,6 +730,10 @@
&& getFixedRotationDelta(info, pipTaskChange) == ROTATION_90) {
adjustedSourceRectHint.offset(cutoutInsets.left, cutoutInsets.top);
}
+ if (Flags.enableDesktopWindowingPip()) {
+ adjustedSourceRectHint.offset(-pipActivityChange.getStartAbsBounds().left,
+ -pipActivityChange.getStartAbsBounds().top);
+ }
} else {
// For non-valid app provided src-rect-hint, calculate one to crop into during
// app icon overlay animation.
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 37d5878..032dac9 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
@@ -1317,6 +1317,9 @@
// otherwise a new transition will notify the relevant observers
if (returningToApp && allAppsAreTranslucent(mPausingTasks)) {
mHomeTransitionObserver.notifyHomeVisibilityChanged(true);
+ } else if (!toHome && mState == STATE_NEW_TASK
+ && allAppsAreTranslucent(mOpeningTasks)) {
+ // We are opening a translucent app. Launcher is still visible so we do nothing.
} else if (!toHome) {
// For some transitions, we may have notified home activity that it became
// visible. We need to notify the observer that we are no longer going home.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index a368245..2998a07 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -512,6 +512,11 @@
mStageCoordinator.getStageBounds(outTopOrLeftBounds, outBottomOrRightBounds);
}
+ /** Get the parent-based coordinates for split stages. */
+ public void getRefStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
+ mStageCoordinator.getRefStageBounds(outTopOrLeftBounds, outBottomOrRightBounds);
+ }
+
public void registerSplitScreenListener(SplitScreen.SplitScreenListener listener) {
mStageCoordinator.registerSplitScreenListener(listener);
}
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 b40996f..ba724ed 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
@@ -1776,6 +1776,11 @@
outBottomOrRightBounds.set(mSplitLayout.getBottomRightBounds());
}
+ void getRefStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
+ outTopOrLeftBounds.set(mSplitLayout.getTopLeftRefBounds());
+ outBottomOrRightBounds.set(mSplitLayout.getBottomRightRefBounds());
+ }
+
private void runForActiveStages(Consumer<StageTaskListener> consumer) {
mStageOrderOperator.getActiveStages().forEach(consumer);
}
@@ -2150,8 +2155,7 @@
wct.setForceTranslucent(mRootTaskInfo.token, translucent);
}
- /** Callback when split roots visiblility changed.
- * NOTICE: This only be called on legacy transition. */
+ /** Callback when split roots visiblility changed. */
@Override
public void onStageVisibilityChanged(StageTaskListener stageListener) {
// If split didn't active, just ignore this callback because we should already did these
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index 4a37169..f1245ba 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -240,12 +240,20 @@
@Override
@CallSuper
public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
- ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskInfoChanged: taskId=%d taskAct=%s "
- + "stageId=%s",
- taskInfo.taskId, taskInfo.baseActivity, stageTypeToString(mId));
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
+ "onTaskInfoChanged: taskId=%d vis=%b reqVis=%b baseAct=%s stageId=%s",
+ taskInfo.taskId, taskInfo.isVisible, taskInfo.isVisibleRequested,
+ taskInfo.baseActivity, stageTypeToString(mId));
mWindowDecorViewModel.ifPresent(viewModel -> viewModel.onTaskInfoChanged(taskInfo));
if (mRootTaskInfo.taskId == taskInfo.taskId) {
mRootTaskInfo = taskInfo;
+ boolean isVisible = taskInfo.isVisible && taskInfo.isVisibleRequested;
+ if (mVisible != isVisible) {
+ ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskInfoChanged: currentVis=%b newVis=%b",
+ mVisible, isVisible);
+ mVisible = isVisible;
+ mCallbacks.onStageVisibilityChanged(this);
+ }
} else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {
if (!taskInfo.supportsMultiWindow
|| !ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
@@ -260,7 +268,6 @@
return;
}
mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);
- mVisible = isStageVisible();
mCallbacks.onChildTaskStatusChanged(this, taskInfo.taskId, true /* present */,
taskInfo.isVisible && taskInfo.isVisibleRequested);
} else {
@@ -309,19 +316,6 @@
t.reparent(sc, findTaskSurface(taskId));
}
- /**
- * Checks against all children task info and return true if any are marked as visible.
- */
- private boolean isStageVisible() {
- for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
- if (mChildrenTaskInfo.valueAt(i).isVisible
- && mChildrenTaskInfo.valueAt(i).isVisibleRequested) {
- return true;
- }
- }
- return false;
- }
-
private SurfaceControl findTaskSurface(int taskId) {
if (mRootTaskInfo.taskId == taskId) {
return mRootLeash;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskView.java
index 82c0aaf..361d7663 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskView.java
@@ -186,6 +186,7 @@
*/
public void setObscuredTouchRect(Rect obscuredRect) {
mObscuredTouchRegion = obscuredRect != null ? new Region(obscuredRect) : null;
+ invalidate();
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt
index 4d95cde..01fc644 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopHandleManageWindowsMenu.kt
@@ -19,19 +19,18 @@
import android.app.ActivityManager.RunningTaskInfo
import android.content.Context
import android.graphics.Point
-import android.graphics.Rect
+import android.view.View
import android.view.WindowManager
import android.window.TaskSnapshot
import androidx.compose.ui.graphics.toArgb
+import com.android.wm.shell.R
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.shared.multiinstance.ManageWindowsViewContainer
-import com.android.wm.shell.shared.split.SplitScreenConstants
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer
+import com.android.wm.shell.windowdecor.common.calculateMenuPosition
import com.android.wm.shell.windowdecor.common.DecorThemeUtil
-import com.android.wm.shell.windowdecor.extension.isFullscreen
-import com.android.wm.shell.windowdecor.extension.isMultiWindow
/**
* Implementation of [ManageWindowsViewContainer] meant to be used in desktop header and app
@@ -59,35 +58,19 @@
}
private fun calculateMenuPosition(): Point {
- val position = Point()
- val nonFreeformX = (captionX + (captionWidth / 2) - (menuView.menuWidth / 2))
- when {
- callerTaskInfo.isFreeform -> {
- val taskBounds = callerTaskInfo.getConfiguration().windowConfiguration.bounds
- position.set(taskBounds.left, taskBounds.top)
- }
- callerTaskInfo.isFullscreen -> {
- position.set(nonFreeformX, 0)
- }
- callerTaskInfo.isMultiWindow -> {
- val splitPosition = splitScreenController.getSplitPosition(callerTaskInfo.taskId)
- val leftOrTopStageBounds = Rect()
- val rightOrBottomStageBounds = Rect()
- splitScreenController.getStageBounds(leftOrTopStageBounds, rightOrBottomStageBounds)
- // TODO(b/343561161): This needs to be calculated differently if the task is in
- // top/bottom split.
- when (splitPosition) {
- SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT -> {
- position.set(leftOrTopStageBounds.width() + nonFreeformX, /* y= */ 0)
- }
-
- SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT -> {
- position.set(nonFreeformX, /* y= */ 0)
- }
- }
- }
- }
- return position
+ return calculateMenuPosition(
+ splitScreenController,
+ callerTaskInfo,
+ marginStart = 0,
+ marginTop = context.resources.getDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_margin_top
+ ),
+ captionX,
+ 0,
+ captionWidth,
+ menuView.menuWidth,
+ context.isRtl()
+ )
}
override fun addToContainer(menuView: ManageWindowsView) {
@@ -109,4 +92,7 @@
override fun removeFromContainer() {
menuViewContainer?.releaseView()
}
+
+ private fun Context.isRtl() =
+ resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 85e3068..aea4bda 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -717,7 +717,8 @@
// App sometimes draws before the insets from WindowDecoration#relayout have
// been added, so they must be added here
decoration.addCaptionInset(wct);
- mDesktopTasksController.moveTaskToDesktop(taskId, wct, source);
+ mDesktopTasksController.moveTaskToDesktop(taskId, wct, source,
+ /* remoteTransition= */ null);
decoration.closeHandleMenu();
if (source == DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON) {
@@ -1634,7 +1635,9 @@
}
final DesktopModeWindowDecoration windowDecoration =
mDesktopModeWindowDecorFactory.create(
- mContext,
+ Flags.enableBugFixesForSecondaryDisplay()
+ ? mDisplayController.getDisplayContext(taskInfo.displayId)
+ : mContext,
mContext.createContextAsUser(UserHandle.of(taskInfo.userId), 0 /* flags */),
mDisplayController,
mSplitScreenController,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
index 049b8d6..1179b0c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
@@ -47,12 +47,12 @@
import androidx.core.view.isGone
import com.android.window.flags.Flags
import com.android.wm.shell.R
-import com.android.wm.shell.apptoweb.isBrowserApp
import com.android.wm.shell.shared.split.SplitScreenConstants
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer
import com.android.wm.shell.windowdecor.common.DecorThemeUtil
+import com.android.wm.shell.windowdecor.common.calculateMenuPosition
import com.android.wm.shell.windowdecor.extension.isFullscreen
import com.android.wm.shell.windowdecor.extension.isMultiWindow
import com.android.wm.shell.windowdecor.extension.isPinned
@@ -240,7 +240,19 @@
val menuX: Int
val menuY: Int
val taskBounds = taskInfo.getConfiguration().windowConfiguration.bounds
- updateGlobalMenuPosition(taskBounds, captionX, captionY)
+ globalMenuPosition.set(
+ calculateMenuPosition(
+ splitScreenController,
+ taskInfo,
+ marginStart = marginMenuStart,
+ marginMenuTop,
+ captionX,
+ captionY,
+ captionWidth,
+ menuWidth,
+ context.isRtl()
+ )
+ )
if (layoutResId == R.layout.desktop_mode_app_header) {
// Align the handle menu to the start of the header.
menuX = if (context.isRtl()) {
@@ -265,53 +277,6 @@
handleMenuPosition.set(menuX.toFloat(), menuY.toFloat())
}
- private fun updateGlobalMenuPosition(taskBounds: Rect, captionX: Int, captionY: Int) {
- val nonFreeformX = captionX + (captionWidth / 2) - (menuWidth / 2)
- when {
- taskInfo.isFreeform -> {
- if (context.isRtl()) {
- globalMenuPosition.set(
- /* x= */ taskBounds.right - menuWidth - marginMenuStart,
- /* y= */ taskBounds.top + captionY + marginMenuTop
- )
- } else {
- globalMenuPosition.set(
- /* x= */ taskBounds.left + marginMenuStart,
- /* y= */ taskBounds.top + captionY + marginMenuTop
- )
- }
- }
- taskInfo.isFullscreen -> {
- globalMenuPosition.set(
- /* x = */ nonFreeformX,
- /* y = */ marginMenuTop + captionY
- )
- }
- taskInfo.isMultiWindow -> {
- val splitPosition = splitScreenController.getSplitPosition(taskInfo.taskId)
- val leftOrTopStageBounds = Rect()
- val rightOrBottomStageBounds = Rect()
- splitScreenController.getStageBounds(leftOrTopStageBounds, rightOrBottomStageBounds)
- // TODO(b/343561161): This needs to be calculated differently if the task is in
- // top/bottom split.
- when (splitPosition) {
- SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT -> {
- globalMenuPosition.set(
- /* x = */ leftOrTopStageBounds.width() + nonFreeformX,
- /* y = */ captionY + marginMenuTop
- )
- }
- SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT -> {
- globalMenuPosition.set(
- /* x = */ nonFreeformX,
- /* y = */ captionY + marginMenuTop
- )
- }
- }
- }
- }
- }
-
/**
* Update pill layout, in case task changes have caused positioning to change.
*/
@@ -374,8 +339,6 @@
)
if (splitScreenController.getSplitPosition(taskInfo.taskId)
== SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT) {
- // TODO(b/343561161): This also needs to be calculated differently if
- // the task is in top/bottom split.
val leftStageBounds = Rect()
splitScreenController.getStageBounds(leftStageBounds, Rect())
inputRelativeToMenu.x += leftStageBounds.width().toFloat()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/DesktopMenuPositionUtility.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/DesktopMenuPositionUtility.kt
new file mode 100644
index 0000000..6def3da
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/DesktopMenuPositionUtility.kt
@@ -0,0 +1,81 @@
+/*
+ * 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.windowdecor.common
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.graphics.Point
+import android.graphics.Rect
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
+import com.android.wm.shell.splitscreen.SplitScreenController
+import com.android.wm.shell.windowdecor.extension.isFullscreen
+
+/** Utility function used for calculating position of desktop mode menus. */
+fun calculateMenuPosition(
+ splitScreenController: SplitScreenController,
+ taskInfo: RunningTaskInfo,
+ marginStart: Int,
+ marginTop: Int,
+ captionX: Int,
+ captionY: Int,
+ captionWidth: Int,
+ menuWidth: Int,
+ isRtl: Boolean,
+): Point {
+ if (taskInfo.isFreeform) {
+ val taskBounds = taskInfo.configuration.windowConfiguration.bounds
+ return if (isRtl) {
+ Point(
+ /* x= */ taskBounds.right - menuWidth - marginStart,
+ /* y= */ taskBounds.top + marginTop,
+ )
+ } else {
+ Point(/* x= */ taskBounds.left + marginStart, /* y= */ taskBounds.top + marginTop)
+ }
+ }
+ val nonFreeformPosition = Point(captionX + (captionWidth / 2) - (menuWidth / 2), captionY)
+ if (taskInfo.isFullscreen) {
+ return Point(nonFreeformPosition.x, nonFreeformPosition.y + marginTop)
+ }
+ // Only the splitscreen case left.
+ val splitPosition = splitScreenController.getSplitPosition(taskInfo.taskId)
+ val leftOrTopStageBounds = Rect()
+ val rightOrBottomStageBounds = Rect()
+ splitScreenController.getRefStageBounds(leftOrTopStageBounds, rightOrBottomStageBounds)
+ if (splitScreenController.isLeftRightSplit) {
+ val rightStageModifier =
+ if (splitPosition == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
+ rightOrBottomStageBounds.left
+ } else {
+ 0
+ }
+ return Point(
+ /* x = */ rightStageModifier + nonFreeformPosition.x,
+ /* y = */ nonFreeformPosition.y + marginTop,
+ )
+ } else {
+ val bottomSplitModifier =
+ if (splitPosition == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
+ rightOrBottomStageBounds.top
+ } else {
+ 0
+ }
+ return Point(
+ /* x = */ nonFreeformPosition.x,
+ /* y = */ nonFreeformPosition.y + bottomSplitModifier + marginTop,
+ )
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplier.kt
new file mode 100644
index 0000000..47cfaee
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplier.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.wm.shell.windowdecor.common.viewhost
+
+import android.content.Context
+import android.os.Trace
+import android.util.Pools
+import android.view.Display
+import android.view.SurfaceControl
+import com.android.wm.shell.shared.annotations.ShellMainThread
+import com.android.wm.shell.sysui.ShellInit
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+/**
+ * A [WindowDecorViewHostSupplier] backed by a pool to allow recycling view hosts which may be
+ * expensive to recreate for each new or updated window decoration.
+ *
+ * Callers can obtain a [WindowDecorViewHost] using [acquire], which will return a pooled object if
+ * available, or create a new instance and return it if needed. When finished using a
+ * [WindowDecorViewHost], it must be released using [release] to allow it to be sent back into the
+ * pool and reused later on.
+ *
+ * This class also supports pre-warming [ReusableWindowDecorViewHost] instances, which will be put
+ * into the pool immediately after creation.
+ */
+class PooledWindowDecorViewHostSupplier(
+ private val context: Context,
+ @ShellMainThread private val mainScope: CoroutineScope,
+ shellInit: ShellInit,
+ maxPoolSize: Int,
+ private val preWarmSize: Int,
+) : WindowDecorViewHostSupplier<WindowDecorViewHost> {
+
+ private val pool: Pools.Pool<WindowDecorViewHost> = Pools.SynchronizedPool(maxPoolSize)
+ private var nextDecorViewHostId = 0
+
+ init {
+ require(preWarmSize <= maxPoolSize) { "Pre-warm size should not exceed pool size" }
+ shellInit.addInitCallback(this::onShellInit, this)
+ }
+
+ private fun onShellInit() {
+ if (preWarmSize <= 0) {
+ return
+ }
+ preWarmViewHosts(preWarmSize)
+ }
+
+ private fun preWarmViewHosts(preWarmSize: Int) {
+ mainScope.launch {
+ // Applying isn't needed, as the surface was never actually shown.
+ val t = SurfaceControl.Transaction()
+ repeat(preWarmSize) {
+ val warmedViewHost = newInstance(context, context.display).apply { warmUp() }
+ // Put the warmed view host in the pool by releasing it.
+ release(warmedViewHost, t)
+ }
+ }
+ }
+
+ override fun acquire(context: Context, display: Display): WindowDecorViewHost {
+ val pooledViewHost = pool.acquire()
+ if (pooledViewHost != null) {
+ return pooledViewHost
+ }
+ Trace.beginSection("PooledWindowDecorViewHostSupplier#acquire-newInstance")
+ val newDecorViewHost = newInstance(context, display)
+ Trace.endSection()
+ return newDecorViewHost
+ }
+
+ override fun release(viewHost: WindowDecorViewHost, t: SurfaceControl.Transaction) {
+ val pooled = pool.release(viewHost)
+ if (!pooled) {
+ viewHost.release(t)
+ }
+ }
+
+ private fun newInstance(context: Context, display: Display): ReusableWindowDecorViewHost {
+ // Use a reusable window decor view host, as it allows swapping the entire view hierarchy.
+ return ReusableWindowDecorViewHost(
+ context = context,
+ mainScope = mainScope,
+ display = display,
+ id = nextDecorViewHostId++,
+ )
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHost.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHost.kt
new file mode 100644
index 0000000..da41e1b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHost.kt
@@ -0,0 +1,149 @@
+/*
+ * 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.windowdecor.common.viewhost
+
+import android.content.Context
+import android.content.res.Configuration
+import android.graphics.PixelFormat
+import android.graphics.Region
+import android.view.Display
+import android.view.SurfaceControl
+import android.view.View
+import android.view.WindowManager
+import android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+import android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+import android.view.WindowManager.LayoutParams.TYPE_APPLICATION
+import android.widget.FrameLayout
+import androidx.tracing.Trace
+import com.android.internal.annotations.VisibleForTesting
+import com.android.wm.shell.shared.annotations.ShellMainThread
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+
+/**
+ * An implementation of [WindowDecorViewHost] that supports:
+ * 1) Replacing the root [View], meaning [WindowDecorViewHost.updateView] maybe be called with
+ * different [View] instances. This is useful when reusing [WindowDecorViewHost]s instances for
+ * vastly different view hierarchies, such as Desktop Windowing's App Handles and App Headers.
+ * 2) Pre-warming of the underlying [SurfaceControlViewHostAdapter]s. Useful because their creation
+ * and first root view assignment are expensive, which is undesirable in latency-sensitive code
+ * paths like during a shell transition.
+ */
+class ReusableWindowDecorViewHost(
+ private val context: Context,
+ @ShellMainThread private val mainScope: CoroutineScope,
+ display: Display,
+ val id: Int,
+ @VisibleForTesting
+ val viewHostAdapter: SurfaceControlViewHostAdapter =
+ SurfaceControlViewHostAdapter(context, display),
+) : WindowDecorViewHost, Warmable {
+ @VisibleForTesting val rootView = FrameLayout(context)
+
+ private var currentUpdateJob: Job? = null
+
+ override val surfaceControl: SurfaceControl
+ get() = viewHostAdapter.rootSurface
+
+ override fun warmUp() {
+ if (viewHostAdapter.isInitialized()) {
+ // Already warmed up.
+ return
+ }
+ Trace.beginSection("$TAG#warmUp")
+ viewHostAdapter.prepareViewHost(context.resources.configuration, touchableRegion = null)
+ viewHostAdapter.updateView(
+ rootView,
+ WindowManager.LayoutParams(
+ 0 /* width*/,
+ 0 /* height */,
+ TYPE_APPLICATION,
+ FLAG_NOT_FOCUSABLE or FLAG_SPLIT_TOUCH,
+ PixelFormat.TRANSPARENT,
+ )
+ .apply {
+ setTitle("View root of $TAG#$id")
+ setTrustedOverlay()
+ },
+ )
+ Trace.endSection()
+ }
+
+ override fun updateView(
+ view: View,
+ attrs: WindowManager.LayoutParams,
+ configuration: Configuration,
+ touchableRegion: Region?,
+ onDrawTransaction: SurfaceControl.Transaction?,
+ ) {
+ Trace.beginSection("ReusableWindowDecorViewHost#updateView")
+ clearCurrentUpdateJob()
+ updateViewHost(view, attrs, configuration, touchableRegion, onDrawTransaction)
+ Trace.endSection()
+ }
+
+ override fun updateViewAsync(
+ view: View,
+ attrs: WindowManager.LayoutParams,
+ configuration: Configuration,
+ touchableRegion: Region?,
+ ) {
+ Trace.beginSection("ReusableWindowDecorViewHost#updateViewAsync")
+ clearCurrentUpdateJob()
+ currentUpdateJob =
+ mainScope.launch {
+ updateViewHost(
+ view,
+ attrs,
+ configuration,
+ touchableRegion,
+ onDrawTransaction = null,
+ )
+ }
+ Trace.endSection()
+ }
+
+ override fun release(t: SurfaceControl.Transaction) {
+ clearCurrentUpdateJob()
+ viewHostAdapter.release(t)
+ }
+
+ private fun updateViewHost(
+ view: View,
+ attrs: WindowManager.LayoutParams,
+ configuration: Configuration,
+ touchableRegion: Region?,
+ onDrawTransaction: SurfaceControl.Transaction?,
+ ) {
+ Trace.beginSection("ReusableWindowDecorViewHost#updateViewHost")
+ viewHostAdapter.prepareViewHost(configuration, touchableRegion)
+ onDrawTransaction?.let { viewHostAdapter.applyTransactionOnDraw(it) }
+ rootView.removeAllViews()
+ rootView.addView(view)
+ viewHostAdapter.updateView(rootView, attrs)
+ Trace.endSection()
+ }
+
+ private fun clearCurrentUpdateJob() {
+ currentUpdateJob?.cancel()
+ currentUpdateJob = null
+ }
+
+ companion object {
+ private const val TAG = "ReusableWindowDecorViewHost"
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/Warmable.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/Warmable.kt
new file mode 100644
index 0000000..2cb0f89
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/viewhost/Warmable.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.wm.shell.windowdecor.common.viewhost
+
+/**
+ * An interface for an object that can be warmed up before it's needed.
+ */
+interface Warmable {
+ fun warmUp()
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
index d943918..a474160 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHeaderViewHolder.kt
@@ -40,12 +40,12 @@
import androidx.core.content.withStyledAttributes
import androidx.core.view.isGone
import androidx.core.view.isVisible
-import com.android.internal.R.attr.materialColorOnSecondaryContainer
-import com.android.internal.R.attr.materialColorOnSurface
-import com.android.internal.R.attr.materialColorSecondaryContainer
-import com.android.internal.R.attr.materialColorSurfaceContainerHigh
-import com.android.internal.R.attr.materialColorSurfaceContainerLow
-import com.android.internal.R.attr.materialColorSurfaceDim
+import com.android.internal.R.color.materialColorOnSecondaryContainer
+import com.android.internal.R.color.materialColorOnSurface
+import com.android.internal.R.color.materialColorSecondaryContainer
+import com.android.internal.R.color.materialColorSurfaceContainerHigh
+import com.android.internal.R.color.materialColorSurfaceContainerLow
+import com.android.internal.R.color.materialColorSurfaceDim
import com.android.window.flags.Flags
import com.android.window.flags.Flags.enableMinimizeButton
import com.android.wm.shell.R
@@ -595,33 +595,31 @@
@ColorInt
private fun getAppNameAndButtonColor(taskInfo: RunningTaskInfo, hasGlobalFocus: Boolean): Int {
- val materialColorAttr = when {
+ val materialColor = context.getColor(when {
taskInfo.isTransparentCaptionBarAppearance &&
taskInfo.isLightCaptionBarAppearance -> materialColorOnSecondaryContainer
taskInfo.isTransparentCaptionBarAppearance &&
!taskInfo.isLightCaptionBarAppearance -> materialColorOnSurface
isDarkMode() -> materialColorOnSurface
else -> materialColorOnSecondaryContainer
- }
+ })
val appDetailsOpacity = when {
isDarkMode() && !hasGlobalFocus -> DARK_THEME_UNFOCUSED_OPACITY
!isDarkMode() && !hasGlobalFocus -> LIGHT_THEME_UNFOCUSED_OPACITY
else -> FOCUSED_OPACITY
}
- context.withStyledAttributes(null, intArrayOf(materialColorAttr), 0, 0) {
- val color = getColor(0, 0)
- return if (appDetailsOpacity == FOCUSED_OPACITY) {
- color
- } else {
- Color.argb(
- appDetailsOpacity,
- Color.red(color),
- Color.green(color),
- Color.blue(color)
- )
- }
+
+
+ return if (appDetailsOpacity == FOCUSED_OPACITY) {
+ materialColor
+ } else {
+ Color.argb(
+ appDetailsOpacity,
+ Color.red(materialColor),
+ Color.green(materialColor),
+ Color.blue(materialColor)
+ )
}
- return 0
}
private fun isDarkMode(): Boolean {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index f22e2a5..a2afd2c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -33,6 +33,8 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.ArgumentMatchers.notNull;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -634,7 +636,7 @@
releaseBackGesture();
mShellExecutor.flushAll();
- verify(mAppCallback).setHandoffHandler(any());
+ verify(mAppCallback).setHandoffHandler(notNull());
}
@Test
@@ -654,7 +656,7 @@
releaseBackGesture();
mShellExecutor.flushAll();
- verify(mAppCallback, never()).setHandoffHandler(any());
+ verify(mAppCallback).setHandoffHandler(isNull());
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleViewTest.java
index 329a109..bf03834 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/bar/BubbleBarHandleViewTest.java
@@ -15,9 +15,12 @@
*/
package com.android.wm.shell.bubbles.bar;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import android.graphics.Color;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -61,4 +64,18 @@
assertEquals(handleColor,
ContextCompat.getColor(mContext, R.color.bubble_bar_expanded_view_handle_light));
}
+
+ @Test
+ public void testSetHandleInitialColor_beforeUpdateHandleColor_updatesColor() {
+ mHandleView.setHandleInitialColor(Color.RED);
+ assertThat(mHandleView.getHandleColor()).isEqualTo(Color.RED);
+ }
+
+ @Test
+ public void testSetHandleInitialColor_afterUpdateHandleColor_doesNotUpdateColor() {
+ mHandleView.updateHandleColor(/* isRegionDark= */ true, /* animated= */ false);
+ mHandleView.setHandleInitialColor(Color.RED);
+ assertThat(mHandleView.getHandleColor()).isEqualTo(
+ ContextCompat.getColor(mContext, R.color.bubble_bar_expanded_view_handle_light));
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/HandlerExecutorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/HandlerExecutorTest.kt
new file mode 100644
index 0000000..799b48c
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/HandlerExecutorTest.kt
@@ -0,0 +1,173 @@
+/*
+ * 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.common
+
+import android.os.Handler
+import android.os.HandlerThread
+import android.os.Looper
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.wm.shell.ShellTestCase
+import com.google.common.truth.Truth.assertThat
+import java.util.function.BiConsumer
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+import org.mockito.MockitoSession
+import org.mockito.kotlin.whenever
+
+/**
+ * Tests for HandlerExecutor.
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:HandlerExecutorTest
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class HandlerExecutorTest : ShellTestCase() {
+
+ class TestSetThreadPriorityFn : BiConsumer<Int, Int> {
+ var lastSetPriority = UNSET_THREAD_PRIORITY
+ private set
+ var callCount = 0
+ private set
+
+ override fun accept(tid: Int, priority: Int) {
+ lastSetPriority = priority
+ callCount++
+ }
+
+ fun reset() {
+ lastSetPriority = UNSET_THREAD_PRIORITY
+ callCount = 0
+ }
+ }
+
+ val testSetPriorityFn = TestSetThreadPriorityFn()
+
+ @Test
+ fun defaultExecutorDisallowBoost() {
+ val executor = createTestHandlerExecutor()
+
+ executor.setBoost()
+
+ assertThat(executor.isBoosted()).isFalse()
+ }
+
+ @Test
+ fun boostExecutor_resetWhenNotSet_expectNoOp() {
+ val executor = createTestHandlerExecutor(DEFAULT_THREAD_PRIORITY, BOOSTED_THREAD_PRIORITY)
+ val mockSession: MockitoSession = ExtendedMockito.mockitoSession()
+ .mockStatic(android.os.Process::class.java)
+ .startMocking()
+
+ try {
+ // Try to reset and ensure we never try to set the thread priority
+ executor.resetBoost()
+
+ assertThat(testSetPriorityFn.callCount).isEqualTo(0)
+ assertThat(executor.isBoosted()).isFalse()
+ } finally {
+ mockSession.finishMocking()
+ }
+ }
+
+ @Test
+ fun boostExecutor_setResetBoost_expectThreadPriorityUpdated() {
+ val executor = createTestHandlerExecutor(DEFAULT_THREAD_PRIORITY, BOOSTED_THREAD_PRIORITY)
+ val mockSession: MockitoSession = ExtendedMockito.mockitoSession()
+ .mockStatic(android.os.Process::class.java)
+ .startMocking()
+
+ try {
+ // Boost and ensure the boosted thread priority is requested
+ executor.setBoost()
+
+ assertThat(testSetPriorityFn.lastSetPriority).isEqualTo(BOOSTED_THREAD_PRIORITY)
+ assertThat(testSetPriorityFn.callCount).isEqualTo(1)
+ assertThat(executor.isBoosted()).isTrue()
+
+ // Reset and ensure the default thread priority is requested
+ executor.resetBoost()
+
+ assertThat(testSetPriorityFn.lastSetPriority).isEqualTo(DEFAULT_THREAD_PRIORITY)
+ assertThat(testSetPriorityFn.callCount).isEqualTo(2)
+ assertThat(executor.isBoosted()).isFalse()
+ } finally {
+ mockSession.finishMocking()
+ }
+ }
+
+ @Test
+ fun boostExecutor_overlappingBoost_expectResetOnlyWhenNotOverlapping() {
+ val executor = createTestHandlerExecutor(DEFAULT_THREAD_PRIORITY, BOOSTED_THREAD_PRIORITY)
+ val mockSession: MockitoSession = ExtendedMockito.mockitoSession()
+ .mockStatic(android.os.Process::class.java)
+ .startMocking()
+
+ try {
+ // Set and ensure we only update the thread priority once
+ executor.setBoost()
+ executor.setBoost()
+
+ assertThat(testSetPriorityFn.lastSetPriority).isEqualTo(BOOSTED_THREAD_PRIORITY)
+ assertThat(testSetPriorityFn.callCount).isEqualTo(1)
+ assertThat(executor.isBoosted()).isTrue()
+
+ // Reset and ensure we are still boosted and the thread priority doesn't change
+ executor.resetBoost()
+
+ assertThat(testSetPriorityFn.lastSetPriority).isEqualTo(BOOSTED_THREAD_PRIORITY)
+ assertThat(testSetPriorityFn.callCount).isEqualTo(1)
+ assertThat(executor.isBoosted()).isTrue()
+
+ // Reset again and ensure we update the thread priority accordingly
+ executor.resetBoost()
+
+ assertThat(testSetPriorityFn.lastSetPriority).isEqualTo(DEFAULT_THREAD_PRIORITY)
+ assertThat(testSetPriorityFn.callCount).isEqualTo(2)
+ assertThat(executor.isBoosted()).isFalse()
+ } finally {
+ mockSession.finishMocking()
+ }
+ }
+
+ /**
+ * Creates a test handler executor backed by a mocked handler thread.
+ */
+ private fun createTestHandlerExecutor(
+ defaultThreadPriority: Int = DEFAULT_THREAD_PRIORITY,
+ boostedThreadPriority: Int = DEFAULT_THREAD_PRIORITY
+ ) : HandlerExecutor {
+ val handler = mock(Handler::class.java)
+ val looper = mock(Looper::class.java)
+ val thread = mock(HandlerThread::class.java)
+ whenever(handler.looper).thenReturn(looper)
+ whenever(looper.thread).thenReturn(thread)
+ whenever(thread.threadId).thenReturn(1234)
+ val executor = HandlerExecutor(handler, defaultThreadPriority, boostedThreadPriority)
+ executor.replaceSetThreadPriorityFn(testSetPriorityFn)
+ return executor
+ }
+
+ companion object {
+ private const val UNSET_THREAD_PRIORITY = 0
+ private const val DEFAULT_THREAD_PRIORITY = 1
+ private const val BOOSTED_THREAD_PRIORITY = 1000
+ }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
index 94dbd11..4c97c76 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
@@ -19,6 +19,7 @@
import static android.content.res.Configuration.UI_MODE_NIGHT_YES;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_ASYNC_RELAYOUT;
import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
import static com.android.wm.shell.compatui.CompatUIStatusManager.COMPAT_UI_EDUCATION_HIDDEN;
import static com.android.wm.shell.compatui.CompatUIStatusManager.COMPAT_UI_EDUCATION_VISIBLE;
@@ -42,10 +43,12 @@
import android.app.TaskInfo;
import android.graphics.Insets;
import android.graphics.Rect;
+import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.testing.AndroidTestingRunner;
import android.util.Pair;
import android.view.DisplayCutout;
@@ -125,6 +128,9 @@
@Mock private Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> mOnDismissCallback;
@Mock private DockStateReader mDockStateReader;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private CompatUIConfiguration mCompatUIConfiguration;
private TestShellExecutor mExecutor;
private FakeCompatUIStatusManagerTest mCompatUIStatus;
@@ -317,6 +323,7 @@
@Test
@RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
+ @DisableFlags(FLAG_APP_COMPAT_ASYNC_RELAYOUT)
public void testUpdateCompatInfo_updatesLayoutCorrectly() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
@@ -346,6 +353,36 @@
@Test
@RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
+ @EnableFlags(FLAG_APP_COMPAT_ASYNC_RELAYOUT)
+ public void testUpdateCompatInfo_updatesLayoutCorrectlyAsync() {
+ LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
+
+ assertTrue(windowManager.createLayout(/* canShow= */ true));
+ LetterboxEduDialogLayout layout = windowManager.mLayout;
+ assertNotNull(layout);
+
+ assertTrue(windowManager.updateCompatInfo(
+ createTaskInfo(/* eligible= */ true, USER_ID_1, new Rect(50, 25, 150, 75)),
+ mTaskListener, /* canShow= */ true));
+
+ verifyLayout(layout, layout.getLayoutParams(), /* expectedWidth= */ 100,
+ /* expectedHeight= */ 50, /* expectedExtraTopMargin= */ 0,
+ /* expectedExtraBottomMargin= */ 0);
+ verify(mViewHost).relayout(mWindowAttrsCaptor.capture(), any());
+ assertThat(mWindowAttrsCaptor.getValue()).isEqualTo(layout.getLayoutParams());
+
+ // Window manager should be released (without animation) when eligible becomes false.
+ assertFalse(windowManager.updateCompatInfo(createTaskInfo(/* eligible= */ false),
+ mTaskListener, /* canShow= */ true));
+
+ verify(windowManager).release();
+ verify(mOnDismissCallback, never()).accept(any());
+ verify(mAnimationController, never()).startExitAnimation(any(), any());
+ assertNull(windowManager.mLayout);
+ }
+
+ @Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testUpdateCompatInfo_notEligibleUntilUpdate_createsLayoutAfterUpdate() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ false);
@@ -375,6 +412,7 @@
@Test
@RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
+ @DisableFlags(FLAG_APP_COMPAT_ASYNC_RELAYOUT)
public void testUpdateDisplayLayout_updatesLayoutCorrectly() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
@@ -397,6 +435,29 @@
@Test
@RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
+ @EnableFlags(FLAG_APP_COMPAT_ASYNC_RELAYOUT)
+ public void testUpdateDisplayLayout_updatesLayoutCorrectlyAsync() {
+ LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
+
+ assertTrue(windowManager.createLayout(/* canShow= */ true));
+ LetterboxEduDialogLayout layout = windowManager.mLayout;
+ assertNotNull(layout);
+
+ int newDisplayCutoutTop = DISPLAY_CUTOUT_TOP + 7;
+ int newDisplayCutoutBottom = DISPLAY_CUTOUT_BOTTOM + 9;
+ windowManager.updateDisplayLayout(createDisplayLayout(
+ Insets.of(DISPLAY_CUTOUT_HORIZONTAL, newDisplayCutoutTop,
+ DISPLAY_CUTOUT_HORIZONTAL, newDisplayCutoutBottom)));
+
+ verifyLayout(layout, layout.getLayoutParams(), /* expectedWidth= */ TASK_WIDTH,
+ /* expectedHeight= */ TASK_HEIGHT, /* expectedExtraTopMargin= */
+ newDisplayCutoutTop, /* expectedExtraBottomMargin= */ newDisplayCutoutBottom);
+ verify(mViewHost).relayout(mWindowAttrsCaptor.capture(), any());
+ assertThat(mWindowAttrsCaptor.getValue()).isEqualTo(layout.getLayoutParams());
+ }
+
+ @Test
+ @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testRelease_animationIsCancelled() {
LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/OWNERS b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/OWNERS
index 5b05af9..3a017f3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/OWNERS
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/OWNERS
@@ -1,2 +1,8 @@
# Bug component: 970984
-# includes OWNERS from parent directories
\ No newline at end of file
+# includes OWNERS from parent directories
+
+mariiasand@google.com
+mcarli@google.com
+minagranic@google.com
+gracielawputri@google.com
+eevlachavas@google.com
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxUtilsTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxUtilsTest.kt
index 06b8052..6675112 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxUtilsTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxUtilsTest.kt
@@ -19,9 +19,14 @@
import android.content.Context
import android.graphics.Rect
import android.testing.AndroidTestingRunner
+import android.view.SurfaceControl
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Maps.runOnItem
+import com.android.wm.shell.compatui.letterbox.LetterboxUtils.Transactions.moveAndCrop
import java.util.function.Consumer
+import kotlin.test.assertEquals
+import kotlin.test.assertNull
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
@@ -100,6 +105,35 @@
}
}
+ @Test
+ fun `runOnItem executes onFound when an item has been found for a key`() {
+ runTestScenario { r ->
+ r.initMap(1 to 2, 3 to 4)
+ r.runOnItem<Int>(1)
+ r.verifyOnItemInvoked(expectedItem = 2)
+ r.verifyOnMissingNotInvoked()
+ }
+ }
+
+ @Test
+ fun `runOnItem executes onMissing when an item has not been found for a key`() {
+ runTestScenario { r ->
+ r.initMap(1 to 2, 3 to 4)
+ r.runOnItem<Int>(8)
+ r.verifyOnItemNotInvoked()
+ r.verifyOnMissingInvoked(expectedKey = 8)
+ }
+ }
+
+ @Test
+ fun `moveAndCrop invoked Move and then Crop`() {
+ runTestScenario { r ->
+ r.invoke(Rect(1, 2, 51, 62))
+ r.verifySetPosition(expectedX = 1f, expectedY = 2f)
+ r.verifySetWindowCrop(expectedWidth = 50, expectedHeight = 60)
+ }
+ }
+
/**
* Runs a test scenario providing a Robot.
*/
@@ -113,6 +147,14 @@
builder: (LetterboxSurfaceBuilder) -> LetterboxController
) : LetterboxControllerRobotTest(ctx, builder) {
+ private var testableMap = mutableMapOf<Int, Int>()
+ private var onItemState: Int? = null
+ private var onMissingStateKey: Int? = null
+ private var onMissingStateMap: MutableMap<Int, Int>? = null
+
+ private val transaction = getTransactionMock()
+ private val surface = SurfaceControl()
+
fun verifyCreateSurfaceInvokedWithRequest(
target: LetterboxController,
times: Int = 1
@@ -147,5 +189,46 @@
) {
verify(target, times(times)).dump()
}
+
+ fun initMap(vararg values: Pair<Int, Int>) = testableMap.putAll(values.toMap())
+
+ fun <T> runOnItem(key: Int) {
+ testableMap.runOnItem(key, onFound = { item ->
+ onItemState = item
+ }, onMissed = { k, m ->
+ onMissingStateKey = k
+ onMissingStateMap = m
+ })
+ }
+
+ fun verifyOnItemInvoked(expectedItem: Int) {
+ assertEquals(expectedItem, onItemState)
+ }
+
+ fun verifyOnItemNotInvoked() {
+ assertNull(onItemState)
+ }
+
+ fun verifyOnMissingInvoked(expectedKey: Int) {
+ assertEquals(expectedKey, onMissingStateKey)
+ assertEquals(onMissingStateMap, testableMap)
+ }
+
+ fun verifyOnMissingNotInvoked() {
+ assertNull(onMissingStateKey)
+ assertNull(onMissingStateMap)
+ }
+
+ fun invoke(rect: Rect) {
+ transaction.moveAndCrop(surface, rect)
+ }
+
+ fun verifySetPosition(expectedX: Float, expectedY: Float) {
+ verify(transaction).setPosition(surface, expectedX, expectedY)
+ }
+
+ fun verifySetWindowCrop(expectedWidth: Int, expectedHeight: Int) {
+ verify(transaction).setWindowCrop(surface, expectedWidth, expectedHeight)
+ }
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 3bee588..33c1451 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -21,6 +21,7 @@
import android.app.ActivityOptions
import android.app.KeyguardManager
import android.app.PendingIntent
+import android.app.PictureInPictureParams
import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
@@ -1216,14 +1217,40 @@
}
@Test
- fun moveRunningTaskToDesktop_deviceSupported_taskIsMovedToDesktop() {
- val task = setUpFullscreenTask()
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+ fun moveBackgroundTaskToDesktop_remoteTransition_usesOneShotHandler() {
+ val transitionHandlerArgCaptor = ArgumentCaptor.forClass(TransitionHandler::class.java)
+ whenever(
+ transitions.startTransition(anyInt(), any(), transitionHandlerArgCaptor.capture())
+ ).thenReturn(Binder())
- controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
+ val task = createTaskInfo(1)
+ whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null)
+ whenever(recentTasksController.findTaskInBackground(anyInt())).thenReturn(task)
+ controller.moveTaskToDesktop(
+ taskId = task.taskId,
+ transitionSource = UNKNOWN,
+ remoteTransition = RemoteTransition(spy(TestRemoteTransition())))
- val wct = getLatestEnterDesktopWct()
- assertThat(wct.changes[task.token.asBinder()]?.windowingMode).isEqualTo(WINDOWING_MODE_FREEFORM)
verify(desktopModeEnterExitTransitionListener).onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION)
+ assertIs<OneShotRemoteHandler>(transitionHandlerArgCaptor.value)
+ }
+
+
+ @Test
+ fun moveRunningTaskToDesktop_remoteTransition_usesOneShotHandler() {
+ val transitionHandlerArgCaptor = ArgumentCaptor.forClass(TransitionHandler::class.java)
+ whenever(
+ transitions.startTransition(anyInt(), any(), transitionHandlerArgCaptor.capture())
+ ).thenReturn(Binder())
+
+ controller.moveRunningTaskToDesktop(
+ task = setUpFullscreenTask(),
+ transitionSource = UNKNOWN,
+ remoteTransition = RemoteTransition(spy(TestRemoteTransition())))
+
+ verify(desktopModeEnterExitTransitionListener).onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION)
+ assertIs<OneShotRemoteHandler>(transitionHandlerArgCaptor.value)
}
@Test
@@ -1724,6 +1751,34 @@
}
@Test
+ fun onDesktopWindowMinimize_pipTask_autoEnterEnabled_startPipTransition() {
+ val task = setUpPipTask(autoEnterEnabled = true)
+ val handler = mock(TransitionHandler::class.java)
+ whenever(freeformTaskTransitionStarter.startPipTransition(any()))
+ .thenReturn(Binder())
+ whenever(transitions.dispatchRequest(any(), any(), anyOrNull()))
+ .thenReturn(android.util.Pair(handler, WindowContainerTransaction())
+ )
+
+ controller.minimizeTask(task)
+
+ verify(freeformTaskTransitionStarter).startPipTransition(any())
+ verify(freeformTaskTransitionStarter, never()).startMinimizedModeTransition(any())
+ }
+
+ @Test
+ fun onDesktopWindowMinimize_pipTask_autoEnterDisabled_startMinimizeTransition() {
+ val task = setUpPipTask(autoEnterEnabled = false)
+ whenever(freeformTaskTransitionStarter.startMinimizedModeTransition(any()))
+ .thenReturn(Binder())
+
+ controller.minimizeTask(task)
+
+ verify(freeformTaskTransitionStarter).startMinimizedModeTransition(any())
+ verify(freeformTaskTransitionStarter, never()).startPipTransition(any())
+ }
+
+ @Test
fun onDesktopWindowMinimize_singleActiveTask_noWallpaperActivityToken_doesntRemoveWallpaper() {
val task = setUpFreeformTask(active = true)
val transition = Binder()
@@ -3033,20 +3088,21 @@
.thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR)
// Drag move the task to the top edge
+ val currentDragBounds = Rect(100, 50, 500, 1000)
spyController.onDragPositioningMove(task, mockSurface, 200f, Rect(100, 200, 500, 1000))
spyController.onDragPositioningEnd(
task,
mockSurface,
Point(100, 50), /* position */
PointF(200f, 300f), /* inputCoordinate */
- Rect(100, 50, 500, 1000), /* currentDragBounds */
+ currentDragBounds,
Rect(0, 50, 2000, 2000) /* validDragArea */,
Rect() /* dragStartBounds */,
motionEvent,
desktopWindowDecoration)
// Assert bounds set to stable bounds
- val wct = getLatestToggleResizeDesktopTaskWct()
+ val wct = getLatestToggleResizeDesktopTaskWct(currentDragBounds)
assertThat(findBoundsChange(wct, task)).isEqualTo(STABLE_BOUNDS)
// Assert event is properly logged
verify(desktopModeEventLogger, times(1)).logTaskResizingStarted(
@@ -4228,6 +4284,14 @@
return task
}
+ private fun setUpPipTask(autoEnterEnabled: Boolean): RunningTaskInfo {
+ return setUpFreeformTask().apply {
+ pictureInPictureParams = PictureInPictureParams.Builder()
+ .setAutoEnterEnabled(autoEnterEnabled)
+ .build()
+ }
+ }
+
private fun setUpHomeTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
val task = createHomeTask(displayId)
whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 88f62d1..2ffdcf8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -591,7 +591,8 @@
verify(mockDesktopTasksController).moveTaskToDesktop(
eq(decor.mTaskInfo.taskId),
any(),
- eq(DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON)
+ eq(DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON),
+ anyOrNull()
)
}
@@ -824,7 +825,7 @@
)
verify(mockDesktopTasksController, times(1))
- .moveTaskToDesktop(any(), any(), any())
+ .moveTaskToDesktop(any(), any(), any(), anyOrNull())
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
index 6babf81..3bcbcbdd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
@@ -257,7 +257,7 @@
if (splitPosition == SPLIT_POSITION_TOP_OR_LEFT) {
(SPLIT_LEFT_BOUNDS.width() / 2) - (HANDLE_WIDTH / 2)
} else {
- (SPLIT_RIGHT_BOUNDS.width() / 2) - (HANDLE_WIDTH / 2)
+ SPLIT_LEFT_BOUNDS.width() + (SPLIT_RIGHT_BOUNDS.width() / 2) - (HANDLE_WIDTH / 2)
}
}
else -> error("Invalid windowing mode")
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/DesktopMenuPositionUtilityTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/DesktopMenuPositionUtilityTest.kt
new file mode 100644
index 0000000..7b42ff4
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/DesktopMenuPositionUtilityTest.kt
@@ -0,0 +1,201 @@
+/*
+ * 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.windowdecor.common
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
+import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
+import com.android.wm.shell.splitscreen.SplitScreenController
+import org.junit.runner.RunWith
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+
+/**
+ * Tests for [DesktopMenuPositionUtility].
+ *
+ * Build/Install/Run: atest WMShellUnitTests:DesktopMenuPositionUtilityTest
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class DesktopMenuPositionUtilityTest : ShellTestCase() {
+
+ @Mock private val mockSplitScreenController = mock<SplitScreenController>()
+
+ @Test
+ fun testFullscreenPositionCalculation() {
+ val task = setupTaskInfo(WINDOWING_MODE_FULLSCREEN)
+ val result =
+ calculateMenuPosition(
+ splitScreenController = mockSplitScreenController,
+ taskInfo = task,
+ MARGIN_START,
+ MARGIN_TOP,
+ CAPTION_X,
+ CAPTION_Y,
+ CAPTION_WIDTH,
+ MENU_WIDTH,
+ isRtl = false,
+ )
+ assertEquals(CAPTION_X + (CAPTION_WIDTH / 2) - (MENU_WIDTH / 2), result.x)
+ assertEquals(CAPTION_Y + MARGIN_TOP, result.y)
+ }
+
+ @Test
+ fun testSplitLeftPositionCalculation() {
+ val task = setupTaskInfo(WINDOWING_MODE_MULTI_WINDOW)
+ setupMockSplitScreenController(
+ splitPosition = SPLIT_POSITION_TOP_OR_LEFT,
+ isLeftRightSplit = true,
+ )
+ val result =
+ calculateMenuPosition(
+ splitScreenController = mockSplitScreenController,
+ taskInfo = task,
+ MARGIN_START,
+ MARGIN_TOP,
+ CAPTION_X,
+ CAPTION_Y,
+ CAPTION_WIDTH,
+ MENU_WIDTH,
+ isRtl = false,
+ )
+ assertEquals(CAPTION_X + (CAPTION_WIDTH / 2) - (MENU_WIDTH / 2), result.x)
+ assertEquals(CAPTION_Y + MARGIN_TOP, result.y)
+ }
+
+ @Test
+ fun testSplitRightPositionCalculation() {
+ val task = setupTaskInfo(WINDOWING_MODE_MULTI_WINDOW)
+ setupMockSplitScreenController(
+ splitPosition = SPLIT_POSITION_BOTTOM_OR_RIGHT,
+ isLeftRightSplit = true,
+ )
+ val result =
+ calculateMenuPosition(
+ splitScreenController = mockSplitScreenController,
+ taskInfo = task,
+ MARGIN_START,
+ MARGIN_TOP,
+ CAPTION_X,
+ CAPTION_Y,
+ CAPTION_WIDTH,
+ MENU_WIDTH,
+ isRtl = false,
+ )
+ assertEquals(
+ CAPTION_X + (CAPTION_WIDTH / 2) - (MENU_WIDTH / 2) + SPLIT_LEFT_BOUNDS.width(),
+ result.x,
+ )
+ assertEquals(CAPTION_Y + MARGIN_TOP, result.y)
+ }
+
+ @Test
+ fun testSplitTopPositionCalculation() {
+ val task = setupTaskInfo(WINDOWING_MODE_MULTI_WINDOW)
+ setupMockSplitScreenController(
+ splitPosition = SPLIT_POSITION_TOP_OR_LEFT,
+ isLeftRightSplit = false,
+ )
+ val result =
+ calculateMenuPosition(
+ splitScreenController = mockSplitScreenController,
+ taskInfo = task,
+ MARGIN_START,
+ MARGIN_TOP,
+ CAPTION_X,
+ CAPTION_Y,
+ CAPTION_WIDTH,
+ MENU_WIDTH,
+ isRtl = false,
+ )
+ assertEquals(CAPTION_X + (CAPTION_WIDTH / 2) - (MENU_WIDTH / 2), result.x)
+ assertEquals(CAPTION_Y + MARGIN_TOP, result.y)
+ }
+
+ @Test
+ fun testSplitBottomPositionCalculation() {
+ val task = setupTaskInfo(WINDOWING_MODE_MULTI_WINDOW)
+ setupMockSplitScreenController(
+ splitPosition = SPLIT_POSITION_BOTTOM_OR_RIGHT,
+ isLeftRightSplit = false,
+ )
+ val result =
+ calculateMenuPosition(
+ splitScreenController = mockSplitScreenController,
+ taskInfo = task,
+ MARGIN_START,
+ MARGIN_TOP,
+ CAPTION_X,
+ CAPTION_Y,
+ CAPTION_WIDTH,
+ MENU_WIDTH,
+ isRtl = false,
+ )
+ assertEquals(CAPTION_X + (CAPTION_WIDTH / 2) - (MENU_WIDTH / 2), result.x)
+ assertEquals(CAPTION_Y + MARGIN_TOP + SPLIT_TOP_BOUNDS.height(), result.y)
+ }
+
+ private fun setupTaskInfo(windowingMode: Int): RunningTaskInfo {
+ return TestRunningTaskInfoBuilder().setWindowingMode(windowingMode).build()
+ }
+
+ private fun setupMockSplitScreenController(isLeftRightSplit: Boolean, splitPosition: Int) {
+ whenever(mockSplitScreenController.getSplitPosition(anyInt())).thenReturn(splitPosition)
+ whenever(mockSplitScreenController.getRefStageBounds(any(), any())).thenAnswer {
+ (it.arguments.first() as Rect).set(
+ if (isLeftRightSplit) {
+ SPLIT_LEFT_BOUNDS
+ } else {
+ SPLIT_TOP_BOUNDS
+ }
+ )
+ (it.arguments[1] as Rect).set(
+ if (isLeftRightSplit) {
+ SPLIT_RIGHT_BOUNDS
+ } else {
+ SPLIT_BOTTOM_BOUNDS
+ }
+ )
+ }
+ whenever(mockSplitScreenController.isLeftRightSplit).thenReturn(isLeftRightSplit)
+ }
+
+ companion object {
+ private val SPLIT_LEFT_BOUNDS = Rect(0, 0, 1280, 1600)
+ private val SPLIT_RIGHT_BOUNDS = Rect(1280, 0, 2560, 1600)
+ private val SPLIT_TOP_BOUNDS = Rect(0, 0, 2560, 800)
+ private val SPLIT_BOTTOM_BOUNDS = Rect(0, 800, 2560, 1600)
+ private const val CAPTION_X = 800
+ private const val CAPTION_Y = 50
+ private const val MARGIN_START = 30
+ private const val MARGIN_TOP = 50
+ private const val MENU_WIDTH = 500
+ private const val CAPTION_WIDTH = 200
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplierTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplierTest.kt
new file mode 100644
index 0000000..92f5def
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/PooledWindowDecorViewHostSupplierTest.kt
@@ -0,0 +1,160 @@
+/*
+ * 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.windowdecor.common.viewhost
+
+import android.content.res.Configuration
+import android.graphics.Region
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.SurfaceControl
+import android.view.View
+import android.view.WindowManager
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.sysui.ShellInit
+import com.android.wm.shell.util.StubTransaction
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.mock
+
+/**
+ * Tests for [PooledWindowDecorViewHostSupplier].
+ *
+ * Build/Install/Run: atest WMShellUnitTests:PooledWindowDecorViewHostSupplierTest
+ */
+@SmallTest
+@RunWithLooper
+@RunWith(AndroidTestingRunner::class)
+class PooledWindowDecorViewHostSupplierTest : ShellTestCase() {
+
+ private val testExecutor = TestShellExecutor()
+ private val testShellInit = ShellInit(testExecutor)
+
+ private lateinit var supplier: PooledWindowDecorViewHostSupplier
+
+ @Test
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun onInit_warmsAndPoolsViewHosts() = runTest {
+ supplier = createSupplier(maxPoolSize = 5, preWarmSize = 2)
+
+ testExecutor.flushAll()
+ advanceUntilIdle()
+
+ val viewHost1 = supplier.acquire(context, context.display) as ReusableWindowDecorViewHost
+ val viewHost2 = supplier.acquire(context, context.display) as ReusableWindowDecorViewHost
+
+ // Acquired warmed up view hosts from the pool.
+ assertThat(viewHost1.viewHostAdapter.isInitialized()).isTrue()
+ assertThat(viewHost2.viewHostAdapter.isInitialized()).isTrue()
+ }
+
+ @Test(expected = Throwable::class)
+ fun onInit_warmUpSizeExceedsPoolSize_throws() = runTest {
+ createSupplier(maxPoolSize = 3, preWarmSize = 4)
+ }
+
+ @Test
+ fun acquire_poolBelowLimit_caches() = runTest {
+ supplier = createSupplier(maxPoolSize = 5)
+
+ val viewHost = FakeWindowDecorViewHost()
+ supplier.release(viewHost, StubTransaction())
+
+ assertThat(supplier.acquire(context, context.display)).isEqualTo(viewHost)
+ }
+
+ @Test
+ fun release_poolBelowLimit_doesNotReleaseViewHost() = runTest {
+ supplier = createSupplier(maxPoolSize = 5)
+
+ val viewHost = FakeWindowDecorViewHost()
+ val mockT = mock<SurfaceControl.Transaction>()
+ supplier.release(viewHost, mockT)
+
+ assertThat(viewHost.released).isFalse()
+ }
+
+ @Test
+ fun release_poolAtLimit_doesNotCache() = runTest {
+ supplier = createSupplier(maxPoolSize = 1)
+ val viewHost = FakeWindowDecorViewHost()
+ supplier.release(viewHost, StubTransaction()) // Maxes pool.
+
+ val viewHost2 = FakeWindowDecorViewHost()
+ supplier.release(viewHost2, StubTransaction()) // Beyond limit.
+
+ assertThat(supplier.acquire(context, context.display)).isEqualTo(viewHost)
+ // Second one wasn't cached, so the acquired one should've been a new instance.
+ assertThat(supplier.acquire(context, context.display)).isNotEqualTo(viewHost2)
+ }
+
+ @Test
+ fun release_poolAtLimit_releasesViewHost() = runTest {
+ supplier = createSupplier(maxPoolSize = 1)
+ val viewHost = FakeWindowDecorViewHost()
+ supplier.release(viewHost, StubTransaction()) // Maxes pool.
+
+ val viewHost2 = FakeWindowDecorViewHost()
+ val mockT = mock<SurfaceControl.Transaction>()
+ supplier.release(viewHost2, mockT) // Beyond limit.
+
+ // Second one doesn't fit, so it needs to be released.
+ assertThat(viewHost2.released).isTrue()
+ }
+
+ private fun CoroutineScope.createSupplier(maxPoolSize: Int, preWarmSize: Int = 0) =
+ PooledWindowDecorViewHostSupplier(context, this, testShellInit, maxPoolSize, preWarmSize)
+ .also { testShellInit.init() }
+
+ private class FakeWindowDecorViewHost : WindowDecorViewHost {
+ var released = false
+ private set
+
+ override val surfaceControl: SurfaceControl
+ get() = SurfaceControl()
+
+ override fun updateView(
+ view: View,
+ attrs: WindowManager.LayoutParams,
+ configuration: Configuration,
+ touchableRegion: Region?,
+ onDrawTransaction: SurfaceControl.Transaction?,
+ ) {}
+
+ override fun updateViewAsync(
+ view: View,
+ attrs: WindowManager.LayoutParams,
+ configuration: Configuration,
+ touchableRegion: Region?,
+ ) {}
+
+ override fun release(t: SurfaceControl.Transaction) {
+ released = true
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHostTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHostTest.kt
new file mode 100644
index 0000000..d99a482
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/viewhost/ReusableWindowDecorViewHostTest.kt
@@ -0,0 +1,178 @@
+/*
+ * 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.windowdecor.common.viewhost
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.SurfaceControl
+import android.view.View
+import android.view.WindowManager
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.verify
+
+/**
+ * Tests for [ReusableWindowDecorViewHost].
+ *
+ * Build/Install/Run: atest WMShellUnitTests:ReusableWindowDecorViewHostTest
+ */
+@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner::class)
+class ReusableWindowDecorViewHostTest : ShellTestCase() {
+
+ @Test
+ fun update_differentView_replacesView() = runTest {
+ val view = View(context)
+ val lp = WindowManager.LayoutParams()
+ val reusableVH = createReusableViewHost()
+ reusableVH.updateView(view, lp, context.resources.configuration, null)
+
+ assertThat(reusableVH.rootView.childCount).isEqualTo(1)
+ assertThat(reusableVH.rootView.getChildAt(0)).isEqualTo(view)
+
+ val newView = View(context)
+ val newLp = WindowManager.LayoutParams()
+ reusableVH.updateView(newView, newLp, context.resources.configuration, null)
+
+ assertThat(reusableVH.rootView.childCount).isEqualTo(1)
+ assertThat(reusableVH.rootView.getChildAt(0)).isEqualTo(newView)
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun updateView_clearsPendingAsyncJob() = runTest {
+ val reusableVH = createReusableViewHost()
+ val asyncView = View(context)
+ val syncView = View(context)
+ val asyncAttrs = WindowManager.LayoutParams(100, 100)
+ val syncAttrs = WindowManager.LayoutParams(200, 200)
+
+ reusableVH.updateViewAsync(
+ view = asyncView,
+ attrs = asyncAttrs,
+ configuration = context.resources.configuration,
+ )
+
+ // No view host yet, since the coroutine hasn't run.
+ assertThat(reusableVH.viewHostAdapter.isInitialized()).isFalse()
+
+ reusableVH.updateView(
+ view = syncView,
+ attrs = syncAttrs,
+ configuration = context.resources.configuration,
+ onDrawTransaction = null,
+ )
+
+ // Would run coroutine if it hadn't been cancelled.
+ advanceUntilIdle()
+
+ assertThat(reusableVH.viewHostAdapter.isInitialized()).isTrue()
+ // View host view/attrs should match the ones from the sync call.
+ assertThat(reusableVH.rootView.getChildAt(0)).isEqualTo(syncView)
+ assertThat(reusableVH.view()!!.layoutParams.width).isEqualTo(syncAttrs.width)
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun updateViewAsync() = runTest {
+ val reusableVH = createReusableViewHost()
+ val view = View(context)
+ val attrs = WindowManager.LayoutParams(100, 100)
+
+ reusableVH.updateViewAsync(
+ view = view,
+ attrs = attrs,
+ configuration = context.resources.configuration,
+ )
+
+ assertThat(reusableVH.viewHostAdapter.isInitialized()).isFalse()
+
+ advanceUntilIdle()
+
+ assertThat(reusableVH.viewHostAdapter.isInitialized()).isTrue()
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun updateViewAsync_clearsPendingAsyncJob() = runTest {
+ val reusableVH = createReusableViewHost()
+
+ val view = View(context)
+ reusableVH.updateViewAsync(
+ view = view,
+ attrs = WindowManager.LayoutParams(100, 100),
+ configuration = context.resources.configuration,
+ )
+ val otherView = View(context)
+ reusableVH.updateViewAsync(
+ view = otherView,
+ attrs = WindowManager.LayoutParams(100, 100),
+ configuration = context.resources.configuration,
+ )
+
+ advanceUntilIdle()
+
+ assertThat(reusableVH.viewHostAdapter.isInitialized()).isTrue()
+ assertThat(reusableVH.rootView.getChildAt(0)).isEqualTo(otherView)
+ }
+
+ @Test
+ fun release() = runTest {
+ val reusableVH = createReusableViewHost()
+
+ val view = View(context)
+ reusableVH.updateView(
+ view = view,
+ attrs = WindowManager.LayoutParams(100, 100),
+ configuration = context.resources.configuration,
+ onDrawTransaction = null,
+ )
+
+ val t = mock(SurfaceControl.Transaction::class.java)
+ reusableVH.release(t)
+
+ verify(reusableVH.viewHostAdapter).release(t)
+ }
+
+ @Test
+ fun warmUp_addsRootView() = runTest {
+ val reusableVH = createReusableViewHost().apply { warmUp() }
+
+ assertThat(reusableVH.viewHostAdapter.isInitialized()).isTrue()
+ assertThat(reusableVH.view()).isEqualTo(reusableVH.rootView)
+ }
+
+ private fun CoroutineScope.createReusableViewHost() =
+ ReusableWindowDecorViewHost(
+ context = context,
+ mainScope = this,
+ display = context.display,
+ id = 1,
+ viewHostAdapter = spy(SurfaceControlViewHostAdapter(context, context.display)),
+ )
+
+ private fun ReusableWindowDecorViewHost.view(): View? = viewHostAdapter.viewHost?.view
+}
diff --git a/libs/hwui/jni/text/TextShaper.cpp b/libs/hwui/jni/text/TextShaper.cpp
index c735989..d1782b2 100644
--- a/libs/hwui/jni/text/TextShaper.cpp
+++ b/libs/hwui/jni/text/TextShaper.cpp
@@ -225,8 +225,8 @@
constexpr float NO_OVERRIDE = -1;
-float findValueFromVariationSettings(const minikin::FontFakery& fakery, minikin::AxisTag tag) {
- for (const minikin::FontVariation& fv : fakery.variationSettings()) {
+float findValueFromVariationSettings(const minikin::VariationSettings& axes, minikin::AxisTag tag) {
+ for (const minikin::FontVariation& fv : axes) {
if (fv.axisTag == tag) {
return fv.value;
}
@@ -238,8 +238,8 @@
static jfloat TextShaper_Result_getWeightOverride(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
const LayoutWrapper* layout = reinterpret_cast<LayoutWrapper*>(ptr);
if (text_feature::typeface_redesign_readonly()) {
- float value =
- findValueFromVariationSettings(layout->layout.getFakery(i), minikin::TAG_wght);
+ float value = findValueFromVariationSettings(layout->layout.typeface(i)->GetAxes(),
+ minikin::TAG_wght);
return std::isnan(value) ? NO_OVERRIDE : value;
} else {
return layout->layout.getFakery(i).wghtAdjustment();
@@ -250,8 +250,8 @@
static jfloat TextShaper_Result_getItalicOverride(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
const LayoutWrapper* layout = reinterpret_cast<LayoutWrapper*>(ptr);
if (text_feature::typeface_redesign_readonly()) {
- float value =
- findValueFromVariationSettings(layout->layout.getFakery(i), minikin::TAG_ital);
+ float value = findValueFromVariationSettings(layout->layout.typeface(i)->GetAxes(),
+ minikin::TAG_ital);
return std::isnan(value) ? NO_OVERRIDE : value;
} else {
return layout->layout.getFakery(i).italAdjustment();
diff --git a/location/api/system-current.txt b/location/api/system-current.txt
index 9478e35..ba42241 100644
--- a/location/api/system-current.txt
+++ b/location/api/system-current.txt
@@ -6,6 +6,111 @@
method public void onLocationBatch(java.util.List<android.location.Location>);
}
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class BeidouAssistance implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public android.location.GnssAlmanac getAlmanac();
+ method @Nullable public android.location.KlobucharIonosphericModel getIonosphericModel();
+ method @Nullable public android.location.LeapSecondsModel getLeapSecondsModel();
+ method @NonNull public java.util.List<android.location.RealTimeIntegrityModel> getRealTimeIntegrityModels();
+ method @NonNull public java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections> getSatelliteCorrections();
+ method @NonNull public java.util.List<android.location.BeidouSatelliteEphemeris> getSatelliteEphemeris();
+ method @NonNull public java.util.List<android.location.TimeModel> getTimeModels();
+ method @Nullable public android.location.UtcModel getUtcModel();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.BeidouAssistance> CREATOR;
+ }
+
+ public static final class BeidouAssistance.Builder {
+ ctor public BeidouAssistance.Builder();
+ method @NonNull public android.location.BeidouAssistance build();
+ method @NonNull public android.location.BeidouAssistance.Builder setAlmanac(@Nullable android.location.GnssAlmanac);
+ method @NonNull public android.location.BeidouAssistance.Builder setIonosphericModel(@Nullable android.location.KlobucharIonosphericModel);
+ method @NonNull public android.location.BeidouAssistance.Builder setLeapSecondsModel(@Nullable android.location.LeapSecondsModel);
+ method @NonNull public android.location.BeidouAssistance.Builder setRealTimeIntegrityModels(@Nullable java.util.List<android.location.RealTimeIntegrityModel>);
+ method @NonNull public android.location.BeidouAssistance.Builder setSatelliteCorrections(@Nullable java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections>);
+ method @NonNull public android.location.BeidouAssistance.Builder setSatelliteEphemeris(@Nullable java.util.List<android.location.BeidouSatelliteEphemeris>);
+ method @NonNull public android.location.BeidouAssistance.Builder setTimeModels(@Nullable java.util.List<android.location.TimeModel>);
+ method @NonNull public android.location.BeidouAssistance.Builder setUtcModel(@Nullable android.location.UtcModel);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class BeidouSatelliteEphemeris implements android.os.Parcelable {
+ method public int describeContents();
+ method @IntRange(from=1, to=63) public int getPrn();
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel getSatelliteClockModel();
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime getSatelliteEphemerisTime();
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteHealth getSatelliteHealth();
+ method @NonNull public android.location.KeplerianOrbitModel getSatelliteOrbitModel();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.BeidouSatelliteEphemeris> CREATOR;
+ }
+
+ public static final class BeidouSatelliteEphemeris.BeidouSatelliteClockModel implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=-0.00977F, to=0.00977f) public double getAf0();
+ method @FloatRange(from=-1.87E-9F, to=1.87E-9f) public double getAf1();
+ method @FloatRange(from=-1.39E-17F, to=1.39E-17f) public double getAf2();
+ method @IntRange(from=0, to=31) public int getAodc();
+ method @FloatRange(from=-5.12E-8F, to=5.12E-8f) public double getTgd1();
+ method @FloatRange(from=-5.12E-8F, to=5.12E-8f) public double getTgd2();
+ method @IntRange(from=0) public long getTimeOfClockSeconds();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel> CREATOR;
+ }
+
+ public static final class BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder {
+ ctor public BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder();
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel build();
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setAf0(@FloatRange(from=-0.00977F, to=0.00977f) double);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setAf1(@FloatRange(from=-1.87E-9F, to=1.87E-9f) double);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setAf2(@FloatRange(from=-1.39E-17F, to=1.39E-17f) double);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setAodc(@IntRange(from=0, to=31) int);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setTgd1(@FloatRange(from=-5.12E-8F, to=5.12E-8f) double);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setTgd2(@FloatRange(from=-5.12E-8F, to=5.12E-8f) double);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel.Builder setTimeOfClockSeconds(@IntRange(from=0) long);
+ }
+
+ public static final class BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime implements android.os.Parcelable {
+ method public int describeContents();
+ method @IntRange(from=0) public int getBeidouWeekNumber();
+ method @IntRange(from=0, to=31) public int getIode();
+ method @IntRange(from=0, to=604792) public int getToeSeconds();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime> CREATOR;
+ }
+
+ public static final class BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime.Builder {
+ ctor public BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime.Builder();
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime build();
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime.Builder setBeidouWeekNumber(@IntRange(from=0) int);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime.Builder setIode(int);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime.Builder setToeSeconds(@IntRange(from=0, to=604792) int);
+ }
+
+ public static final class BeidouSatelliteEphemeris.BeidouSatelliteHealth implements android.os.Parcelable {
+ method public int describeContents();
+ method @IntRange(from=0, to=1) public int getSatH1();
+ method @FloatRange(from=0.0f, to=8192.0f) public double getSvAccur();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.BeidouSatelliteEphemeris.BeidouSatelliteHealth> CREATOR;
+ }
+
+ public static final class BeidouSatelliteEphemeris.BeidouSatelliteHealth.Builder {
+ ctor public BeidouSatelliteEphemeris.BeidouSatelliteHealth.Builder();
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteHealth build();
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteHealth.Builder setSatH1(int);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.BeidouSatelliteHealth.Builder setSvAccur(double);
+ }
+
+ public static final class BeidouSatelliteEphemeris.Builder {
+ ctor public BeidouSatelliteEphemeris.Builder();
+ method @NonNull public android.location.BeidouSatelliteEphemeris build();
+ method @NonNull public android.location.BeidouSatelliteEphemeris.Builder setPrn(int);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.Builder setSatelliteClockModel(@NonNull android.location.BeidouSatelliteEphemeris.BeidouSatelliteClockModel);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.Builder setSatelliteEphemerisTime(@NonNull android.location.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.Builder setSatelliteHealth(@NonNull android.location.BeidouSatelliteEphemeris.BeidouSatelliteHealth);
+ method @NonNull public android.location.BeidouSatelliteEphemeris.Builder setSatelliteOrbitModel(@NonNull android.location.KeplerianOrbitModel);
+ }
+
public final class CorrelationVector implements android.os.Parcelable {
method public int describeContents();
method @FloatRange(from=0.0f) public double getFrequencyOffsetMetersPerSecond();
@@ -43,12 +148,375 @@
method public void unregisterCountryDetectorCallback(@NonNull java.util.function.Consumer<android.location.Country>);
}
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GalileoAssistance implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public android.location.GnssAlmanac getAlmanac();
+ method @Nullable public android.location.KlobucharIonosphericModel getIonosphericModel();
+ method @Nullable public android.location.LeapSecondsModel getLeapSecondsModel();
+ method @NonNull public java.util.List<android.location.RealTimeIntegrityModel> getRealTimeIntegrityModels();
+ method @NonNull public java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections> getSatelliteCorrections();
+ method @NonNull public java.util.List<android.location.GalileoSatelliteEphemeris> getSatelliteEphemeris();
+ method @NonNull public java.util.List<android.location.TimeModel> getTimeModels();
+ method @Nullable public android.location.UtcModel getUtcModel();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GalileoAssistance> CREATOR;
+ }
+
+ public static final class GalileoAssistance.Builder {
+ ctor public GalileoAssistance.Builder();
+ method @NonNull public android.location.GalileoAssistance build();
+ method @NonNull public android.location.GalileoAssistance.Builder setAlmanac(@Nullable android.location.GnssAlmanac);
+ method @NonNull public android.location.GalileoAssistance.Builder setIonosphericModel(@Nullable android.location.KlobucharIonosphericModel);
+ method @NonNull public android.location.GalileoAssistance.Builder setLeapSecondsModel(@Nullable android.location.LeapSecondsModel);
+ method @NonNull public android.location.GalileoAssistance.Builder setRealTimeIntegrityModels(@Nullable java.util.List<android.location.RealTimeIntegrityModel>);
+ method @NonNull public android.location.GalileoAssistance.Builder setSatelliteCorrections(@Nullable java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections>);
+ method @NonNull public android.location.GalileoAssistance.Builder setSatelliteEphemeris(@Nullable java.util.List<android.location.GalileoSatelliteEphemeris>);
+ method @NonNull public android.location.GalileoAssistance.Builder setTimeModels(@Nullable java.util.List<android.location.TimeModel>);
+ method @NonNull public android.location.GalileoAssistance.Builder setUtcModel(@Nullable android.location.UtcModel);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GalileoIonosphericModel implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=0.0f, to=512.0f) public double getAi0();
+ method @FloatRange(from=-4.0F, to=4.0f) public double getAi1();
+ method @FloatRange(from=-0.5F, to=0.5f) public double getAi2();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GalileoIonosphericModel> CREATOR;
+ }
+
+ public static final class GalileoIonosphericModel.Builder {
+ ctor public GalileoIonosphericModel.Builder();
+ method @NonNull public android.location.GalileoIonosphericModel build();
+ method @NonNull public android.location.GalileoIonosphericModel.Builder setAi0(@FloatRange(from=0.0f, to=512.0f) double);
+ method @NonNull public android.location.GalileoIonosphericModel.Builder setAi1(@FloatRange(from=-4.0F, to=4.0f) double);
+ method @NonNull public android.location.GalileoIonosphericModel.Builder setAi2(@FloatRange(from=-0.5F, to=0.5f) double);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GalileoSatelliteEphemeris implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public java.util.List<android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel> getSatelliteClockModels();
+ method @IntRange(from=1, to=36) public int getSatelliteCodeNumber();
+ method @NonNull public android.location.SatelliteEphemerisTime getSatelliteEphemerisTime();
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth getSatelliteHealth();
+ method @NonNull public android.location.KeplerianOrbitModel getSatelliteOrbitModel();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GalileoSatelliteEphemeris> CREATOR;
+ }
+
+ public static final class GalileoSatelliteEphemeris.Builder {
+ ctor public GalileoSatelliteEphemeris.Builder();
+ method @NonNull public android.location.GalileoSatelliteEphemeris build();
+ method @NonNull public android.location.GalileoSatelliteEphemeris.Builder setSatelliteClockModels(@NonNull java.util.List<android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel>);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.Builder setSatelliteCodeNumber(@IntRange(from=1, to=36) int);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.Builder setSatelliteEphemerisTime(@NonNull android.location.SatelliteEphemerisTime);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.Builder setSatelliteHealth(@NonNull android.location.GalileoSatelliteEphemeris.GalileoSvHealth);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.Builder setSatelliteOrbitModel(@NonNull android.location.KeplerianOrbitModel);
+ }
+
+ public static final class GalileoSatelliteEphemeris.GalileoSatelliteClockModel implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=-0.0625F, to=0.0625f) public double getAf0();
+ method @FloatRange(from=-1.5E-8F, to=1.5E-8f) public double getAf1();
+ method @FloatRange(from=-5.56E-17F, to=5.56E-17f) public double getAf2();
+ method @FloatRange(from=-1.2E-7F, to=1.2E-7f) public double getBgdSeconds();
+ method public int getSatelliteClockType();
+ method @FloatRange(from=0.0f) public double getSisaMeters();
+ method @IntRange(from=0) public long getTimeOfClockSeconds();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel> CREATOR;
+ field public static final int TYPE_FNAV = 1; // 0x1
+ field public static final int TYPE_INAV = 2; // 0x2
+ field public static final int TYPE_UNDEFINED = 0; // 0x0
+ }
+
+ public static final class GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder {
+ ctor public GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder();
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel build();
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setAf0(@FloatRange(from=-0.0625F, to=0.0625f) double);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setAf1(@FloatRange(from=-1.5E-8F, to=1.5E-8f) double);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setAf2(@FloatRange(from=-5.56E-17F, to=5.56E-17f) double);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setBgdSeconds(@FloatRange(from=-1.2E-7F, to=1.2E-7f) double);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setSatelliteClockType(int);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setSisaMeters(@FloatRange(from=0.0f) double);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.Builder setTimeOfClockSeconds(@IntRange(from=0) long);
+ }
+
+ public static final class GalileoSatelliteEphemeris.GalileoSvHealth implements android.os.Parcelable {
+ method public int describeContents();
+ method @IntRange(from=0, to=1) public int getDataValidityStatusE1b();
+ method @IntRange(from=0, to=1) public int getDataValidityStatusE5a();
+ method @IntRange(from=0, to=1) public int getDataValidityStatusE5b();
+ method @IntRange(from=0, to=3) public int getSignalHealthStatusE1b();
+ method @IntRange(from=0, to=3) public int getSignalHealthStatusE5a();
+ method @IntRange(from=0, to=3) public int getSignalHealthStatusE5b();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GalileoSatelliteEphemeris.GalileoSvHealth> CREATOR;
+ }
+
+ public static final class GalileoSatelliteEphemeris.GalileoSvHealth.Builder {
+ ctor public GalileoSatelliteEphemeris.GalileoSvHealth.Builder();
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth build();
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth.Builder setDataValidityStatusE1b(@IntRange(from=0, to=1) int);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth.Builder setDataValidityStatusE5a(@IntRange(from=0, to=1) int);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth.Builder setDataValidityStatusE5b(@IntRange(from=0, to=1) int);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth.Builder setSignalHealthStatusE1b(@IntRange(from=0, to=3) int);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth.Builder setSignalHealthStatusE5a(@IntRange(from=0, to=3) int);
+ method @NonNull public android.location.GalileoSatelliteEphemeris.GalileoSvHealth.Builder setSignalHealthStatusE5b(@IntRange(from=0, to=3) int);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GlonassAlmanac implements android.os.Parcelable {
+ ctor public GlonassAlmanac(@IntRange(from=0) long, @NonNull java.util.List<android.location.GlonassAlmanac.GlonassSatelliteAlmanac>);
+ method public int describeContents();
+ method @IntRange(from=0) public long getIssueDateMillis();
+ method @NonNull public java.util.List<android.location.GlonassAlmanac.GlonassSatelliteAlmanac> getSatelliteAlmanacs();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GlonassAlmanac> CREATOR;
+ }
+
+ public static final class GlonassAlmanac.GlonassSatelliteAlmanac implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=-0.067F, to=0.067f) public double getDeltaI();
+ method @FloatRange(from=-3600.0F, to=3600.0f) public double getDeltaT();
+ method @FloatRange(from=-0.004F, to=0.004f) public double getDeltaTDot();
+ method @FloatRange(from=0.0f, to=0.03f) public double getEccentricity();
+ method @IntRange(from=0, to=31) public int getFreqChannel();
+ method @FloatRange(from=-1.0F, to=1.0f) public double getLambda();
+ method @FloatRange(from=-1.0F, to=1.0f) public double getOmega();
+ method @IntRange(from=1, to=25) public int getSlotNumber();
+ method @IntRange(from=0, to=1) public int getSvHealth();
+ method @FloatRange(from=0.0f, to=44100.0f) public double getTLambda();
+ method @FloatRange(from=-0.0019F, to=0.0019f) public double getTau();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GlonassAlmanac.GlonassSatelliteAlmanac> CREATOR;
+ }
+
+ public static final class GlonassAlmanac.GlonassSatelliteAlmanac.Builder {
+ ctor public GlonassAlmanac.GlonassSatelliteAlmanac.Builder();
+ method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac build();
+ method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setDeltaI(@FloatRange(from=-0.067F, to=0.067f) double);
+ method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setDeltaT(@FloatRange(from=-3600.0F, to=3600.0f) double);
+ method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setDeltaTDot(@FloatRange(from=-0.004F, to=0.004f) double);
+ method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setEccentricity(@FloatRange(from=0.0f, to=0.03f) double);
+ method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setFreqChannel(@IntRange(from=0, to=31) int);
+ method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setLambda(@FloatRange(from=-1.0F, to=1.0f) double);
+ method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setOmega(@FloatRange(from=-1.0F, to=1.0f) double);
+ method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setSlotNumber(@IntRange(from=1, to=25) int);
+ method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setSvHealth(@IntRange(from=0, to=1) int);
+ method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setTLambda(@FloatRange(from=0.0f, to=44100.0f) double);
+ method @NonNull public android.location.GlonassAlmanac.GlonassSatelliteAlmanac.Builder setTau(@FloatRange(from=-0.0019F, to=0.0019f) double);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GlonassAssistance implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public android.location.GlonassAlmanac getAlmanac();
+ method @NonNull public java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections> getSatelliteCorrections();
+ method @NonNull public java.util.List<android.location.GlonassSatelliteEphemeris> getSatelliteEphemeris();
+ method @NonNull public java.util.List<android.location.TimeModel> getTimeModels();
+ method @Nullable public android.location.UtcModel getUtcModel();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GlonassAssistance> CREATOR;
+ }
+
+ public static final class GlonassAssistance.Builder {
+ ctor public GlonassAssistance.Builder();
+ method @NonNull public android.location.GlonassAssistance build();
+ method @NonNull public android.location.GlonassAssistance.Builder setAlmanac(@Nullable android.location.GlonassAlmanac);
+ method @NonNull public android.location.GlonassAssistance.Builder setSatelliteCorrections(@Nullable java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections>);
+ method @NonNull public android.location.GlonassAssistance.Builder setSatelliteEphemeris(@Nullable java.util.List<android.location.GlonassSatelliteEphemeris>);
+ method @NonNull public android.location.GlonassAssistance.Builder setTimeModels(@Nullable java.util.List<android.location.TimeModel>);
+ method @NonNull public android.location.GlonassAssistance.Builder setUtcModel(@Nullable android.location.UtcModel);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GlonassSatelliteEphemeris implements android.os.Parcelable {
+ method public int describeContents();
+ method @IntRange(from=0, to=31) public int getAgeInDays();
+ method @FloatRange(from=0.0f) public double getFrameTimeSeconds();
+ method @IntRange(from=0, to=1) public int getHealthState();
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel getSatelliteClockModel();
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel getSatelliteOrbitModel();
+ method @IntRange(from=1, to=25) public int getSlotNumber();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GlonassSatelliteEphemeris> CREATOR;
+ }
+
+ public static final class GlonassSatelliteEphemeris.Builder {
+ ctor public GlonassSatelliteEphemeris.Builder();
+ method @NonNull public android.location.GlonassSatelliteEphemeris build();
+ method @NonNull public android.location.GlonassSatelliteEphemeris.Builder setAgeInDays(@IntRange(from=0, to=31) int);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.Builder setFrameTimeSeconds(@FloatRange(from=0.0f) double);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.Builder setHealthState(@IntRange(from=0, to=1) int);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.Builder setSatelliteClockModel(@NonNull android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.Builder setSatelliteOrbitModel(@NonNull android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.Builder setSlotNumber(@IntRange(from=1, to=25) int);
+ }
+
+ public static final class GlonassSatelliteEphemeris.GlonassSatelliteClockModel implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=-0.002F, to=0.002f) public double getClockBias();
+ method @FloatRange(from=-9.32E-10F, to=9.32E-10f) public double getFrequencyBias();
+ method @IntRange(from=0xfffffff9, to=6) public int getFrequencyNumber();
+ method @IntRange(from=0) public long getTimeOfClockSeconds();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel> CREATOR;
+ }
+
+ public static final class GlonassSatelliteEphemeris.GlonassSatelliteClockModel.Builder {
+ ctor public GlonassSatelliteEphemeris.GlonassSatelliteClockModel.Builder();
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel build();
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel.Builder setClockBias(@FloatRange(from=-0.002F, to=0.002f) double);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel.Builder setFrequencyBias(@FloatRange(from=-9.32E-10F, to=9.32E-10f) double);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel.Builder setFrequencyNumber(@IntRange(from=0xfffffff9, to=6) int);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteClockModel.Builder setTimeOfClockSeconds(@IntRange(from=0) long);
+ }
+
+ public static final class GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=-27000.0F, to=27000.0f) public double getX();
+ method @FloatRange(from=-6.2E-9F, to=6.2E-9f) public double getXAccel();
+ method @FloatRange(from=-4.3F, to=4.3f) public double getXDot();
+ method @FloatRange(from=-27000.0F, to=27000.0f) public double getY();
+ method @FloatRange(from=-6.2E-9F, to=6.2E-9f) public double getYAccel();
+ method @FloatRange(from=-4.3F, to=4.3f) public double getYDot();
+ method @FloatRange(from=-27000.0F, to=27000.0f) public double getZ();
+ method @FloatRange(from=-6.2E-9F, to=6.2E-9f) public double getZAccel();
+ method @FloatRange(from=-4.3F, to=4.3f) public double getZDot();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel> CREATOR;
+ }
+
+ public static final class GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder {
+ ctor public GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder();
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel build();
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setX(@FloatRange(from=-27000.0F, to=27000.0f) double);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setXAccel(@FloatRange(from=-6.2E-9F, to=6.2E-9f) double);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setXDot(@FloatRange(from=-4.3F, to=4.3f) double);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setY(@FloatRange(from=-27000.0F, to=27000.0f) double);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setYAccel(@FloatRange(from=-6.2E-9F, to=6.2E-9f) double);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setYDot(@FloatRange(from=-4.3F, to=4.3f) double);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setZ(@FloatRange(from=-27000.0F, to=27000.0f) double);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setZAccel(@FloatRange(from=-6.2E-9F, to=6.2E-9f) double);
+ method @NonNull public android.location.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel.Builder setZDot(@FloatRange(from=-4.3F, to=4.3f) double);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GnssAlmanac implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public java.util.List<android.location.GnssAlmanac.GnssSatelliteAlmanac> getGnssSatelliteAlmanacs();
+ method @IntRange(from=0) public int getIod();
+ method @IntRange(from=0) public long getIssueDateMillis();
+ method @IntRange(from=0, to=604800) public int getToaSeconds();
+ method @IntRange(from=0) public int getWeekNumber();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssAlmanac> CREATOR;
+ }
+
+ public static final class GnssAlmanac.Builder {
+ ctor public GnssAlmanac.Builder();
+ method @NonNull public android.location.GnssAlmanac build();
+ method @NonNull public android.location.GnssAlmanac.Builder setGnssSatelliteAlmanacs(@NonNull java.util.List<android.location.GnssAlmanac.GnssSatelliteAlmanac>);
+ method @NonNull public android.location.GnssAlmanac.Builder setIod(@IntRange(from=0) int);
+ method @NonNull public android.location.GnssAlmanac.Builder setIssueDateMillis(@IntRange(from=0) long);
+ method @NonNull public android.location.GnssAlmanac.Builder setToaSeconds(@IntRange(from=0, to=604800) int);
+ method @NonNull public android.location.GnssAlmanac.Builder setWeekNumber(@IntRange(from=0) int);
+ }
+
+ public static final class GnssAlmanac.GnssSatelliteAlmanac implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=-0.0625F, to=0.0625f) public double getAf0();
+ method @FloatRange(from=-1.5E-8F, to=1.5E-8f) public double getAf1();
+ method @FloatRange(from=0.0f) public double getEccentricity();
+ method @FloatRange(from=-1.0F, to=1.0f) public double getInclination();
+ method @FloatRange(from=-1.0F, to=1.0f) public double getM0();
+ method @FloatRange(from=-1.0F, to=1.0f) public double getOmega();
+ method @FloatRange(from=-1.0F, to=1.0f) public double getOmega0();
+ method @FloatRange(from=-1.0F, to=1.0f) public double getOmegaDot();
+ method @FloatRange(from=0.0f, to=8192.0f) public double getRootA();
+ method @IntRange(from=0) public int getSvHealth();
+ method @IntRange(from=1) public int getSvid();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssAlmanac.GnssSatelliteAlmanac> CREATOR;
+ }
+
+ public static final class GnssAlmanac.GnssSatelliteAlmanac.Builder {
+ ctor public GnssAlmanac.GnssSatelliteAlmanac.Builder();
+ method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac build();
+ method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setAf0(@FloatRange(from=-0.0625F, to=0.0625f) double);
+ method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setAf1(@FloatRange(from=-1.5E-8F, to=1.5E-8f) double);
+ method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setEccentricity(@FloatRange(from=0.0f) double);
+ method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setInclination(@FloatRange(from=-1.0F, to=1.0f) double);
+ method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setM0(@FloatRange(from=-1.0F, to=1.0f) double);
+ method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setOmega(@FloatRange(from=-1.0F, to=1.0f) double);
+ method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setOmega0(@FloatRange(from=-1.0F, to=1.0f) double);
+ method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setOmegaDot(@FloatRange(from=-1.0F, to=1.0f) double);
+ method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setRootA(@FloatRange(from=0.0f, to=8192.0f) double);
+ method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setSvHealth(@IntRange(from=0) int);
+ method @NonNull public android.location.GnssAlmanac.GnssSatelliteAlmanac.Builder setSvid(@IntRange(from=1) int);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GnssAssistance implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public android.location.BeidouAssistance getBeidouAssistance();
+ method @Nullable public android.location.GalileoAssistance getGalileoAssistance();
+ method @Nullable public android.location.GlonassAssistance getGlonassAssistance();
+ method @Nullable public android.location.GpsAssistance getGpsAssistance();
+ method @Nullable public android.location.QzssAssistance getQzssAssistance();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssAssistance> CREATOR;
+ }
+
+ public static final class GnssAssistance.Builder {
+ ctor public GnssAssistance.Builder();
+ method @NonNull public android.location.GnssAssistance build();
+ method @NonNull public android.location.GnssAssistance.Builder setBeidouAssistance(@Nullable android.location.BeidouAssistance);
+ method @NonNull public android.location.GnssAssistance.Builder setGalileoAssistance(@Nullable android.location.GalileoAssistance);
+ method @NonNull public android.location.GnssAssistance.Builder setGlonassAssistance(@Nullable android.location.GlonassAssistance);
+ method @NonNull public android.location.GnssAssistance.Builder setGpsAssistance(@Nullable android.location.GpsAssistance);
+ method @NonNull public android.location.GnssAssistance.Builder setQzssAssistance(@Nullable android.location.QzssAssistance);
+ }
+
+ public static final class GnssAssistance.GnssSatelliteCorrections implements android.os.Parcelable {
+ ctor public GnssAssistance.GnssSatelliteCorrections(@IntRange(from=1, to=206) int, @NonNull java.util.List<android.location.IonosphericCorrection>);
+ method public int describeContents();
+ method @NonNull public java.util.List<android.location.IonosphericCorrection> getIonosphericCorrections();
+ method @IntRange(from=1, to=206) public int getSvid();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssAssistance.GnssSatelliteCorrections> CREATOR;
+ }
+
public final class GnssCapabilities implements android.os.Parcelable {
method @Deprecated public boolean hasMeasurementCorrectionsReflectingPane();
method @Deprecated public boolean hasNavMessages();
method @Deprecated public boolean hasSatelliteBlacklist();
}
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GnssCorrectionComponent implements android.os.Parcelable {
+ ctor public GnssCorrectionComponent(@NonNull String, @NonNull android.location.GnssCorrectionComponent.GnssInterval, @NonNull android.location.GnssCorrectionComponent.PseudorangeCorrection);
+ method public int describeContents();
+ method @NonNull public android.location.GnssCorrectionComponent.PseudorangeCorrection getPseudorangeCorrection();
+ method @NonNull public String getSourceKey();
+ method @NonNull public android.location.GnssCorrectionComponent.GnssInterval getValidityInterval();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssCorrectionComponent> CREATOR;
+ }
+
+ public static final class GnssCorrectionComponent.GnssInterval implements android.os.Parcelable {
+ ctor public GnssCorrectionComponent.GnssInterval(@IntRange(from=0) long, @IntRange(from=0) long);
+ method public int describeContents();
+ method @IntRange(from=0) public long getEndMillisSinceGpsEpoch();
+ method @IntRange(from=0) public long getStartMillisSinceGpsEpoch();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssCorrectionComponent.GnssInterval> CREATOR;
+ }
+
+ public static final class GnssCorrectionComponent.PseudorangeCorrection implements android.os.Parcelable {
+ ctor public GnssCorrectionComponent.PseudorangeCorrection(double, double, double);
+ method public int describeContents();
+ method public double getCorrectionMeters();
+ method public double getCorrectionRateMetersPerSecond();
+ method @FloatRange(from=0.0f) public double getCorrectionUncertaintyMeters();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssCorrectionComponent.PseudorangeCorrection> CREATOR;
+ }
+
public final class GnssExcessPathInfo implements android.os.Parcelable {
method public int describeContents();
method @FloatRange(from=0.0f) public float getAttenuationDb();
@@ -193,6 +661,33 @@
method @NonNull public android.location.GnssSingleSatCorrection.Builder setSatelliteId(@IntRange(from=0) int);
}
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GpsAssistance implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public android.location.GnssAlmanac getAlmanac();
+ method @Nullable public android.location.KlobucharIonosphericModel getIonosphericModel();
+ method @Nullable public android.location.LeapSecondsModel getLeapSecondsModel();
+ method @NonNull public java.util.List<android.location.RealTimeIntegrityModel> getRealTimeIntegrityModels();
+ method @NonNull public java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections> getSatelliteCorrections();
+ method @NonNull public java.util.List<android.location.GpsSatelliteEphemeris> getSatelliteEphemeris();
+ method @NonNull public java.util.List<android.location.TimeModel> getTimeModels();
+ method @Nullable public android.location.UtcModel getUtcModel();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GpsAssistance> CREATOR;
+ }
+
+ public static final class GpsAssistance.Builder {
+ ctor public GpsAssistance.Builder();
+ method @NonNull public android.location.GpsAssistance build();
+ method @NonNull public android.location.GpsAssistance.Builder setAlmanac(@Nullable android.location.GnssAlmanac);
+ method @NonNull public android.location.GpsAssistance.Builder setIonosphericModel(@Nullable android.location.KlobucharIonosphericModel);
+ method @NonNull public android.location.GpsAssistance.Builder setLeapSecondsModel(@Nullable android.location.LeapSecondsModel);
+ method @NonNull public android.location.GpsAssistance.Builder setRealTimeIntegrityModels(@Nullable java.util.List<android.location.RealTimeIntegrityModel>);
+ method @NonNull public android.location.GpsAssistance.Builder setSatelliteCorrections(@Nullable java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections>);
+ method @NonNull public android.location.GpsAssistance.Builder setSatelliteEphemeris(@Nullable java.util.List<android.location.GpsSatelliteEphemeris>);
+ method @NonNull public android.location.GpsAssistance.Builder setTimeModels(@Nullable java.util.List<android.location.TimeModel>);
+ method @NonNull public android.location.GpsAssistance.Builder setUtcModel(@Nullable android.location.UtcModel);
+ }
+
@Deprecated public class GpsClock implements android.os.Parcelable {
method @Deprecated public int describeContents();
method @Deprecated public double getBiasInNs();
@@ -418,6 +913,174 @@
method @Deprecated public void onStatusChanged(int);
}
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class GpsSatelliteEphemeris implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsL2Params getGpsL2Params();
+ method @IntRange(from=1, to=32) public int getPrn();
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel getSatelliteClockModel();
+ method @NonNull public android.location.SatelliteEphemerisTime getSatelliteEphemerisTime();
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteHealth getSatelliteHealth();
+ method @NonNull public android.location.KeplerianOrbitModel getSatelliteOrbitModel();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GpsSatelliteEphemeris> CREATOR;
+ }
+
+ public static final class GpsSatelliteEphemeris.Builder {
+ ctor public GpsSatelliteEphemeris.Builder();
+ method @NonNull public android.location.GpsSatelliteEphemeris build();
+ method @NonNull public android.location.GpsSatelliteEphemeris.Builder setGpsL2Params(@NonNull android.location.GpsSatelliteEphemeris.GpsL2Params);
+ method @NonNull public android.location.GpsSatelliteEphemeris.Builder setPrn(@IntRange(from=1, to=32) int);
+ method @NonNull public android.location.GpsSatelliteEphemeris.Builder setSatelliteClockModel(@NonNull android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel);
+ method @NonNull public android.location.GpsSatelliteEphemeris.Builder setSatelliteEphemerisTime(@NonNull android.location.SatelliteEphemerisTime);
+ method @NonNull public android.location.GpsSatelliteEphemeris.Builder setSatelliteHealth(@NonNull android.location.GpsSatelliteEphemeris.GpsSatelliteHealth);
+ method @NonNull public android.location.GpsSatelliteEphemeris.Builder setSatelliteOrbitModel(@NonNull android.location.KeplerianOrbitModel);
+ }
+
+ public static final class GpsSatelliteEphemeris.GpsL2Params implements android.os.Parcelable {
+ method public int describeContents();
+ method @IntRange(from=0, to=3) public int getL2Code();
+ method @IntRange(from=0, to=1) public int getL2Flag();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GpsSatelliteEphemeris.GpsL2Params> CREATOR;
+ }
+
+ public static final class GpsSatelliteEphemeris.GpsL2Params.Builder {
+ ctor public GpsSatelliteEphemeris.GpsL2Params.Builder();
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsL2Params build();
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsL2Params.Builder setL2Code(@IntRange(from=0, to=3) int);
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsL2Params.Builder setL2Flag(@IntRange(from=0, to=1) int);
+ }
+
+ public static final class GpsSatelliteEphemeris.GpsSatelliteClockModel implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=-0.00977F, to=0.00977f) public double getAf0();
+ method @FloatRange(from=-3.73E-9F, to=3.73E-9f) public double getAf1();
+ method @FloatRange(from=-3.56E-15F, to=3.56E-15f) public double getAf2();
+ method @IntRange(from=0, to=1023) public int getIodc();
+ method @FloatRange(from=-5.97E-8F, to=5.97E-8f) public double getTgd();
+ method @IntRange(from=0) public long getTimeOfClockSeconds();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel> CREATOR;
+ }
+
+ public static final class GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder {
+ ctor public GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder();
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel build();
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder setAf0(@FloatRange(from=-0.00977F, to=0.00977f) double);
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder setAf1(@FloatRange(from=-3.73E-9F, to=3.73E-9f) double);
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder setAf2(@FloatRange(from=-3.56E-15F, to=3.56E-15f) double);
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder setIodc(@IntRange(from=0, to=1023) int);
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder setTgd(@FloatRange(from=-5.97E-8F, to=5.97E-8f) double);
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel.Builder setTimeOfClockSeconds(@IntRange(from=0) long);
+ }
+
+ public static final class GpsSatelliteEphemeris.GpsSatelliteHealth implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=0.0f) public double getFitInt();
+ method @FloatRange(from=0.0f, to=8192.0f) public double getSvAccur();
+ method @IntRange(from=0, to=63) public int getSvHealth();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.GpsSatelliteEphemeris.GpsSatelliteHealth> CREATOR;
+ }
+
+ public static final class GpsSatelliteEphemeris.GpsSatelliteHealth.Builder {
+ ctor public GpsSatelliteEphemeris.GpsSatelliteHealth.Builder();
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteHealth build();
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteHealth.Builder setFitInt(@FloatRange(from=0.0f) double);
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteHealth.Builder setSvAccur(@FloatRange(from=0.0f, to=8192.0f) double);
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteHealth.Builder setSvHealth(@IntRange(from=0, to=63) int);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class IonosphericCorrection implements android.os.Parcelable {
+ ctor public IonosphericCorrection(@IntRange(from=0) long, @NonNull android.location.GnssCorrectionComponent);
+ method public int describeContents();
+ method @IntRange(from=0) public long getCarrierFrequencyHz();
+ method @NonNull public android.location.GnssCorrectionComponent getIonosphericCorrection();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.IonosphericCorrection> CREATOR;
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class KeplerianOrbitModel implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=-1.18E-8F, to=1.18E-8f) public double getDeltaN();
+ method @FloatRange(from=0.0f, to=0.5f) public double getEccentricity();
+ method @FloatRange(from=-3.15F, to=3.15f) public double getI0();
+ method @FloatRange(from=-2.94E-9F, to=2.94E-9f) public double getIDot();
+ method @FloatRange(from=-3.15F, to=3.15f) public double getM0();
+ method @FloatRange(from=-3.15F, to=3.15f) public double getOmega();
+ method @FloatRange(from=-3.15F, to=3.15f) public double getOmega0();
+ method @FloatRange(from=-3.1E-6F, to=3.1E-6f) public double getOmegaDot();
+ method @FloatRange(from=0.0f, to=8192.0f) public double getRootA();
+ method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation getSecondOrderHarmonicPerturbation();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.KeplerianOrbitModel> CREATOR;
+ }
+
+ public static final class KeplerianOrbitModel.Builder {
+ ctor public KeplerianOrbitModel.Builder();
+ method @NonNull public android.location.KeplerianOrbitModel build();
+ method @NonNull public android.location.KeplerianOrbitModel.Builder setDeltaN(@FloatRange(from=-1.18E-8F, to=1.18E-8f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.Builder setEccentricity(@FloatRange(from=0.0f, to=0.5f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.Builder setI0(@FloatRange(from=-3.15F, to=3.15f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.Builder setIDot(@FloatRange(from=-2.94E-9F, to=2.94E-9f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.Builder setM0(@FloatRange(from=-3.15F, to=3.15f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.Builder setOmega(@FloatRange(from=-3.15F, to=3.15f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.Builder setOmega0(@FloatRange(from=-3.15F, to=3.15f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.Builder setOmegaDot(@FloatRange(from=-3.1E-6F, to=3.1E-6f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.Builder setRootA(@FloatRange(from=0.0f, to=8192.0f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.Builder setSecondOrderHarmonicPerturbation(@NonNull android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation);
+ }
+
+ public static final class KeplerianOrbitModel.SecondOrderHarmonicPerturbation implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=-6.11E-5F, to=6.11E-5f) public double getCic();
+ method @FloatRange(from=-6.11E-5F, to=6.11E-5f) public double getCis();
+ method @FloatRange(from=-2048.0F, to=2048.0f) public double getCrc();
+ method @FloatRange(from=-2048.0F, to=2048.0f) public double getCrs();
+ method @FloatRange(from=-6.11E-5F, to=6.11E-5f) public double getCuc();
+ method @FloatRange(from=-6.11E-5F, to=6.11E-5f) public double getCus();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation> CREATOR;
+ }
+
+ public static final class KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder {
+ ctor public KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder();
+ method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation build();
+ method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder setCic(@FloatRange(from=-6.11E-5F, to=6.11E-5f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder setCis(@FloatRange(from=-6.11E-5F, to=6.11E-5f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder setCrc(@FloatRange(from=-2048.0F, to=2048.0f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder setCrs(@FloatRange(from=-2048.0F, to=2048.0f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder setCuc(@FloatRange(from=-6.11E-5F, to=6.11E-5f) double);
+ method @NonNull public android.location.KeplerianOrbitModel.SecondOrderHarmonicPerturbation.Builder setCus(@FloatRange(from=-6.11E-5F, to=6.11E-5f) double);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class KlobucharIonosphericModel implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=-1.193E-7F, to=1.193E-7f) public double getAlpha0();
+ method @FloatRange(from=-9.54E-7F, to=9.54E-7f) public double getAlpha1();
+ method @FloatRange(from=-7.63E-6F, to=7.63E-6f) public double getAlpha2();
+ method @FloatRange(from=-7.63E-6F, to=7.63E-6f) public double getAlpha3();
+ method @FloatRange(from=-262144.0F, to=262144.0f) public double getBeta0();
+ method @FloatRange(from=-2097152.0F, to=2097152.0f) public double getBeta1();
+ method @FloatRange(from=-8388608.0F, to=8388608.0f) public double getBeta2();
+ method @FloatRange(from=-8388608.0F, to=8388608.0f) public double getBeta3();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.KlobucharIonosphericModel> CREATOR;
+ }
+
+ public static final class KlobucharIonosphericModel.Builder {
+ ctor public KlobucharIonosphericModel.Builder();
+ method @NonNull public android.location.KlobucharIonosphericModel build();
+ method @NonNull public android.location.KlobucharIonosphericModel.Builder setAlpha0(@FloatRange(from=-1.193E-7F, to=1.193E-7f) double);
+ method @NonNull public android.location.KlobucharIonosphericModel.Builder setAlpha1(@FloatRange(from=-9.54E-7F, to=9.54E-7f) double);
+ method @NonNull public android.location.KlobucharIonosphericModel.Builder setAlpha2(@FloatRange(from=-7.63E-6F, to=7.63E-6f) double);
+ method @NonNull public android.location.KlobucharIonosphericModel.Builder setAlpha3(@FloatRange(from=-7.63E-6F, to=7.63E-6f) double);
+ method @NonNull public android.location.KlobucharIonosphericModel.Builder setBeta0(@FloatRange(from=-262144.0F, to=262144.0f) double);
+ method @NonNull public android.location.KlobucharIonosphericModel.Builder setBeta1(@FloatRange(from=-2097152.0F, to=2097152.0f) double);
+ method @NonNull public android.location.KlobucharIonosphericModel.Builder setBeta2(@FloatRange(from=-8388608.0F, to=8388608.0f) double);
+ method @NonNull public android.location.KlobucharIonosphericModel.Builder setBeta3(@FloatRange(from=-8388608.0F, to=8388608.0f) double);
+ }
+
public final class LastLocationRequest implements android.os.Parcelable {
method public int describeContents();
method public boolean isAdasGnssBypass();
@@ -436,6 +1099,25 @@
method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_BYPASS) public android.location.LastLocationRequest.Builder setLocationSettingsIgnored(boolean);
}
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class LeapSecondsModel implements android.os.Parcelable {
+ method public int describeContents();
+ method @IntRange(from=0) public int getDayNumberLeapSecondsFuture();
+ method @IntRange(from=0) public int getLeapSeconds();
+ method @IntRange(from=0) public int getLeapSecondsFuture();
+ method @IntRange(from=0) public int getWeekNumberLeapSecondsFuture();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.LeapSecondsModel> CREATOR;
+ }
+
+ public static final class LeapSecondsModel.Builder {
+ ctor public LeapSecondsModel.Builder();
+ method @NonNull public android.location.LeapSecondsModel build();
+ method @NonNull public android.location.LeapSecondsModel.Builder setDayNumberLeapSecondsFuture(@IntRange(from=0) int);
+ method @NonNull public android.location.LeapSecondsModel.Builder setLeapSeconds(@IntRange(from=0) int);
+ method @NonNull public android.location.LeapSecondsModel.Builder setLeapSecondsFuture(@IntRange(from=0) int);
+ method @NonNull public android.location.LeapSecondsModel.Builder setWeekNumberLeapSecondsFuture(@IntRange(from=0) int);
+ }
+
public class LocationManager {
method @Deprecated @FlaggedApi("android.location.flags.deprecate_provider_request_apis") @RequiresPermission(allOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.INTERACT_ACROSS_USERS}) public void addProviderRequestChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.location.provider.ProviderRequest.ChangedListener);
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void flushGnssBatch();
@@ -513,6 +1195,98 @@
method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.location.LocationRequest.Builder setWorkSource(@Nullable android.os.WorkSource);
}
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class QzssAssistance implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public android.location.GnssAlmanac getAlmanac();
+ method @Nullable public android.location.KlobucharIonosphericModel getIonosphericModel();
+ method @Nullable public android.location.LeapSecondsModel getLeapSecondsModel();
+ method @NonNull public java.util.List<android.location.RealTimeIntegrityModel> getRealTimeIntegrityModels();
+ method @NonNull public java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections> getSatelliteCorrections();
+ method @NonNull public java.util.List<android.location.QzssSatelliteEphemeris> getSatelliteEphemeris();
+ method @NonNull public java.util.List<android.location.TimeModel> getTimeModels();
+ method @Nullable public android.location.UtcModel getUtcModel();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.QzssAssistance> CREATOR;
+ }
+
+ public static final class QzssAssistance.Builder {
+ ctor public QzssAssistance.Builder();
+ method @NonNull public android.location.QzssAssistance build();
+ method @NonNull public android.location.QzssAssistance.Builder setAlmanac(@Nullable android.location.GnssAlmanac);
+ method @NonNull public android.location.QzssAssistance.Builder setIonosphericModel(@Nullable android.location.KlobucharIonosphericModel);
+ method @NonNull public android.location.QzssAssistance.Builder setLeapSecondsModel(@Nullable android.location.LeapSecondsModel);
+ method @NonNull public android.location.QzssAssistance.Builder setRealTimeIntegrityModels(@Nullable java.util.List<android.location.RealTimeIntegrityModel>);
+ method @NonNull public android.location.QzssAssistance.Builder setSatelliteCorrections(@Nullable java.util.List<android.location.GnssAssistance.GnssSatelliteCorrections>);
+ method @NonNull public android.location.QzssAssistance.Builder setSatelliteEphemeris(@Nullable java.util.List<android.location.QzssSatelliteEphemeris>);
+ method @NonNull public android.location.QzssAssistance.Builder setTimeModels(@Nullable java.util.List<android.location.TimeModel>);
+ method @NonNull public android.location.QzssAssistance.Builder setUtcModel(@Nullable android.location.UtcModel);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class QzssSatelliteEphemeris implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsL2Params getGpsL2Params();
+ method @IntRange(from=183, to=206) public int getPrn();
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel getSatelliteClockModel();
+ method @NonNull public android.location.SatelliteEphemerisTime getSatelliteEphemerisTime();
+ method @NonNull public android.location.GpsSatelliteEphemeris.GpsSatelliteHealth getSatelliteHealth();
+ method @NonNull public android.location.KeplerianOrbitModel getSatelliteOrbitModel();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.QzssSatelliteEphemeris> CREATOR;
+ }
+
+ public static final class QzssSatelliteEphemeris.Builder {
+ ctor public QzssSatelliteEphemeris.Builder();
+ method @NonNull public android.location.QzssSatelliteEphemeris build();
+ method @NonNull public android.location.QzssSatelliteEphemeris.Builder setGpsL2Params(@NonNull android.location.GpsSatelliteEphemeris.GpsL2Params);
+ method @NonNull public android.location.QzssSatelliteEphemeris.Builder setPrn(@IntRange(from=183, to=206) int);
+ method @NonNull public android.location.QzssSatelliteEphemeris.Builder setSatelliteClockModel(@NonNull android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel);
+ method @NonNull public android.location.QzssSatelliteEphemeris.Builder setSatelliteEphemerisTime(@NonNull android.location.SatelliteEphemerisTime);
+ method @NonNull public android.location.QzssSatelliteEphemeris.Builder setSatelliteHealth(@NonNull android.location.GpsSatelliteEphemeris.GpsSatelliteHealth);
+ method @NonNull public android.location.QzssSatelliteEphemeris.Builder setSatelliteOrbitModel(@NonNull android.location.KeplerianOrbitModel);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class RealTimeIntegrityModel implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public String getAdvisoryNumber();
+ method @NonNull public String getAdvisoryType();
+ method @IntRange(from=0) public long getEndDateSeconds();
+ method @IntRange(from=0) public long getPublishDateSeconds();
+ method @IntRange(from=0) public long getStartDateSeconds();
+ method @IntRange(from=1, to=206) public int getSvid();
+ method public boolean isUsable();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.RealTimeIntegrityModel> CREATOR;
+ }
+
+ public static final class RealTimeIntegrityModel.Builder {
+ ctor public RealTimeIntegrityModel.Builder();
+ method @NonNull public android.location.RealTimeIntegrityModel build();
+ method @NonNull public android.location.RealTimeIntegrityModel.Builder setAdvisoryNumber(@NonNull String);
+ method @NonNull public android.location.RealTimeIntegrityModel.Builder setAdvisoryType(@NonNull String);
+ method @NonNull public android.location.RealTimeIntegrityModel.Builder setEndDateSeconds(@IntRange(from=0) long);
+ method @NonNull public android.location.RealTimeIntegrityModel.Builder setPublishDateSeconds(@IntRange(from=0) long);
+ method @NonNull public android.location.RealTimeIntegrityModel.Builder setStartDateSeconds(@IntRange(from=0) long);
+ method @NonNull public android.location.RealTimeIntegrityModel.Builder setSvid(@IntRange(from=1, to=206) int);
+ method @NonNull public android.location.RealTimeIntegrityModel.Builder setUsable(boolean);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class SatelliteEphemerisTime implements android.os.Parcelable {
+ method public int describeContents();
+ method @IntRange(from=0, to=1023) public int getIode();
+ method @IntRange(from=0, to=604799) public int getToeSeconds();
+ method @IntRange(from=0) public int getWeekNumber();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.SatelliteEphemerisTime> CREATOR;
+ }
+
+ public static final class SatelliteEphemerisTime.Builder {
+ ctor public SatelliteEphemerisTime.Builder();
+ method @NonNull public android.location.SatelliteEphemerisTime build();
+ method @NonNull public android.location.SatelliteEphemerisTime.Builder setIode(@IntRange(from=0, to=1023) int);
+ method @NonNull public android.location.SatelliteEphemerisTime.Builder setToeSeconds(@IntRange(from=0, to=604799) int);
+ method @NonNull public android.location.SatelliteEphemerisTime.Builder setWeekNumber(@IntRange(from=0) int);
+ }
+
public final class SatellitePvt implements android.os.Parcelable {
method public int describeContents();
method @Nullable public android.location.SatellitePvt.ClockInfo getClockInfo();
@@ -587,6 +1361,46 @@
field @NonNull public static final android.os.Parcelable.Creator<android.location.SatellitePvt.VelocityEcef> CREATOR;
}
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class TimeModel implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=-1.0F, to=1.0f) public double getA0();
+ method @FloatRange(from=-3.28E-6F, to=3.28E-6f) public double getA1();
+ method @IntRange(from=0, to=604800) public int getTimeOfWeek();
+ method public int getToGnss();
+ method @IntRange(from=0) public int getWeekNumber();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.TimeModel> CREATOR;
+ }
+
+ public static final class TimeModel.Builder {
+ ctor public TimeModel.Builder();
+ method @NonNull public android.location.TimeModel build();
+ method @NonNull public android.location.TimeModel.Builder setA0(@FloatRange(from=-1.0F, to=1.0f) double);
+ method @NonNull public android.location.TimeModel.Builder setA1(@FloatRange(from=-3.28E-6F, to=3.28E-6f) double);
+ method @NonNull public android.location.TimeModel.Builder setTimeOfWeek(@IntRange(from=0, to=604800) int);
+ method @NonNull public android.location.TimeModel.Builder setToGnss(int);
+ method @NonNull public android.location.TimeModel.Builder setWeekNumber(@IntRange(from=0) int);
+ }
+
+ @FlaggedApi("android.location.flags.gnss_assistance_interface") public final class UtcModel implements android.os.Parcelable {
+ method public int describeContents();
+ method @FloatRange(from=-2.0F, to=2.0f) public double getA0();
+ method @FloatRange(from=-7.45E-9F, to=7.45E-9f) public double getA1();
+ method @IntRange(from=0, to=604800) public int getTimeOfWeek();
+ method @IntRange(from=0) public int getWeekNumber();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.UtcModel> CREATOR;
+ }
+
+ public static final class UtcModel.Builder {
+ ctor public UtcModel.Builder();
+ method @NonNull public android.location.UtcModel build();
+ method @NonNull public android.location.UtcModel.Builder setA0(@FloatRange(from=-2.0F, to=2.0f) double);
+ method @NonNull public android.location.UtcModel.Builder setA1(@FloatRange(from=-7.45E-9F, to=7.45E-9f) double);
+ method @NonNull public android.location.UtcModel.Builder setTimeOfWeek(@IntRange(from=0, to=604800) int);
+ method @NonNull public android.location.UtcModel.Builder setWeekNumber(@IntRange(from=0) int);
+ }
+
}
package android.location.provider {
diff --git a/location/java/android/location/BeidouAssistance.java b/location/java/android/location/BeidouAssistance.java
new file mode 100644
index 0000000..f55249e6
--- /dev/null
+++ b/location/java/android/location/BeidouAssistance.java
@@ -0,0 +1,283 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.location.GnssAssistance.GnssSatelliteCorrections;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains Beidou assistance.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class BeidouAssistance implements Parcelable {
+
+ /** The Beidou almanac. */
+ @Nullable private final GnssAlmanac mAlmanac;
+
+ /** The Klobuchar ionospheric model. */
+ @Nullable private final KlobucharIonosphericModel mIonosphericModel;
+
+ /** The UTC model. */
+ @Nullable private final UtcModel mUtcModel;
+
+ /** The leap seconds model. */
+ @Nullable private final LeapSecondsModel mLeapSecondsModel;
+
+ /** The list of time models. */
+ @NonNull private final List<TimeModel> mTimeModels;
+
+ /** The list of Beidou ephemeris. */
+ @NonNull private final List<BeidouSatelliteEphemeris> mSatelliteEphemeris;
+
+ /** The list of real time integrity models. */
+ @NonNull private final List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+
+ /** The list of Beidou satellite corrections. */
+ @NonNull private final List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+ private BeidouAssistance(Builder builder) {
+ mAlmanac = builder.mAlmanac;
+ mIonosphericModel = builder.mIonosphericModel;
+ mUtcModel = builder.mUtcModel;
+ mLeapSecondsModel = builder.mLeapSecondsModel;
+ if (builder.mTimeModels != null) {
+ mTimeModels = Collections.unmodifiableList(new ArrayList<>(builder.mTimeModels));
+ } else {
+ mTimeModels = new ArrayList<>();
+ }
+ if (builder.mSatelliteEphemeris != null) {
+ mSatelliteEphemeris =
+ Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteEphemeris));
+ } else {
+ mSatelliteEphemeris = new ArrayList<>();
+ }
+ if (builder.mRealTimeIntegrityModels != null) {
+ mRealTimeIntegrityModels =
+ Collections.unmodifiableList(new ArrayList<>(builder.mRealTimeIntegrityModels));
+ } else {
+ mRealTimeIntegrityModels = new ArrayList<>();
+ }
+ if (builder.mSatelliteCorrections != null) {
+ mSatelliteCorrections =
+ Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteCorrections));
+ } else {
+ mSatelliteCorrections = new ArrayList<>();
+ }
+ }
+
+ /** Returns the Beidou almanac. */
+ @Nullable
+ public GnssAlmanac getAlmanac() {
+ return mAlmanac;
+ }
+
+ /** Returns the Klobuchar ionospheric model. */
+ @Nullable
+ public KlobucharIonosphericModel getIonosphericModel() {
+ return mIonosphericModel;
+ }
+
+ /** Returns the UTC model. */
+ @Nullable
+ public UtcModel getUtcModel() {
+ return mUtcModel;
+ }
+
+ /** Returns the leap seconds model. */
+ @Nullable
+ public LeapSecondsModel getLeapSecondsModel() {
+ return mLeapSecondsModel;
+ }
+
+ /** Returns the list of time models. */
+ @NonNull
+ public List<TimeModel> getTimeModels() {
+ return mTimeModels;
+ }
+
+ /** Returns the list ofBeidou ephemeris. */
+ @NonNull
+ public List<BeidouSatelliteEphemeris> getSatelliteEphemeris() {
+ return mSatelliteEphemeris;
+ }
+
+ /** Returns the list of real time integrity models. */
+ @NonNull
+ public List<RealTimeIntegrityModel> getRealTimeIntegrityModels() {
+ return mRealTimeIntegrityModels;
+ }
+
+ /** Returns the list of Beidou satellite corrections. */
+ @NonNull
+ public List<GnssSatelliteCorrections> getSatelliteCorrections() {
+ return mSatelliteCorrections;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("BeidouAssistance[");
+ builder.append("almanac = ").append(mAlmanac);
+ builder.append(", ionosphericModel = ").append(mIonosphericModel);
+ builder.append(", utcModel = ").append(mUtcModel);
+ builder.append(", leapSecondsModel = ").append(mLeapSecondsModel);
+ builder.append(", timeModels = ").append(mTimeModels);
+ builder.append(", satelliteEphemeris = ").append(mSatelliteEphemeris);
+ builder.append(", realTimeIntegrityModels = ").append(mRealTimeIntegrityModels);
+ builder.append(", satelliteCorrections = ").append(mSatelliteCorrections);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeTypedObject(mAlmanac, flags);
+ dest.writeTypedObject(mIonosphericModel, flags);
+ dest.writeTypedObject(mUtcModel, flags);
+ dest.writeTypedObject(mLeapSecondsModel, flags);
+ dest.writeTypedList(mTimeModels);
+ dest.writeTypedList(mSatelliteEphemeris);
+ dest.writeTypedList(mRealTimeIntegrityModels);
+ dest.writeTypedList(mSatelliteCorrections);
+ }
+
+ public static final @android.annotation.NonNull Creator<BeidouAssistance> CREATOR =
+ new Creator<BeidouAssistance>() {
+ @Override
+ public BeidouAssistance createFromParcel(Parcel in) {
+ return new BeidouAssistance.Builder()
+ .setAlmanac(in.readTypedObject(GnssAlmanac.CREATOR))
+ .setIonosphericModel(
+ in.readTypedObject(KlobucharIonosphericModel.CREATOR))
+ .setUtcModel(in.readTypedObject(UtcModel.CREATOR))
+ .setLeapSecondsModel(in.readTypedObject(LeapSecondsModel.CREATOR))
+ .setTimeModels(in.createTypedArrayList(TimeModel.CREATOR))
+ .setSatelliteEphemeris(
+ in.createTypedArrayList(BeidouSatelliteEphemeris.CREATOR))
+ .setRealTimeIntegrityModels(
+ in.createTypedArrayList(RealTimeIntegrityModel.CREATOR))
+ .setSatelliteCorrections(
+ in.createTypedArrayList(GnssSatelliteCorrections.CREATOR))
+ .build();
+ }
+
+ @Override
+ public BeidouAssistance[] newArray(int size) {
+ return new BeidouAssistance[size];
+ }
+ };
+
+ /** Builder for {@link BeidouAssistance}. */
+ public static final class Builder {
+ private GnssAlmanac mAlmanac;
+ private KlobucharIonosphericModel mIonosphericModel;
+ private UtcModel mUtcModel;
+ private LeapSecondsModel mLeapSecondsModel;
+ private List<TimeModel> mTimeModels;
+ private List<BeidouSatelliteEphemeris> mSatelliteEphemeris;
+ private List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+ private List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+ /** Sets the Beidou almanac. */
+ @NonNull
+ public Builder setAlmanac(@Nullable GnssAlmanac almanac) {
+ mAlmanac = almanac;
+ return this;
+ }
+
+ /** Sets the Klobuchar ionospheric model. */
+ @NonNull
+ public Builder setIonosphericModel(@Nullable KlobucharIonosphericModel ionosphericModel) {
+ mIonosphericModel = ionosphericModel;
+ return this;
+ }
+
+ /** Sets the UTC model. */
+ @NonNull
+ public Builder setUtcModel(@Nullable UtcModel utcModel) {
+ mUtcModel = utcModel;
+ return this;
+ }
+
+ /** Sets the leap seconds model. */
+ @NonNull
+ public Builder setLeapSecondsModel(@Nullable LeapSecondsModel leapSecondsModel) {
+ mLeapSecondsModel = leapSecondsModel;
+ return this;
+ }
+
+ /** Sets the list of time models. */
+ @NonNull
+ public Builder setTimeModels(
+ @Nullable @SuppressLint("NullableCollection") List<TimeModel> timeModels) {
+ mTimeModels = timeModels;
+ return this;
+ }
+
+ /** Sets the list of Beidou ephemeris. */
+ @NonNull
+ public Builder setSatelliteEphemeris(
+ @Nullable @SuppressLint("NullableCollection")
+ List<BeidouSatelliteEphemeris> satelliteEphemeris) {
+ mSatelliteEphemeris = satelliteEphemeris;
+ return this;
+ }
+
+ /** Sets the list of real time integrity models. */
+ @NonNull
+ public Builder setRealTimeIntegrityModels(
+ @Nullable @SuppressLint("NullableCollection")
+ List<RealTimeIntegrityModel> realTimeIntegrityModels) {
+ mRealTimeIntegrityModels = realTimeIntegrityModels;
+ return this;
+ }
+
+ /** Sets the list of Beidou satellite corrections. */
+ @NonNull
+ public Builder setSatelliteCorrections(
+ @Nullable @SuppressLint("NullableCollection")
+ List<GnssSatelliteCorrections> satelliteCorrections) {
+ mSatelliteCorrections = satelliteCorrections;
+ return this;
+ }
+
+ /** Builds the {@link BeidouAssistance}. */
+ @NonNull
+ public BeidouAssistance build() {
+ return new BeidouAssistance(this);
+ }
+ }
+}
diff --git a/location/java/android/location/BeidouSatelliteEphemeris.java b/location/java/android/location/BeidouSatelliteEphemeris.java
new file mode 100644
index 0000000..6bd91e3
--- /dev/null
+++ b/location/java/android/location/BeidouSatelliteEphemeris.java
@@ -0,0 +1,647 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains ephemeris parameters specific to Beidou satellites.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class BeidouSatelliteEphemeris implements Parcelable {
+ /** The PRN number of the Beidou satellite. */
+ private final int mPrn;
+
+ /** Satellite clock model. */
+ private final BeidouSatelliteClockModel mSatelliteClockModel;
+
+ /** Satellite orbit model. */
+ private final KeplerianOrbitModel mSatelliteOrbitModel;
+
+ /** Satellite health. */
+ private final BeidouSatelliteHealth mSatelliteHealth;
+
+ /** Satellite ephemeris time. */
+ private final BeidouSatelliteEphemerisTime mSatelliteEphemerisTime;
+
+ private BeidouSatelliteEphemeris(Builder builder) {
+ // Allow PRN beyond the range to support potential future extensibility.
+ Preconditions.checkArgument(builder.mPrn >= 1);
+ Preconditions.checkNotNull(builder.mSatelliteClockModel,
+ "SatelliteClockModel cannot be null");
+ Preconditions.checkNotNull(builder.mSatelliteOrbitModel,
+ "SatelliteOrbitModel cannot be null");
+ Preconditions.checkNotNull(builder.mSatelliteHealth,
+ "SatelliteHealth cannot be null");
+ Preconditions.checkNotNull(builder.mSatelliteEphemerisTime,
+ "SatelliteEphemerisTime cannot be null");
+ mPrn = builder.mPrn;
+ mSatelliteClockModel = builder.mSatelliteClockModel;
+ mSatelliteOrbitModel = builder.mSatelliteOrbitModel;
+ mSatelliteHealth = builder.mSatelliteHealth;
+ mSatelliteEphemerisTime = builder.mSatelliteEphemerisTime;
+ }
+
+ /** Returns the PRN of the satellite. */
+ @IntRange(from = 1, to = 63)
+ public int getPrn() {
+ return mPrn;
+ }
+
+ /** Returns the satellite clock model. */
+ @NonNull
+ public BeidouSatelliteClockModel getSatelliteClockModel() {
+ return mSatelliteClockModel;
+ }
+
+ /** Returns the satellite orbit model. */
+ @NonNull
+ public KeplerianOrbitModel getSatelliteOrbitModel() {
+ return mSatelliteOrbitModel;
+ }
+
+ /** Returns the satellite health. */
+ @NonNull
+ public BeidouSatelliteHealth getSatelliteHealth() {
+ return mSatelliteHealth;
+ }
+
+ /** Returns the satellite ephemeris time. */
+ @NonNull
+ public BeidouSatelliteEphemerisTime getSatelliteEphemerisTime() {
+ return mSatelliteEphemerisTime;
+ }
+
+ public static final @NonNull Creator<BeidouSatelliteEphemeris> CREATOR =
+ new Creator<BeidouSatelliteEphemeris>() {
+ @Override
+ @NonNull
+ public BeidouSatelliteEphemeris createFromParcel(Parcel in) {
+ final BeidouSatelliteEphemeris.Builder beidouSatelliteEphemeris =
+ new Builder()
+ .setPrn(in.readInt())
+ .setSatelliteClockModel(
+ in.readTypedObject(BeidouSatelliteClockModel.CREATOR))
+ .setSatelliteOrbitModel(
+ in.readTypedObject(KeplerianOrbitModel.CREATOR))
+ .setSatelliteHealth(
+ in.readTypedObject(BeidouSatelliteHealth.CREATOR))
+ .setSatelliteEphemerisTime(
+ in.readTypedObject(
+ BeidouSatelliteEphemerisTime.CREATOR));
+ return beidouSatelliteEphemeris.build();
+ }
+
+ @Override
+ public BeidouSatelliteEphemeris[] newArray(int size) {
+ return new BeidouSatelliteEphemeris[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mPrn);
+ parcel.writeTypedObject(mSatelliteClockModel, flags);
+ parcel.writeTypedObject(mSatelliteOrbitModel, flags);
+ parcel.writeTypedObject(mSatelliteHealth, flags);
+ parcel.writeTypedObject(mSatelliteEphemerisTime, flags);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("BeidouSatelliteEphemeris[");
+ builder.append("prn = ").append(mPrn);
+ builder.append(", satelliteClockModel = ").append(mSatelliteClockModel);
+ builder.append(", satelliteOrbitModel = ").append(mSatelliteOrbitModel);
+ builder.append(", satelliteHealth = ").append(mSatelliteHealth);
+ builder.append(", satelliteEphemerisTime = ").append(mSatelliteEphemerisTime);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link BeidouSatelliteEphemeris} */
+ public static final class Builder {
+ private int mPrn;
+ private BeidouSatelliteClockModel mSatelliteClockModel;
+ private KeplerianOrbitModel mSatelliteOrbitModel;
+ private BeidouSatelliteHealth mSatelliteHealth;
+ private BeidouSatelliteEphemerisTime mSatelliteEphemerisTime;
+
+ /** Sets the PRN of the satellite. */
+ @NonNull
+ public Builder setPrn(int prn) {
+ mPrn = prn;
+ return this;
+ }
+
+ /** Sets the satellite clock model. */
+ @NonNull
+ public Builder setSatelliteClockModel(
+ @NonNull BeidouSatelliteClockModel satelliteClockModel) {
+ mSatelliteClockModel = satelliteClockModel;
+ return this;
+ }
+
+ /** Sets the satellite orbit model. */
+ @NonNull
+ public Builder setSatelliteOrbitModel(@NonNull KeplerianOrbitModel satelliteOrbitModel) {
+ mSatelliteOrbitModel = satelliteOrbitModel;
+ return this;
+ }
+
+ /** Sets the satellite health. */
+ @NonNull
+ public Builder setSatelliteHealth(@NonNull BeidouSatelliteHealth satelliteHealth) {
+ mSatelliteHealth = satelliteHealth;
+ return this;
+ }
+
+ /** Sets the satellite ephemeris time. */
+ @NonNull
+ public Builder setSatelliteEphemerisTime(
+ @NonNull BeidouSatelliteEphemerisTime satelliteEphemerisTime) {
+ mSatelliteEphemerisTime = satelliteEphemerisTime;
+ return this;
+ }
+
+ /** Builds a {@link BeidouSatelliteEphemeris} instance as specified by this builder. */
+ @NonNull
+ public BeidouSatelliteEphemeris build() {
+ return new BeidouSatelliteEphemeris(this);
+ }
+ }
+
+ /**
+ * A class contains the set of parameters needed for Beidou satellite clock correction.
+ *
+ * <p>This is defined in BDS-SIS-ICD-B1I-3.0, section 5.2.4.9, 5.2.4.10.
+ */
+ public static final class BeidouSatelliteClockModel implements Parcelable {
+ /**
+ * Time of the clock in seconds since Beidou epoch.
+ *
+ * <p>Corresponds to the 'Epoch' field within the 'SV/EPOCH/SV CLK' record of Beidou
+ * navigation message in RINEX 3.05 Table A14.
+ */
+ private final long mTimeOfClockSeconds;
+
+ /** SV clock bias in seconds. */
+ private final double mAf0;
+
+ /** SV clock drift in seconds per second. */
+ private final double mAf1;
+
+ /** SV clock drift in seconds per second squared. */
+ private final double mAf2;
+
+ /** Group delay differential 1 B1/B3 in seconds. */
+ private final double mTgd1;
+
+ /** Group delay differential 2 B2/B3 in seconds. */
+ private final double mTgd2;
+
+ /**
+ * Age of Data Clock.
+ * <p>This is defined in BDS-SIS-ICD-B1I-3.0 Section 5.2.4.8 Table 5-6.
+ */
+ private final int mAodc;
+
+ private BeidouSatelliteClockModel(Builder builder) {
+ Preconditions.checkArgument(builder.mTimeOfClockSeconds >= 0);
+ Preconditions.checkArgumentInRange(builder.mAf0, -9.77e-3f, 9.77e-3f, "Af0");
+ Preconditions.checkArgumentInRange(builder.mAf1, -1.87e-9f, 1.87e-9f, "Af1");
+ Preconditions.checkArgumentInRange(builder.mAf2, -1.39e-17f, 1.39e-17f, "Af2");
+ Preconditions.checkArgumentInRange(builder.mTgd1, -5.12e-8f, 5.12e-8f, "Tgd1");
+ Preconditions.checkArgumentInRange(builder.mTgd2, -5.12e-8f, 5.12e-8f, "Tgd2");
+ Preconditions.checkArgumentInRange(builder.mAodc, 0, 31, "Aodc");
+ mTimeOfClockSeconds = builder.mTimeOfClockSeconds;
+ mAf0 = builder.mAf0;
+ mAf1 = builder.mAf1;
+ mAf2 = builder.mAf2;
+ mTgd1 = builder.mTgd1;
+ mTgd2 = builder.mTgd2;
+ mAodc = builder.mAodc;
+ }
+
+ /** Returns the time of the clock in seconds since Beidou epoch. */
+ @IntRange(from = 0)
+ public long getTimeOfClockSeconds() {
+ return mTimeOfClockSeconds;
+ }
+
+ /** Returns the SV clock bias in seconds. */
+ @FloatRange(from = -9.77e-3f, to = 9.77e-3f)
+ public double getAf0() {
+ return mAf0;
+ }
+
+ /** Returns the SV clock drift in seconds per second. */
+ @FloatRange(from = -1.87e-9f, to = 1.87e-9f)
+ public double getAf1() {
+ return mAf1;
+ }
+
+ /** Returns the SV clock drift in seconds per second squared. */
+ @FloatRange(from = -1.39e-17f, to = 1.39e-17f)
+ public double getAf2() {
+ return mAf2;
+ }
+
+ /** Returns the group delay differential 1 B1/B3 in seconds. */
+ @FloatRange(from = -5.12e-8f, to = 5.12e-8f)
+ public double getTgd1() {
+ return mTgd1;
+ }
+
+ /** Returns the group delay differential 2 B2/B3 in seconds. */
+ @FloatRange(from = -5.12e-8f, to = 5.12e-8f)
+ public double getTgd2() {
+ return mTgd2;
+ }
+
+ /** Returns the age of data clock. */
+ @IntRange(from = 0, to = 31)
+ public int getAodc() {
+ return mAodc;
+ }
+
+ public static final @NonNull Creator<BeidouSatelliteClockModel> CREATOR =
+ new Creator<BeidouSatelliteClockModel>() {
+ @Override
+ @NonNull
+ public BeidouSatelliteClockModel createFromParcel(Parcel in) {
+ final BeidouSatelliteClockModel.Builder beidouSatelliteClockModel =
+ new Builder()
+ .setTimeOfClockSeconds(in.readLong())
+ .setAf0(in.readDouble())
+ .setAf1(in.readDouble())
+ .setAf2(in.readDouble())
+ .setTgd1(in.readDouble())
+ .setTgd2(in.readDouble())
+ .setAodc(in.readInt());
+ return beidouSatelliteClockModel.build();
+ }
+
+ @Override
+ public BeidouSatelliteClockModel[] newArray(int size) {
+ return new BeidouSatelliteClockModel[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeLong(mTimeOfClockSeconds);
+ parcel.writeDouble(mAf0);
+ parcel.writeDouble(mAf1);
+ parcel.writeDouble(mAf2);
+ parcel.writeDouble(mTgd1);
+ parcel.writeDouble(mTgd2);
+ parcel.writeInt(mAodc);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("BeidouSatelliteClockModel[");
+ builder.append("timeOfClockSeonds = ").append(mTimeOfClockSeconds);
+ builder.append(", af0 = ").append(mAf0);
+ builder.append(", af1 = ").append(mAf1);
+ builder.append(", af2 = ").append(mAf2);
+ builder.append(", tgd1 = ").append(mTgd1);
+ builder.append(", tgd2 = ").append(mTgd2);
+ builder.append(", aodc = ").append(mAodc);
+ return builder.toString();
+ }
+
+ /** Builder for {@link BeidouSatelliteClockModel} */
+ public static final class Builder {
+ private long mTimeOfClockSeconds;
+ private double mAf0;
+ private double mAf1;
+ private double mAf2;
+ private double mTgd1;
+ private double mTgd2;
+ private int mAodc;
+
+ /** Sets the time of the clock in seconds since Beidou epoch. */
+ @NonNull
+ public Builder setTimeOfClockSeconds(@IntRange(from = 0) long timeOfClockSeconds) {
+ mTimeOfClockSeconds = timeOfClockSeconds;
+ return this;
+ }
+
+ /** Sets the SV clock bias in seconds. */
+ @NonNull
+ public Builder setAf0(@FloatRange(from = -9.77e-3f, to = 9.77e-3f)double af0) {
+ mAf0 = af0;
+ return this;
+ }
+
+ /** Sets the SV clock drift in seconds per second. */
+ @NonNull
+ public Builder setAf1(@FloatRange(from = -1.87e-9f, to = 1.87e-9f) double af1) {
+ mAf1 = af1;
+ return this;
+ }
+
+ /** Sets the SV clock drift in seconds per second squared. */
+ @NonNull
+ public Builder setAf2(@FloatRange(from = -1.39e-17f, to = 1.39e-17f) double af2) {
+ mAf2 = af2;
+ return this;
+ }
+
+ /** Sets the group delay differential 1 B1/B3 in seconds. */
+ @NonNull
+ public Builder setTgd1(@FloatRange(from = -5.12e-8f, to = 5.12e-8f) double tgd1) {
+ mTgd1 = tgd1;
+ return this;
+ }
+
+ /** Sets the group delay differential 2 B2/B3 in seconds. */
+ @NonNull
+ public Builder setTgd2(@FloatRange(from = -5.12e-8f, to = 5.12e-8f) double tgd2) {
+ mTgd2 = tgd2;
+ return this;
+ }
+
+ /** Sets the age of data clock. */
+ @NonNull
+ public Builder setAodc(@IntRange(from = 0, to = 31) int aodc) {
+ mAodc = aodc;
+ return this;
+ }
+
+ /** Builds a {@link BeidouSatelliteClockModel} instance as specified by this builder. */
+ @NonNull
+ public BeidouSatelliteClockModel build() {
+ return new BeidouSatelliteClockModel(this);
+ }
+ }
+ }
+
+ /** A class contains Beidou satellite health. */
+ public static final class BeidouSatelliteHealth implements Parcelable {
+ /**
+ * The autonomous satellite health flag (SatH1) occupies 1 bit.
+ *
+ * <p>“0” means broadcasting satellite is good and “1” means not.
+ *
+ * <p>This is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.6.
+ */
+ private final int mSatH1;
+
+ /**
+ * SV accuracy in meters.
+ *
+ * <p>This is defined in the "BROADCAST ORBIT - 6" record of RINEX 3.05
+ * Table A14, pp.78.
+ */
+ private final double mSvAccur;
+
+ private BeidouSatelliteHealth(Builder builder) {
+ // Allow SatH1 beyond the range to support potential future extensibility.
+ Preconditions.checkArgument(builder.mSatH1 >= 0);
+ Preconditions.checkArgumentInRange(builder.mSvAccur, 0.0f, 8192.0f, "SvAccur");
+ mSatH1 = builder.mSatH1;
+ mSvAccur = builder.mSvAccur;
+ }
+
+ /** Returns the autonomous satellite health flag (SatH1) */
+ @IntRange(from = 0, to = 1)
+ public int getSatH1() {
+ return mSatH1;
+ }
+
+ /** Returns the SV accuracy in meters. */
+ @FloatRange(from = 0.0f, to = 8192.0f)
+ public double getSvAccur() {
+ return mSvAccur;
+ }
+
+ public static final @NonNull Creator<BeidouSatelliteHealth> CREATOR =
+ new Creator<BeidouSatelliteHealth>() {
+ @Override
+ @NonNull
+ public BeidouSatelliteHealth createFromParcel(Parcel in) {
+ final BeidouSatelliteHealth.Builder beidouSatelliteHealth =
+ new Builder().setSatH1(in.readInt()).setSvAccur(in.readDouble());
+ return beidouSatelliteHealth.build();
+ }
+
+ @Override
+ public BeidouSatelliteHealth[] newArray(int size) {
+ return new BeidouSatelliteHealth[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mSatH1);
+ parcel.writeDouble(mSvAccur);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("BeidouSatelliteHealth[");
+ builder.append("satH1 = ").append(mSatH1);
+ builder.append(", svAccur = ").append(mSvAccur);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link BeidouSatelliteHealth} */
+ public static final class Builder {
+ private int mSatH1;
+ private double mSvAccur;
+
+ /** Sets the autonomous satellite health flag (SatH1) */
+ @NonNull
+ public Builder setSatH1(int satH1) {
+ mSatH1 = satH1;
+ return this;
+ }
+
+ /** Sets the SV accuracy in meters. */
+ @NonNull
+ public Builder setSvAccur(double svAccur) {
+ mSvAccur = svAccur;
+ return this;
+ }
+
+ /** Builds a {@link BeidouSatelliteHealth} instance as specified by this builder. */
+ @NonNull
+ public BeidouSatelliteHealth build() {
+ return new BeidouSatelliteHealth(this);
+ }
+ }
+ }
+
+ /** A class contains Beidou satellite ephemeris time. */
+ public static final class BeidouSatelliteEphemerisTime implements Parcelable {
+ /**
+ * AODE Age of Data, Ephemeris.
+ *
+ * <p>This is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.11 Table 5-8.
+ */
+ private final int mIode;
+
+ /** Beidou week number without rollover */
+ private final int mBeidouWeekNumber;
+
+ /**
+ * Time of ephemeris in seconds.
+ *
+ * <p>This is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.12.
+ */
+ private final int mToeSeconds;
+
+ private BeidouSatelliteEphemerisTime(Builder builder) {
+ Preconditions.checkArgumentInRange(builder.mIode, 0, 31, "Iode");
+ Preconditions.checkArgument(builder.mBeidouWeekNumber >= 0);
+ Preconditions.checkArgumentInRange(builder.mToeSeconds, 0, 604792, "ToeSeconds");
+ mIode = builder.mIode;
+ mBeidouWeekNumber = builder.mBeidouWeekNumber;
+ mToeSeconds = builder.mToeSeconds;
+ }
+
+ /** Returns the AODE Age of Data, Ephemeris. */
+ @IntRange(from = 0, to = 31)
+ public int getIode() {
+ return mIode;
+ }
+
+ /** Returns the Beidou week number without rollover . */
+ @IntRange(from = 0)
+ public int getBeidouWeekNumber() {
+ return mBeidouWeekNumber;
+ }
+
+ /** Returns the time of ephemeris in seconds. */
+ @IntRange(from = 0, to = 604792)
+ public int getToeSeconds() {
+ return mToeSeconds;
+ }
+
+ public static final @NonNull Creator<BeidouSatelliteEphemerisTime> CREATOR =
+ new Creator<BeidouSatelliteEphemerisTime>() {
+ @Override
+ @NonNull
+ public BeidouSatelliteEphemerisTime createFromParcel(Parcel in) {
+ final BeidouSatelliteEphemerisTime.Builder beidouSatelliteEphemerisTime =
+ new Builder()
+ .setIode(in.readInt())
+ .setBeidouWeekNumber(in.readInt())
+ .setToeSeconds(in.readInt());
+ return beidouSatelliteEphemerisTime.build();
+ }
+
+ @Override
+ public BeidouSatelliteEphemerisTime[] newArray(int size) {
+ return new BeidouSatelliteEphemerisTime[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mIode);
+ parcel.writeInt(mBeidouWeekNumber);
+ parcel.writeInt(mToeSeconds);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder("BeidouSatelliteEphemerisTime[");
+ builder.append("iode = ").append(mIode);
+ builder.append(", beidouWeekNumber = ").append(mBeidouWeekNumber);
+ builder.append(", toeSeconds = ").append(mToeSeconds);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link BeidouSatelliteEphemerisTime} */
+ public static final class Builder {
+ private int mIode;
+ private int mBeidouWeekNumber;
+ private int mToeSeconds;
+
+ /** Sets the AODE Age of Data, Ephemeris. */
+ @NonNull
+ public Builder setIode(int iode) {
+ mIode = iode;
+ return this;
+ }
+
+ /** Sets the Beidou week number without rollover */
+ @NonNull
+ public Builder setBeidouWeekNumber(
+ @IntRange(from = 0) int beidouWeekNumber) {
+ mBeidouWeekNumber = beidouWeekNumber;
+ return this;
+ }
+
+ /** Sets the time of ephemeris in seconds. */
+ @NonNull
+ public Builder setToeSeconds(@IntRange(from = 0, to = 604792) int toeSeconds) {
+ mToeSeconds = toeSeconds;
+ return this;
+ }
+
+ /**
+ * Builds a {@link BeidouSatelliteEphemerisTime} instance as specified by this builder.
+ */
+ @NonNull
+ public BeidouSatelliteEphemerisTime build() {
+ return new BeidouSatelliteEphemerisTime(this);
+ }
+ }
+ }
+}
diff --git a/location/java/android/location/GalileoAssistance.java b/location/java/android/location/GalileoAssistance.java
new file mode 100644
index 0000000..07c5bab
--- /dev/null
+++ b/location/java/android/location/GalileoAssistance.java
@@ -0,0 +1,283 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.location.GnssAssistance.GnssSatelliteCorrections;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains Galileo assistance.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GalileoAssistance implements Parcelable {
+
+ /** The Galileo almanac. */
+ @Nullable private final GnssAlmanac mAlmanac;
+
+ /** The Klobuchar ionospheric model. */
+ @Nullable private final KlobucharIonosphericModel mIonosphericModel;
+
+ /** The UTC model. */
+ @Nullable private final UtcModel mUtcModel;
+
+ /** The leap seconds model. */
+ @Nullable private final LeapSecondsModel mLeapSecondsModel;
+
+ /** The list of time models. */
+ @NonNull private final List<TimeModel> mTimeModels;
+
+ /** The list of Galileo ephemeris. */
+ @NonNull private final List<GalileoSatelliteEphemeris> mSatelliteEphemeris;
+
+ /** The list of real time integrity models. */
+ @NonNull private final List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+
+ /** The list of Galileo satellite corrections. */
+ @NonNull private final List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+ private GalileoAssistance(Builder builder) {
+ mAlmanac = builder.mAlmanac;
+ mIonosphericModel = builder.mIonosphericModel;
+ mUtcModel = builder.mUtcModel;
+ mLeapSecondsModel = builder.mLeapSecondsModel;
+ if (builder.mTimeModels != null) {
+ mTimeModels = Collections.unmodifiableList(new ArrayList<>(builder.mTimeModels));
+ } else {
+ mTimeModels = new ArrayList<>();
+ }
+ if (builder.mSatelliteEphemeris != null) {
+ mSatelliteEphemeris =
+ Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteEphemeris));
+ } else {
+ mSatelliteEphemeris = new ArrayList<>();
+ }
+ if (builder.mRealTimeIntegrityModels != null) {
+ mRealTimeIntegrityModels =
+ Collections.unmodifiableList(new ArrayList<>(builder.mRealTimeIntegrityModels));
+ } else {
+ mRealTimeIntegrityModels = new ArrayList<>();
+ }
+ if (builder.mSatelliteCorrections != null) {
+ mSatelliteCorrections =
+ Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteCorrections));
+ } else {
+ mSatelliteCorrections = new ArrayList<>();
+ }
+ }
+
+ /** Returns the Galileo almanac. */
+ @Nullable
+ public GnssAlmanac getAlmanac() {
+ return mAlmanac;
+ }
+
+ /** Returns the Klobuchar ionospheric model. */
+ @Nullable
+ public KlobucharIonosphericModel getIonosphericModel() {
+ return mIonosphericModel;
+ }
+
+ /** Returns the UTC model. */
+ @Nullable
+ public UtcModel getUtcModel() {
+ return mUtcModel;
+ }
+
+ /** Returns the leap seconds model. */
+ @Nullable
+ public LeapSecondsModel getLeapSecondsModel() {
+ return mLeapSecondsModel;
+ }
+
+ /** Returns the list of time models. */
+ @NonNull
+ public List<TimeModel> getTimeModels() {
+ return mTimeModels;
+ }
+
+ /** Returns the list of Galileo ephemeris. */
+ @NonNull
+ public List<GalileoSatelliteEphemeris> getSatelliteEphemeris() {
+ return mSatelliteEphemeris;
+ }
+
+ /** Returns the list of real time integrity models. */
+ @NonNull
+ public List<RealTimeIntegrityModel> getRealTimeIntegrityModels() {
+ return mRealTimeIntegrityModels;
+ }
+
+ /** Returns the list of Galileo satellite corrections. */
+ @NonNull
+ public List<GnssSatelliteCorrections> getSatelliteCorrections() {
+ return mSatelliteCorrections;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeTypedObject(mAlmanac, flags);
+ dest.writeTypedObject(mIonosphericModel, flags);
+ dest.writeTypedObject(mUtcModel, flags);
+ dest.writeTypedObject(mLeapSecondsModel, flags);
+ dest.writeTypedList(mTimeModels);
+ dest.writeTypedList(mSatelliteEphemeris);
+ dest.writeTypedList(mRealTimeIntegrityModels);
+ dest.writeTypedList(mSatelliteCorrections);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GalileoAssistance[");
+ builder.append("almanac = ").append(mAlmanac);
+ builder.append(", ionosphericModel = ").append(mIonosphericModel);
+ builder.append(", utcModel = ").append(mUtcModel);
+ builder.append(", leapSecondsModel = ").append(mLeapSecondsModel);
+ builder.append(", timeModels = ").append(mTimeModels);
+ builder.append(", satelliteEphemeris = ").append(mSatelliteEphemeris);
+ builder.append(", realTimeIntegrityModels = ").append(mRealTimeIntegrityModels);
+ builder.append(", satelliteCorrections = ").append(mSatelliteCorrections);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ public static final @android.annotation.NonNull Creator<GalileoAssistance> CREATOR =
+ new Creator<GalileoAssistance>() {
+ @Override
+ public GalileoAssistance createFromParcel(Parcel in) {
+ return new GalileoAssistance.Builder()
+ .setAlmanac(in.readTypedObject(GnssAlmanac.CREATOR))
+ .setIonosphericModel(
+ in.readTypedObject(KlobucharIonosphericModel.CREATOR))
+ .setUtcModel(in.readTypedObject(UtcModel.CREATOR))
+ .setLeapSecondsModel(in.readTypedObject(LeapSecondsModel.CREATOR))
+ .setTimeModels(in.createTypedArrayList(TimeModel.CREATOR))
+ .setSatelliteEphemeris(
+ in.createTypedArrayList(GalileoSatelliteEphemeris.CREATOR))
+ .setRealTimeIntegrityModels(
+ in.createTypedArrayList(RealTimeIntegrityModel.CREATOR))
+ .setSatelliteCorrections(
+ in.createTypedArrayList(GnssSatelliteCorrections.CREATOR))
+ .build();
+ }
+
+ @Override
+ public GalileoAssistance[] newArray(int size) {
+ return new GalileoAssistance[size];
+ }
+ };
+
+ /** Builder for {@link GalileoAssistance}. */
+ public static final class Builder {
+ private GnssAlmanac mAlmanac;
+ private KlobucharIonosphericModel mIonosphericModel;
+ private UtcModel mUtcModel;
+ private LeapSecondsModel mLeapSecondsModel;
+ private List<TimeModel> mTimeModels;
+ private List<GalileoSatelliteEphemeris> mSatelliteEphemeris;
+ private List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+ private List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+ /** Sets the Galileo almanac. */
+ @NonNull
+ public Builder setAlmanac(@Nullable GnssAlmanac almanac) {
+ mAlmanac = almanac;
+ return this;
+ }
+
+ /** Sets the Klobuchar ionospheric model. */
+ @NonNull
+ public Builder setIonosphericModel(@Nullable KlobucharIonosphericModel ionosphericModel) {
+ mIonosphericModel = ionosphericModel;
+ return this;
+ }
+
+ /** Sets the UTC model. */
+ @NonNull
+ public Builder setUtcModel(@Nullable UtcModel utcModel) {
+ mUtcModel = utcModel;
+ return this;
+ }
+
+ /** Sets the leap seconds model. */
+ @NonNull
+ public Builder setLeapSecondsModel(@Nullable LeapSecondsModel leapSecondsModel) {
+ mLeapSecondsModel = leapSecondsModel;
+ return this;
+ }
+
+ /** Sets the list of time models. */
+ @NonNull
+ public Builder setTimeModels(
+ @Nullable @SuppressLint("NullableCollection") List<TimeModel> timeModels) {
+ mTimeModels = timeModels;
+ return this;
+ }
+
+ /** Sets the list of Galileo ephemeris. */
+ @NonNull
+ public Builder setSatelliteEphemeris(
+ @Nullable @SuppressLint("NullableCollection")
+ List<GalileoSatelliteEphemeris> satelliteEphemeris) {
+ mSatelliteEphemeris = satelliteEphemeris;
+ return this;
+ }
+
+ /** Sets the list of real time integrity models. */
+ @NonNull
+ public Builder setRealTimeIntegrityModels(
+ @Nullable @SuppressLint("NullableCollection")
+ List<RealTimeIntegrityModel> realTimeIntegrityModels) {
+ mRealTimeIntegrityModels = realTimeIntegrityModels;
+ return this;
+ }
+
+ /** Sets the list of Galileo satellite corrections. */
+ @NonNull
+ public Builder setSatelliteCorrections(
+ @Nullable @SuppressLint("NullableCollection")
+ List<GnssSatelliteCorrections> satelliteCorrections) {
+ mSatelliteCorrections = satelliteCorrections;
+ return this;
+ }
+
+ /** Builds the {@link GalileoAssistance}. */
+ @NonNull
+ public GalileoAssistance build() {
+ return new GalileoAssistance(this);
+ }
+ }
+}
diff --git a/location/java/android/location/GalileoIonosphericModel.java b/location/java/android/location/GalileoIonosphericModel.java
new file mode 100644
index 0000000..6638be9
--- /dev/null
+++ b/location/java/android/location/GalileoIonosphericModel.java
@@ -0,0 +1,148 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Contains Galileo ionospheric model.
+ *
+ * <p>This is defined in Galileo-OS-SIS-ICD-v2.1, section 5.1.6.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GalileoIonosphericModel implements Parcelable {
+ /** Effective ionisation level 1st order parameter in sfu. */
+ private final double mAi0;
+
+ /** Effective ionisation level 2nd order parameter in sfu per degree. */
+ private final double mAi1;
+
+ /** Effective ionisation level 3nd order parameter in sfu per degree squared. */
+ private final double mAi2;
+
+ private GalileoIonosphericModel(Builder builder) {
+ Preconditions.checkArgumentInRange(builder.mAi0, 0.0f, 512.0f, "Ai0");
+ Preconditions.checkArgumentInRange(builder.mAi1, -4.0f, 4.0f, "Ai1");
+ Preconditions.checkArgumentInRange(builder.mAi2, -0.5f, 0.5f, "Ai2");
+ mAi0 = builder.mAi0;
+ mAi1 = builder.mAi1;
+ mAi2 = builder.mAi2;
+ }
+
+ /** Returns the effective ionisation level 1st order parameter in sfu. */
+ @FloatRange(from = 0.0f, to = 512.0f)
+ public double getAi0() {
+ return mAi0;
+ }
+
+ /** Returns the effective ionisation level 2nd order parameter in sfu per degree. */
+ @FloatRange(from = -4.0f, to = 4.0f)
+ public double getAi1() {
+ return mAi1;
+ }
+
+ /** Returns the effective ionisation level 3nd order parameter in sfu per degree squared. */
+ @FloatRange(from = -0.5f, to = 0.5f)
+ public double getAi2() {
+ return mAi2;
+ }
+
+ public static final @NonNull Parcelable.Creator<GalileoIonosphericModel> CREATOR =
+ new Parcelable.Creator<GalileoIonosphericModel>() {
+ @Override
+ public GalileoIonosphericModel createFromParcel(@NonNull Parcel source) {
+ return new GalileoIonosphericModel.Builder()
+ .setAi0(source.readDouble())
+ .setAi1(source.readDouble())
+ .setAi2(source.readDouble())
+ .build();
+ }
+
+ @Override
+ public GalileoIonosphericModel[] newArray(int size) {
+ return new GalileoIonosphericModel[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeDouble(mAi0);
+ dest.writeDouble(mAi1);
+ dest.writeDouble(mAi2);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GalileoIonosphericModel[");
+ builder.append("ai0 = ").append(mAi0);
+ builder.append(", ai1 = ").append(mAi1);
+ builder.append(", ai2 = ").append(mAi2);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GalileoIonosphericModel}. */
+ public static final class Builder {
+ private double mAi0;
+ private double mAi1;
+ private double mAi2;
+
+ /** Sets the effective ionisation level 1st order parameter in sfu. */
+ @NonNull
+ public Builder setAi0(@FloatRange(from = 0.0f, to = 512.0f) double ai0) {
+ mAi0 = ai0;
+ return this;
+ }
+
+ /** Sets the effective ionisation level 2nd order parameter in sfu per degree. */
+ @NonNull
+ public Builder setAi1(@FloatRange(from = -4.0f, to = 4.0f) double ai1) {
+ mAi1 = ai1;
+ return this;
+ }
+
+ /** Sets the effective ionisation level 3nd order parameter in sfu per degree squared. */
+ @NonNull
+ public Builder setAi2(@FloatRange(from = -0.5f, to = 0.5f) double ai2) {
+ mAi2 = ai2;
+ return this;
+ }
+
+ /** Builds a {@link GalileoIonosphericModel}. */
+ @NonNull
+ public GalileoIonosphericModel build() {
+ return new GalileoIonosphericModel(this);
+ }
+ }
+}
diff --git a/location/java/android/location/GalileoSatelliteEphemeris.java b/location/java/android/location/GalileoSatelliteEphemeris.java
new file mode 100644
index 0000000..7dd3711
--- /dev/null
+++ b/location/java/android/location/GalileoSatelliteEphemeris.java
@@ -0,0 +1,660 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Contains ephemeris parameters specific to Galileo satellites.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GalileoSatelliteEphemeris implements Parcelable {
+
+ /** Satellite code number. */
+ private int mSatelliteCodeNumber;
+
+ /** Array of satellite clock model. */
+ @NonNull private final List<GalileoSatelliteClockModel> mSatelliteClockModels;
+
+ /** Satellite orbit model. */
+ @NonNull private final KeplerianOrbitModel mSatelliteOrbitModel;
+
+ /** Satellite health. */
+ @NonNull private final GalileoSvHealth mSatelliteHealth;
+
+ /** Satellite ephemeris time. */
+ @NonNull private final SatelliteEphemerisTime mSatelliteEphemerisTime;
+
+ private GalileoSatelliteEphemeris(Builder builder) {
+ // Allow satelliteCodeNumber beyond the range to support potential future extensibility.
+ Preconditions.checkArgument(builder.mSatelliteCodeNumber >= 1);
+ Preconditions.checkNotNull(
+ builder.mSatelliteClockModels, "SatelliteClockModels cannot be null");
+ Preconditions.checkNotNull(
+ builder.mSatelliteOrbitModel, "SatelliteOrbitModel cannot be null");
+ Preconditions.checkNotNull(builder.mSatelliteHealth, "SatelliteHealth cannot be null");
+ Preconditions.checkNotNull(
+ builder.mSatelliteEphemerisTime, "SatelliteEphemerisTime cannot be null");
+ mSatelliteCodeNumber = builder.mSatelliteCodeNumber;
+ final List<GalileoSatelliteClockModel> satelliteClockModels = builder.mSatelliteClockModels;
+ mSatelliteClockModels = Collections.unmodifiableList(new ArrayList<>(satelliteClockModels));
+ mSatelliteOrbitModel = builder.mSatelliteOrbitModel;
+ mSatelliteHealth = builder.mSatelliteHealth;
+ mSatelliteEphemerisTime = builder.mSatelliteEphemerisTime;
+ }
+
+ /** Returns the satellite code number. */
+ @IntRange(from = 1, to = 36)
+ public int getSatelliteCodeNumber() {
+ return mSatelliteCodeNumber;
+ }
+
+ /** Returns the list of satellite clock models. */
+ @NonNull
+ public List<GalileoSatelliteClockModel> getSatelliteClockModels() {
+ return mSatelliteClockModels;
+ }
+
+ /** Returns the satellite orbit model. */
+ @NonNull
+ public KeplerianOrbitModel getSatelliteOrbitModel() {
+ return mSatelliteOrbitModel;
+ }
+
+ /** Returns the satellite health. */
+ @NonNull
+ public GalileoSvHealth getSatelliteHealth() {
+ return mSatelliteHealth;
+ }
+
+ /** Returns the satellite ephemeris time. */
+ @NonNull
+ public SatelliteEphemerisTime getSatelliteEphemerisTime() {
+ return mSatelliteEphemerisTime;
+ }
+
+ public static final @NonNull Creator<GalileoSatelliteEphemeris> CREATOR =
+ new Creator<GalileoSatelliteEphemeris>() {
+ @Override
+ @NonNull
+ public GalileoSatelliteEphemeris createFromParcel(Parcel in) {
+ final GalileoSatelliteEphemeris.Builder galileoSatelliteEphemeris =
+ new Builder();
+ galileoSatelliteEphemeris.setSatelliteCodeNumber(in.readInt());
+ List<GalileoSatelliteClockModel> satelliteClockModels = new ArrayList<>();
+ in.readTypedList(satelliteClockModels, GalileoSatelliteClockModel.CREATOR);
+ galileoSatelliteEphemeris.setSatelliteClockModels(satelliteClockModels);
+ galileoSatelliteEphemeris.setSatelliteOrbitModel(
+ in.readTypedObject(KeplerianOrbitModel.CREATOR));
+ galileoSatelliteEphemeris.setSatelliteHealth(
+ in.readTypedObject(GalileoSvHealth.CREATOR));
+ galileoSatelliteEphemeris.setSatelliteEphemerisTime(
+ in.readTypedObject(SatelliteEphemerisTime.CREATOR));
+ return galileoSatelliteEphemeris.build();
+ }
+
+ @Override
+ public GalileoSatelliteEphemeris[] newArray(int size) {
+ return new GalileoSatelliteEphemeris[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mSatelliteCodeNumber);
+ parcel.writeTypedList(mSatelliteClockModels, flags);
+ parcel.writeTypedObject(mSatelliteOrbitModel, flags);
+ parcel.writeTypedObject(mSatelliteHealth, flags);
+ parcel.writeTypedObject(mSatelliteEphemerisTime, flags);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GalileoSatelliteEphemeris[");
+ builder.append("satelliteCodeNumber = ").append(mSatelliteCodeNumber);
+ builder.append(", satelliteClockModels = ").append(mSatelliteClockModels);
+ builder.append(", satelliteOrbitModel = ").append(mSatelliteOrbitModel);
+ builder.append(", satelliteHealth = ").append(mSatelliteHealth);
+ builder.append(", satelliteEphemerisTime = ").append(mSatelliteEphemerisTime);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GalileoSatelliteEphemeris}. */
+ public static final class Builder {
+ private int mSatelliteCodeNumber;
+ private List<GalileoSatelliteClockModel> mSatelliteClockModels;
+ private KeplerianOrbitModel mSatelliteOrbitModel;
+ private GalileoSvHealth mSatelliteHealth;
+ private SatelliteEphemerisTime mSatelliteEphemerisTime;
+
+ /** Sets the satellite code number. */
+ @NonNull
+ public Builder setSatelliteCodeNumber(
+ @IntRange(from = 1, to = 36) int satelliteCodeNumber) {
+ mSatelliteCodeNumber = satelliteCodeNumber;
+ return this;
+ }
+
+ /** Sets the array of satellite clock model. */
+ @NonNull
+ public Builder setSatelliteClockModels(
+ @NonNull List<GalileoSatelliteClockModel> satelliteClockModels) {
+ mSatelliteClockModels = satelliteClockModels;
+ return this;
+ }
+
+ /** Sets the satellite orbit model. */
+ @NonNull
+ public Builder setSatelliteOrbitModel(@NonNull KeplerianOrbitModel satelliteOrbitModel) {
+ mSatelliteOrbitModel = satelliteOrbitModel;
+ return this;
+ }
+
+ /** Sets the satellite health. */
+ @NonNull
+ public Builder setSatelliteHealth(@NonNull GalileoSvHealth satelliteHealth) {
+ mSatelliteHealth = satelliteHealth;
+ return this;
+ }
+
+ /** Sets the satellite ephemeris time. */
+ @NonNull
+ public Builder setSatelliteEphemerisTime(
+ @NonNull SatelliteEphemerisTime satelliteEphemerisTime) {
+ mSatelliteEphemerisTime = satelliteEphemerisTime;
+ return this;
+ }
+
+ /** Builds a {@link GalileoSatelliteEphemeris} instance as specified by this builder. */
+ @NonNull
+ public GalileoSatelliteEphemeris build() {
+ return new GalileoSatelliteEphemeris(this);
+ }
+ }
+
+ /**
+ * A class contains the set of parameters needed for Galileo satellite health.
+ *
+ * <p>This is defined in Galileo-OS-SIS-ICD 5.1.9.3.
+ */
+ public static final class GalileoSvHealth implements Parcelable {
+ /** E1-B data validity status. */
+ private int mDataValidityStatusE1b;
+
+ /** E1-B/C signal health status. */
+ private int mSignalHealthStatusE1b;
+
+ /** E5a data validity status. */
+ private int mDataValidityStatusE5a;
+
+ /** E5a signal health status. */
+ private int mSignalHealthStatusE5a;
+
+ /** E5b data validity status. */
+ private int mDataValidityStatusE5b;
+
+ /** E5b signal health status. */
+ private int mSignalHealthStatusE5b;
+
+ private GalileoSvHealth(Builder builder) {
+ Preconditions.checkArgumentInRange(
+ builder.mDataValidityStatusE1b, 0, 1, "DataValidityStatusE1b");
+ Preconditions.checkArgumentInRange(
+ builder.mSignalHealthStatusE1b, 0, 3, "SignalHealthStatusE1b");
+ Preconditions.checkArgumentInRange(
+ builder.mDataValidityStatusE5a, 0, 1, "DataValidityStatusE5a");
+ Preconditions.checkArgumentInRange(
+ builder.mSignalHealthStatusE5a, 0, 3, "SignalHealthStatusE5a");
+ Preconditions.checkArgumentInRange(
+ builder.mDataValidityStatusE5b, 0, 1, "DataValidityStatusE5b");
+ Preconditions.checkArgumentInRange(
+ builder.mSignalHealthStatusE5b, 0, 3, "SignalHealthStatusE5b");
+ mDataValidityStatusE1b = builder.mDataValidityStatusE1b;
+ mSignalHealthStatusE1b = builder.mSignalHealthStatusE1b;
+ mDataValidityStatusE5a = builder.mDataValidityStatusE5a;
+ mSignalHealthStatusE5a = builder.mSignalHealthStatusE5a;
+ mDataValidityStatusE5b = builder.mDataValidityStatusE5b;
+ mSignalHealthStatusE5b = builder.mSignalHealthStatusE5b;
+ }
+
+ /** Returns the E1-B data validity status. */
+ @IntRange(from = 0, to = 1)
+ public int getDataValidityStatusE1b() {
+ return mDataValidityStatusE1b;
+ }
+
+ /** Returns the E1-B/C signal health status. */
+ @IntRange(from = 0, to = 3)
+ public int getSignalHealthStatusE1b() {
+ return mSignalHealthStatusE1b;
+ }
+
+ /** Returns the E5a data validity status. */
+ @IntRange(from = 0, to = 1)
+ public int getDataValidityStatusE5a() {
+ return mDataValidityStatusE5a;
+ }
+
+ /** Returns the E5a signal health status. */
+ @IntRange(from = 0, to = 3)
+ public int getSignalHealthStatusE5a() {
+ return mSignalHealthStatusE5a;
+ }
+
+ /** Returns the E5b data validity status. */
+ @IntRange(from = 0, to = 1)
+ public int getDataValidityStatusE5b() {
+ return mDataValidityStatusE5b;
+ }
+
+ /** Returns the E5b signal health status. */
+ @IntRange(from = 0, to = 3)
+ public int getSignalHealthStatusE5b() {
+ return mSignalHealthStatusE5b;
+ }
+
+ public static final @NonNull Creator<GalileoSvHealth> CREATOR =
+ new Creator<GalileoSvHealth>() {
+ @Override
+ @NonNull
+ public GalileoSvHealth createFromParcel(Parcel in) {
+ final GalileoSvHealth.Builder galileoSvHealth = new Builder();
+ galileoSvHealth.setDataValidityStatusE1b(in.readInt());
+ galileoSvHealth.setSignalHealthStatusE1b(in.readInt());
+ galileoSvHealth.setDataValidityStatusE5a(in.readInt());
+ galileoSvHealth.setSignalHealthStatusE5a(in.readInt());
+ galileoSvHealth.setDataValidityStatusE5b(in.readInt());
+ galileoSvHealth.setSignalHealthStatusE5b(in.readInt());
+ return galileoSvHealth.build();
+ }
+
+ @Override
+ public GalileoSvHealth[] newArray(int size) {
+ return new GalileoSvHealth[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mDataValidityStatusE1b);
+ parcel.writeInt(mSignalHealthStatusE1b);
+ parcel.writeInt(mDataValidityStatusE5a);
+ parcel.writeInt(mSignalHealthStatusE5a);
+ parcel.writeInt(mDataValidityStatusE5b);
+ parcel.writeInt(mSignalHealthStatusE5b);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GalileoSvHealth[");
+ builder.append("dataValidityStatusE1b = ").append(mDataValidityStatusE1b);
+ builder.append(", signalHealthStatusE1b = ").append(mSignalHealthStatusE1b);
+ builder.append(", dataValidityStatusE5a = ").append(mDataValidityStatusE5a);
+ builder.append(", signalHealthStatusE5a = ").append(mSignalHealthStatusE5a);
+ builder.append(", dataValidityStatusE5b = ").append(mDataValidityStatusE5b);
+ builder.append(", signalHealthStatusE5b = ").append(mSignalHealthStatusE5b);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GalileoSvHealth}. */
+ public static final class Builder {
+ private int mDataValidityStatusE1b;
+ private int mSignalHealthStatusE1b;
+ private int mDataValidityStatusE5a;
+ private int mSignalHealthStatusE5a;
+ private int mDataValidityStatusE5b;
+ private int mSignalHealthStatusE5b;
+
+ /** Sets the E1-B data validity status. */
+ @NonNull
+ public Builder setDataValidityStatusE1b(
+ @IntRange(from = 0, to = 1) int dataValidityStatusE1b) {
+ mDataValidityStatusE1b = dataValidityStatusE1b;
+ return this;
+ }
+
+ /** Sets the E1-B/C signal health status. */
+ @NonNull
+ public Builder setSignalHealthStatusE1b(
+ @IntRange(from = 0, to = 3) int signalHealthStatusE1b) {
+ mSignalHealthStatusE1b = signalHealthStatusE1b;
+ return this;
+ }
+
+ /** Sets the E5a data validity status. */
+ @NonNull
+ public Builder setDataValidityStatusE5a(
+ @IntRange(from = 0, to = 1) int dataValidityStatusE5a) {
+ mDataValidityStatusE5a = dataValidityStatusE5a;
+ return this;
+ }
+
+ /** Sets the E5a signal health status. */
+ @NonNull
+ public Builder setSignalHealthStatusE5a(
+ @IntRange(from = 0, to = 3) int signalHealthStatusE5a) {
+ mSignalHealthStatusE5a = signalHealthStatusE5a;
+ return this;
+ }
+
+ /** Sets the E5b data validity status. */
+ @NonNull
+ public Builder setDataValidityStatusE5b(
+ @IntRange(from = 0, to = 1) int dataValidityStatusE5b) {
+ mDataValidityStatusE5b = dataValidityStatusE5b;
+ return this;
+ }
+
+ /** Sets the E5b signal health status. */
+ @NonNull
+ public Builder setSignalHealthStatusE5b(
+ @IntRange(from = 0, to = 3) int signalHealthStatusE5b) {
+ mSignalHealthStatusE5b = signalHealthStatusE5b;
+ return this;
+ }
+
+ /** Builds a {@link GalileoSvHealth}. */
+ @NonNull
+ public GalileoSvHealth build() {
+ return new GalileoSvHealth(this);
+ }
+ }
+ }
+
+ /**
+ * A class contains the set of parameters needed for Galileo satellite clock correction.
+ *
+ * <p>This is defined in Galileo-OS-SIS-ICD 5.1.3.
+ */
+ public static final class GalileoSatelliteClockModel implements Parcelable {
+
+ /**
+ * The type of the satellite clock.
+ *
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({TYPE_UNDEFINED, TYPE_FNAV, TYPE_INAV})
+ public @interface SatelliteClockType {}
+
+ /**
+ * The following enumerations must be in sync with the values declared in
+ * GalileoSatelliteEphemeris.aidl.
+ */
+
+ /** The type of the satellite clock is unknown. */
+ public static final int TYPE_UNDEFINED = 0;
+
+ /** The type of the satellite clock is FNAV. */
+ public static final int TYPE_FNAV = 1;
+
+ /** The type of the satellite clock is INAV. */
+ public static final int TYPE_INAV = 2;
+
+ /**
+ * Time of the clock in seconds since Galileo epoch.
+ *
+ * <p>Corresponds to the 'Epoch' field within the 'SV/EPOCH/SV CLK' record of Galileo
+ * navigation message in RINEX 3.05 Table A8.
+ */
+ private final long mTimeOfClockSeconds;
+
+ /** SV clock bias correction coefficient in seconds. */
+ private double mAf0;
+
+ /** SV clock drift correction coefficient in seconds per second. */
+ private double mAf1;
+
+ /** SV clock drift rate correction coefficient in seconds per second squared. */
+ private double mAf2;
+
+ /**
+ * Broadcast group delay in seconds.
+ *
+ * <p>This is defined in Galileo-OS-SIS-ICD 5.1.5.
+ */
+ private double mBgdSeconds;
+
+ /**
+ * Signal in space accuracy in meters.
+ *
+ * <p>This is defined in Galileo-OS-SIS-ICD 5.1.12.
+ */
+ private double mSisaMeters;
+
+ /** Type of satellite clock . */
+ private final @SatelliteClockType int mSatelliteClockType;
+
+ private GalileoSatelliteClockModel(Builder builder) {
+ Preconditions.checkArgument(builder.mTimeOfClockSeconds >= 0);
+ Preconditions.checkArgumentInRange(builder.mAf0, -0.0625f, 0.0625f, "AF0");
+ Preconditions.checkArgumentInRange(builder.mAf1, -1.5e-8f, 1.5e-8f, "AF1");
+ Preconditions.checkArgumentInRange(builder.mAf2, -5.56e-17f, 5.56e-17f, "AF2");
+ Preconditions.checkArgumentInRange(
+ builder.mBgdSeconds, -1.2e-7f, 1.2e-7f, "BgdSeconds");
+ Preconditions.checkArgument(builder.mSisaMeters >= 0.0f);
+ Preconditions.checkArgumentInRange(
+ builder.mSatelliteClockType, TYPE_UNDEFINED, TYPE_INAV, "SatelliteClockType");
+ mTimeOfClockSeconds = builder.mTimeOfClockSeconds;
+ mAf0 = builder.mAf0;
+ mAf1 = builder.mAf1;
+ mAf2 = builder.mAf2;
+ mBgdSeconds = builder.mBgdSeconds;
+ mSisaMeters = builder.mSisaMeters;
+ mSatelliteClockType = builder.mSatelliteClockType;
+ }
+
+ /** Returns the time of the clock in seconds since Galileo epoch. */
+ @IntRange(from = 0)
+ public long getTimeOfClockSeconds() {
+ return mTimeOfClockSeconds;
+ }
+
+ /** Returns the SV clock bias correction coefficient in seconds. */
+ @FloatRange(from = -0.0625f, to = 0.0625f)
+ public double getAf0() {
+ return mAf0;
+ }
+
+ /** Returns the SV clock drift correction coefficient in seconds per second. */
+ @FloatRange(from = -1.5e-8f, to = 1.5e-8f)
+ public double getAf1() {
+ return mAf1;
+ }
+
+ /** Returns the SV clock drift rate correction coefficient in seconds per second squared. */
+ @FloatRange(from = -5.56e-17f, to = 5.56e-17f)
+ public double getAf2() {
+ return mAf2;
+ }
+
+ /** Returns the broadcast group delay in seconds. */
+ @FloatRange(from = -1.2e-7f, to = 1.2e-7f)
+ public double getBgdSeconds() {
+ return mBgdSeconds;
+ }
+
+ /** Returns the signal in space accuracy in meters. */
+ @FloatRange(from = 0.0f)
+ public double getSisaMeters() {
+ return mSisaMeters;
+ }
+
+ /** Returns the type of satellite clock. */
+ public @SatelliteClockType int getSatelliteClockType() {
+ return mSatelliteClockType;
+ }
+
+ public static final @NonNull Creator<GalileoSatelliteClockModel> CREATOR =
+ new Creator<GalileoSatelliteClockModel>() {
+ @Override
+ @NonNull
+ public GalileoSatelliteClockModel createFromParcel(Parcel in) {
+ final GalileoSatelliteClockModel.Builder galileoSatelliteClockModel =
+ new Builder();
+ galileoSatelliteClockModel.setTimeOfClockSeconds(in.readLong());
+ galileoSatelliteClockModel.setAf0(in.readDouble());
+ galileoSatelliteClockModel.setAf1(in.readDouble());
+ galileoSatelliteClockModel.setAf2(in.readDouble());
+ galileoSatelliteClockModel.setBgdSeconds(in.readDouble());
+ galileoSatelliteClockModel.setSisaMeters(in.readDouble());
+ galileoSatelliteClockModel.setSatelliteClockType(in.readInt());
+ return galileoSatelliteClockModel.build();
+ }
+
+ @Override
+ public GalileoSatelliteClockModel[] newArray(int size) {
+ return new GalileoSatelliteClockModel[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeLong(mTimeOfClockSeconds);
+ parcel.writeDouble(mAf0);
+ parcel.writeDouble(mAf1);
+ parcel.writeDouble(mAf2);
+ parcel.writeDouble(mBgdSeconds);
+ parcel.writeDouble(mSisaMeters);
+ parcel.writeInt(mSatelliteClockType);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GalileoSatelliteClockModel[");
+ builder.append("timeOfClockSeconds = ").append(mTimeOfClockSeconds);
+ builder.append(", af0 = ").append(mAf0);
+ builder.append(", af1 = ").append(mAf1);
+ builder.append(", af2 = ").append(mAf2);
+ builder.append(", bgdSeconds = ").append(mBgdSeconds);
+ builder.append(", sisaMeters = ").append(mSisaMeters);
+ builder.append(", satelliteClockType = ").append(mSatelliteClockType);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GalileoSatelliteClockModel}. */
+ public static final class Builder {
+ private long mTimeOfClockSeconds;
+ private double mAf0;
+ private double mAf1;
+ private double mAf2;
+ private double mBgdSeconds;
+ private double mSisaMeters;
+ private @SatelliteClockType int mSatelliteClockType;
+
+ /** Sets the time of the clock in seconds since Galileo epoch. */
+ @NonNull
+ public Builder setTimeOfClockSeconds(@IntRange(from = 0) long timeOfClockSeconds) {
+ mTimeOfClockSeconds = timeOfClockSeconds;
+ return this;
+ }
+
+ /** Sets the SV clock bias correction coefficient in seconds. */
+ @NonNull
+ public Builder setAf0(@FloatRange(from = -0.0625f, to = 0.0625f) double af0) {
+ mAf0 = af0;
+ return this;
+ }
+
+ /** Sets the SV clock drift correction coefficient in seconds per second. */
+ @NonNull
+ public Builder setAf1(@FloatRange(from = -1.5e-8f, to = 1.5e-8f) double af1) {
+ mAf1 = af1;
+ return this;
+ }
+
+ /**
+ * Sets the SV clock drift rate correction coefficient in seconds per second squared.
+ */
+ @NonNull
+ public Builder setAf2(@FloatRange(from = -5.56e-17f, to = 5.56e-17f) double af2) {
+ mAf2 = af2;
+ return this;
+ }
+
+ /** Sets the broadcast group delay in seconds. */
+ @NonNull
+ public Builder setBgdSeconds(
+ @FloatRange(from = -1.2e-7f, to = 1.2e-7f) double bgdSeconds) {
+ mBgdSeconds = bgdSeconds;
+ return this;
+ }
+
+ /** Sets the signal in space accuracy in meters. */
+ @NonNull
+ public Builder setSisaMeters(@FloatRange(from = 0.0f) double sisaMeters) {
+ mSisaMeters = sisaMeters;
+ return this;
+ }
+
+ /** Sets the type of satellite clock. */
+ @NonNull
+ public Builder setSatelliteClockType(@SatelliteClockType int satelliteClockType) {
+ mSatelliteClockType = satelliteClockType;
+ return this;
+ }
+
+ /**
+ * Builds a {@link GalileoSatelliteClockModel} instance as specified by this builder.
+ */
+ @NonNull
+ public GalileoSatelliteClockModel build() {
+ return new GalileoSatelliteClockModel(this);
+ }
+ }
+ }
+}
diff --git a/location/java/android/location/GlonassAlmanac.java b/location/java/android/location/GlonassAlmanac.java
new file mode 100644
index 0000000..861dc5d
--- /dev/null
+++ b/location/java/android/location/GlonassAlmanac.java
@@ -0,0 +1,418 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains Glonass almanac data.
+ *
+ * <p>This is defined in Glonass ICD v5.1 section 4.5.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GlonassAlmanac implements Parcelable {
+
+ /** Almanac issue date in milliseconds (UTC) */
+ private final long mIssueDateMillis;
+
+ /** List of GlonassSatelliteAlmanacs. */
+ @NonNull private final List<GlonassSatelliteAlmanac> mSatelliteAlmanacs;
+
+ /**
+ * Constructor for GlonassAlmanac.
+ *
+ * @param issueDateMillis The almanac issue date in milliseconds (UTC).
+ * @param satelliteAlmanacs The list of GlonassSatelliteAlmanac.
+ */
+ public GlonassAlmanac(
+ @IntRange(from = 0) long issueDateMillis,
+ @NonNull List<GlonassSatelliteAlmanac> satelliteAlmanacs) {
+ Preconditions.checkArgument(issueDateMillis >= 0);
+ Preconditions.checkNotNull(satelliteAlmanacs, "satelliteAlmanacs cannot be null");
+ mIssueDateMillis = issueDateMillis;
+ mSatelliteAlmanacs = Collections.unmodifiableList(new ArrayList<>(satelliteAlmanacs));
+ }
+
+ /** Returns the almanac issue date in milliseconds (UTC). */
+ @IntRange(from = 0)
+ public long getIssueDateMillis() {
+ return mIssueDateMillis;
+ }
+
+ /** Returns the list of GlonassSatelliteAlmanacs. */
+ @NonNull
+ public List<GlonassSatelliteAlmanac> getSatelliteAlmanacs() {
+ return mSatelliteAlmanacs;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeLong(mIssueDateMillis);
+ dest.writeTypedList(mSatelliteAlmanacs);
+ }
+
+ public static final @NonNull Parcelable.Creator<GlonassAlmanac> CREATOR =
+ new Parcelable.Creator<GlonassAlmanac>() {
+ @Override
+ public GlonassAlmanac createFromParcel(@NonNull Parcel in) {
+ long issueDateMillis = in.readLong();
+ List<GlonassSatelliteAlmanac> satelliteAlmanacs = new ArrayList<>();
+ in.readTypedList(satelliteAlmanacs, GlonassSatelliteAlmanac.CREATOR);
+ return new GlonassAlmanac(issueDateMillis, satelliteAlmanacs);
+ }
+
+ @Override
+ public GlonassAlmanac[] newArray(int size) {
+ return new GlonassAlmanac[size];
+ }
+ };
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GlonassAlmanac[");
+ builder.append("issueDateMillis = ").append(mIssueDateMillis);
+ builder.append(", satelliteAlmanacs = ").append(mSatelliteAlmanacs);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /**
+ * A class contains Glonass satellite almanac data.
+ *
+ * <p>This is defined in Glonass ICD v5.1 section 4.5.
+ */
+ public static final class GlonassSatelliteAlmanac implements Parcelable {
+ /** Slot number. */
+ private final int mSlotNumber;
+
+ /** Satellite health information (0=healthy, 1=unhealthy). */
+ private final int mSvHealth;
+
+ /** Frequency channel number. */
+ private final int mFreqChannel;
+
+ /** Coarse value of satellite time correction to GLONASS time in seconds. */
+ private final double mTau;
+
+ /** Time of first ascending node passage of satellite in seconds. */
+ private final double mTLambda;
+
+ /** Longitude of the first ascending node in semi-circles. */
+ private final double mLambda;
+
+ /** Correction to the mean value of inclination in semi-circles. */
+ private final double mDeltaI;
+
+ /** Correction to the mean value of the draconian period in seconds per orbital period */
+ private final double mDeltaT;
+
+ /** Rate of change of draconian period in seconds per orbital period squared. */
+ private final double mDeltaTDot;
+
+ /** Eccentricity. */
+ private final double mEccentricity;
+
+ /** Argument of perigee in radians. */
+ private final double mOmega;
+
+ private GlonassSatelliteAlmanac(Builder builder) {
+ // Allow slotNumber beyond the range to support potential future extensibility.
+ Preconditions.checkArgument(builder.mSlotNumber >= 1);
+ // Allow svHealth beyond the range to support potential future extensibility.
+ Preconditions.checkArgument(builder.mSvHealth >= 0);
+ Preconditions.checkArgumentInRange(builder.mFreqChannel, 0, 31, "FreqChannel");
+ Preconditions.checkArgumentInRange(builder.mTau, -1.9e-3f, 1.9e-3f, "Tau");
+ Preconditions.checkArgumentInRange(builder.mTLambda, 0.0f, 44100.0f, "TLambda");
+ Preconditions.checkArgumentInRange(builder.mLambda, -1.0f, 1.0f, "Lambda");
+ Preconditions.checkArgumentInRange(builder.mDeltaI, -0.067f, 0.067f, "DeltaI");
+ Preconditions.checkArgumentInRange(builder.mDeltaT, -3600.0f, 3600.0f, "DeltaT");
+ Preconditions.checkArgumentInRange(builder.mDeltaTDot, -0.004f, 0.004f, "DeltaTDot");
+ Preconditions.checkArgumentInRange(builder.mEccentricity, 0.0f, 0.03f, "Eccentricity");
+ Preconditions.checkArgumentInRange(builder.mOmega, -1.0f, 1.0f, "Omega");
+ mSlotNumber = builder.mSlotNumber;
+ mSvHealth = builder.mSvHealth;
+ mFreqChannel = builder.mFreqChannel;
+ mTau = builder.mTau;
+ mTLambda = builder.mTLambda;
+ mLambda = builder.mLambda;
+ mDeltaI = builder.mDeltaI;
+ mDeltaT = builder.mDeltaT;
+ mDeltaTDot = builder.mDeltaTDot;
+ mEccentricity = builder.mEccentricity;
+ mOmega = builder.mOmega;
+ }
+
+ /** Returns the slot number. */
+ @IntRange(from = 1, to = 25)
+ public int getSlotNumber() {
+ return mSlotNumber;
+ }
+
+ /** Returns the Satellite health information (0=healthy, 1=unhealthy). */
+ @IntRange(from = 0, to = 1)
+ public int getSvHealth() {
+ return mSvHealth;
+ }
+
+ /** Returns the frequency channel number. */
+ @IntRange(from = 0, to = 31)
+ public int getFreqChannel() {
+ return mFreqChannel;
+ }
+
+ /** Returns the coarse value of satellite time correction to GLONASS time in seconds. */
+ @FloatRange(from = -1.9e-3f, to = 1.9e-3f)
+ public double getTau() {
+ return mTau;
+ }
+
+ /** Returns the time of first ascending node passage of satellite in seconds. */
+ @FloatRange(from = 0.0f, to = 44100.0f)
+ public double getTLambda() {
+ return mTLambda;
+ }
+
+ /** Returns the longitude of the first ascending node in semi-circles. */
+ @FloatRange(from = -1.0f, to = 1.0f)
+ public double getLambda() {
+ return mLambda;
+ }
+
+ /** Returns the correction to the mean value of inclination in semi-circles. */
+ @FloatRange(from = -0.067f, to = 0.067f)
+ public double getDeltaI() {
+ return mDeltaI;
+ }
+
+ /**
+ * Returns the correction to the mean value of the draconian period in seconds per orbital
+ * period
+ */
+ @FloatRange(from = -3600.0f, to = 3600.0f)
+ public double getDeltaT() {
+ return mDeltaT;
+ }
+
+ /** Returns the rate of change of draconian period in seconds per orbital period squared. */
+ @FloatRange(from = -0.004f, to = 0.004f)
+ public double getDeltaTDot() {
+ return mDeltaTDot;
+ }
+
+ /** Returns the eccentricity. */
+ @FloatRange(from = 0.0f, to = 0.03f)
+ public double getEccentricity() {
+ return mEccentricity;
+ }
+
+ /** Returns the argument of perigee in radians. */
+ @FloatRange(from = -1.0f, to = 1.0f)
+ public double getOmega() {
+ return mOmega;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mSlotNumber);
+ dest.writeInt(mSvHealth);
+ dest.writeInt(mFreqChannel);
+ dest.writeDouble(mTau);
+ dest.writeDouble(mTLambda);
+ dest.writeDouble(mLambda);
+ dest.writeDouble(mDeltaI);
+ dest.writeDouble(mDeltaT);
+ dest.writeDouble(mDeltaTDot);
+ dest.writeDouble(mEccentricity);
+ dest.writeDouble(mOmega);
+ }
+
+ public static final @NonNull Parcelable.Creator<GlonassSatelliteAlmanac> CREATOR =
+ new Parcelable.Creator<GlonassSatelliteAlmanac>() {
+ @Override
+ public GlonassSatelliteAlmanac createFromParcel(@NonNull Parcel source) {
+ return new GlonassSatelliteAlmanac.Builder()
+ .setSlotNumber(source.readInt())
+ .setSvHealth(source.readInt())
+ .setFreqChannel(source.readInt())
+ .setTau(source.readDouble())
+ .setTLambda(source.readDouble())
+ .setLambda(source.readDouble())
+ .setDeltaI(source.readDouble())
+ .setDeltaT(source.readDouble())
+ .setDeltaTDot(source.readDouble())
+ .setEccentricity(source.readDouble())
+ .setOmega(source.readDouble())
+ .build();
+ }
+
+ @Override
+ public GlonassSatelliteAlmanac[] newArray(int size) {
+ return new GlonassSatelliteAlmanac[size];
+ }
+ };
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GlonassSatelliteAlmanac[");
+ builder.append("slotNumber = ").append(mSlotNumber);
+ builder.append(", svHealth = ").append(mSvHealth);
+ builder.append(", freqChannel = ").append(mFreqChannel);
+ builder.append(", tau = ").append(mTau);
+ builder.append(", tLambda = ").append(mTLambda);
+ builder.append(", lambda = ").append(mLambda);
+ builder.append(", deltaI = ").append(mDeltaI);
+ builder.append(", deltaT = ").append(mDeltaT);
+ builder.append(", deltaTDot = ").append(mDeltaTDot);
+ builder.append(", eccentricity = ").append(mEccentricity);
+ builder.append(", omega = ").append(mOmega);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GlonassSatelliteAlmanac}. */
+ public static final class Builder {
+ private int mSlotNumber;
+ private int mSvHealth;
+ private int mFreqChannel;
+ private double mTau;
+ private double mTLambda;
+ private double mLambda;
+ private double mDeltaI;
+ private double mDeltaT;
+ private double mDeltaTDot;
+ private double mEccentricity;
+ private double mOmega;
+
+ /** Sets the slot number. */
+ @NonNull
+ public Builder setSlotNumber(@IntRange(from = 1, to = 25) int slotNumber) {
+ mSlotNumber = slotNumber;
+ return this;
+ }
+
+ /** Sets the Satellite health information (0=healthy, 1=unhealthy). */
+ @NonNull
+ public Builder setSvHealth(@IntRange(from = 0, to = 1) int svHealth) {
+ mSvHealth = svHealth;
+ return this;
+ }
+
+ /** Sets the frequency channel number. */
+ @NonNull
+ public Builder setFreqChannel(@IntRange(from = 0, to = 31) int freqChannel) {
+ mFreqChannel = freqChannel;
+ return this;
+ }
+
+ /** Sets the coarse value of satellite time correction to GLONASS time in seconds. */
+ @NonNull
+ public Builder setTau(@FloatRange(from = -1.9e-3f, to = 1.9e-3f) double tau) {
+ mTau = tau;
+ return this;
+ }
+
+ /** Sets the time of first ascending node passage of satellite in seconds. */
+ @NonNull
+ public Builder setTLambda(@FloatRange(from = 0.0f, to = 44100.0f) double tLambda) {
+ mTLambda = tLambda;
+ return this;
+ }
+
+ /** Sets the longitude of the first ascending node in semi-circles. */
+ @NonNull
+ public Builder setLambda(@FloatRange(from = -1.0f, to = 1.0f) double lambda) {
+ mLambda = lambda;
+ return this;
+ }
+
+ /** Sets the correction to the mean value of inclination in semi-circles. */
+ @NonNull
+ public Builder setDeltaI(@FloatRange(from = -0.067f, to = 0.067f) double deltaI) {
+ mDeltaI = deltaI;
+ return this;
+ }
+
+ /**
+ * Sets the correction to the mean value of the draconian period in seconds per orbital
+ * period.
+ */
+ @NonNull
+ public Builder setDeltaT(@FloatRange(from = -3600.0f, to = 3600.0f) double deltaT) {
+ mDeltaT = deltaT;
+ return this;
+ }
+
+ /**
+ * Sets the rate of change of draconian period in seconds per orbital period squared.
+ */
+ @NonNull
+ public Builder setDeltaTDot(@FloatRange(from = -0.004f, to = 0.004f) double deltaTDot) {
+ mDeltaTDot = deltaTDot;
+ return this;
+ }
+
+ /** Sets the eccentricity. */
+ @NonNull
+ public Builder setEccentricity(
+ @FloatRange(from = 0.0f, to = 0.03f) double eccentricity) {
+ mEccentricity = eccentricity;
+ return this;
+ }
+
+ /** Sets the argument of perigee in radians. */
+ @NonNull
+ public Builder setOmega(@FloatRange(from = -1.0f, to = 1.0f) double omega) {
+ mOmega = omega;
+ return this;
+ }
+
+ /** Builds a {@link GlonassSatelliteAlmanac}. */
+ @NonNull
+ public GlonassSatelliteAlmanac build() {
+ return new GlonassSatelliteAlmanac(this);
+ }
+ }
+ }
+}
diff --git a/location/java/android/location/GlonassAssistance.java b/location/java/android/location/GlonassAssistance.java
new file mode 100644
index 0000000..cc08201
--- /dev/null
+++ b/location/java/android/location/GlonassAssistance.java
@@ -0,0 +1,213 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.location.GnssAssistance.GnssSatelliteCorrections;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains Glonass assistance.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GlonassAssistance implements Parcelable {
+
+ /** The Glonass almanac. */
+ @Nullable private final GlonassAlmanac mAlmanac;
+
+ /** The UTC model. */
+ @Nullable private final UtcModel mUtcModel;
+
+ /** The list of time models. */
+ @NonNull private final List<TimeModel> mTimeModels;
+
+ /** The list of Glonass ephemeris. */
+ @NonNull private final List<GlonassSatelliteEphemeris> mSatelliteEphemeris;
+
+ /** The list of Glonass satellite corrections. */
+ @NonNull private final List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+ private GlonassAssistance(Builder builder) {
+ mAlmanac = builder.mAlmanac;
+ mUtcModel = builder.mUtcModel;
+ if (builder.mTimeModels != null) {
+ mTimeModels = Collections.unmodifiableList(new ArrayList<>(builder.mTimeModels));
+ } else {
+ mTimeModels = new ArrayList<>();
+ }
+ if (builder.mSatelliteEphemeris != null) {
+ mSatelliteEphemeris =
+ Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteEphemeris));
+ } else {
+ mSatelliteEphemeris = new ArrayList<>();
+ }
+ if (builder.mSatelliteCorrections != null) {
+ mSatelliteCorrections =
+ Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteCorrections));
+ } else {
+ mSatelliteCorrections = new ArrayList<>();
+ }
+ }
+
+ /** Returns the Glonass almanac. */
+ @Nullable
+ public GlonassAlmanac getAlmanac() {
+ return mAlmanac;
+ }
+
+ /** Returns the UTC model. */
+ @Nullable
+ public UtcModel getUtcModel() {
+ return mUtcModel;
+ }
+
+ /** Returns the list of time models. */
+ @NonNull
+ public List<TimeModel> getTimeModels() {
+ return mTimeModels;
+ }
+
+ /** Returns the list of Glonass satellite ephemeris. */
+ @NonNull
+ public List<GlonassSatelliteEphemeris> getSatelliteEphemeris() {
+ return mSatelliteEphemeris;
+ }
+
+ /** Returns the list of Glonass satellite corrections. */
+ @NonNull
+ public List<GnssSatelliteCorrections> getSatelliteCorrections() {
+ return mSatelliteCorrections;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeTypedObject(mAlmanac, flags);
+ dest.writeTypedObject(mUtcModel, flags);
+ dest.writeTypedList(mTimeModels);
+ dest.writeTypedList(mSatelliteEphemeris);
+ dest.writeTypedList(mSatelliteCorrections);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GlonassAssistance[");
+ builder.append("almanac = ").append(mAlmanac);
+ builder.append(", utcModel = ").append(mUtcModel);
+ builder.append(", timeModels = ").append(mTimeModels);
+ builder.append(", satelliteEphemeris = ").append(mSatelliteEphemeris);
+ builder.append(", satelliteCorrections = ").append(mSatelliteCorrections);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ public static final @NonNull Creator<GlonassAssistance> CREATOR =
+ new Creator<GlonassAssistance>() {
+ @Override
+ public GlonassAssistance createFromParcel(Parcel in) {
+ return new GlonassAssistance.Builder()
+ .setAlmanac(in.readTypedObject(GlonassAlmanac.CREATOR))
+ .setUtcModel(in.readTypedObject(UtcModel.CREATOR))
+ .setTimeModels(in.createTypedArrayList(TimeModel.CREATOR))
+ .setSatelliteEphemeris(
+ in.createTypedArrayList(GlonassSatelliteEphemeris.CREATOR))
+ .setSatelliteCorrections(
+ in.createTypedArrayList(GnssSatelliteCorrections.CREATOR))
+ .build();
+ }
+
+ @Override
+ public GlonassAssistance[] newArray(int size) {
+ return new GlonassAssistance[size];
+ }
+ };
+
+ /** Builder for {@link GlonassAssistance}. */
+ public static final class Builder {
+ private GlonassAlmanac mAlmanac;
+ private UtcModel mUtcModel;
+ private List<TimeModel> mTimeModels;
+ private List<GlonassSatelliteEphemeris> mSatelliteEphemeris;
+ private List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+ /** Sets the Glonass almanac. */
+ @NonNull
+ public Builder setAlmanac(
+ @Nullable @SuppressLint("NullableCollection") GlonassAlmanac almanac) {
+ mAlmanac = almanac;
+ return this;
+ }
+
+ /** Sets the UTC model. */
+ @NonNull
+ public Builder setUtcModel(
+ @Nullable @SuppressLint("NullableCollection") UtcModel utcModel) {
+ mUtcModel = utcModel;
+ return this;
+ }
+
+ /** Sets the list of time models. */
+ @NonNull
+ public Builder setTimeModels(
+ @Nullable @SuppressLint("NullableCollection") List<TimeModel> timeModels) {
+ mTimeModels = timeModels;
+ return this;
+ }
+
+ /** Sets the list of Glonass satellite ephemeris. */
+ @NonNull
+ public Builder setSatelliteEphemeris(
+ @Nullable @SuppressLint("NullableCollection")
+ List<GlonassSatelliteEphemeris> satelliteEphemeris) {
+ mSatelliteEphemeris = satelliteEphemeris;
+ return this;
+ }
+
+ /** Sets the list of Glonass satellite corrections. */
+ @NonNull
+ public Builder setSatelliteCorrections(
+ @Nullable @SuppressLint("NullableCollection")
+ List<GnssSatelliteCorrections> satelliteCorrections) {
+ mSatelliteCorrections = satelliteCorrections;
+ return this;
+ }
+
+ /** Builds the {@link GlonassAssistance}. */
+ @NonNull
+ public GlonassAssistance build() {
+ return new GlonassAssistance(this);
+ }
+ }
+}
diff --git a/location/java/android/location/GlonassSatelliteEphemeris.java b/location/java/android/location/GlonassSatelliteEphemeris.java
new file mode 100644
index 0000000..77a6ebb
--- /dev/null
+++ b/location/java/android/location/GlonassSatelliteEphemeris.java
@@ -0,0 +1,623 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains ephemeris parameters specific to Glonass satellites.
+ *
+ * <p>This is defined in RINEX 3.05 APPENDIX 10 and Glonass ICD v5.1 section 4.4.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GlonassSatelliteEphemeris implements Parcelable {
+
+ /** L1/Satellite system (R), satellite number (slot number in sat. constellation). */
+ private final int mSlotNumber;
+
+ /** Health state (0=healthy, 1=unhealthy). */
+ private final int mHealthState;
+
+ /** Message frame time in seconds of the UTC week (tk+nd*86400). */
+ private final double mFrameTimeSeconds;
+
+ /** Age of current information in days (E). */
+ private final int mAgeInDays;
+
+ /** Satellite clock model. */
+ @NonNull private final GlonassSatelliteClockModel mSatelliteClockModel;
+
+ /** Satellite orbit model. */
+ @NonNull private final GlonassSatelliteOrbitModel mSatelliteOrbitModel;
+
+ private GlonassSatelliteEphemeris(Builder builder) {
+ // Allow SlotNumber beyond the range to support potential future extensibility.
+ Preconditions.checkArgument(builder.mSlotNumber >= 1);
+ // Allow HealthState beyond the range to support potential future extensibility.
+ Preconditions.checkArgument(builder.mHealthState >= 0);
+ Preconditions.checkArgument(builder.mFrameTimeSeconds >= 0.0f);
+ Preconditions.checkArgumentInRange(builder.mAgeInDays, 0, 31, "AgeInDays");
+ Preconditions.checkNotNull(
+ builder.mSatelliteClockModel, "SatelliteClockModel cannot be null");
+ Preconditions.checkNotNull(
+ builder.mSatelliteOrbitModel, "SatelliteOrbitModel cannot be null");
+ mSlotNumber = builder.mSlotNumber;
+ mHealthState = builder.mHealthState;
+ mFrameTimeSeconds = builder.mFrameTimeSeconds;
+ mAgeInDays = builder.mAgeInDays;
+ mSatelliteClockModel = builder.mSatelliteClockModel;
+ mSatelliteOrbitModel = builder.mSatelliteOrbitModel;
+ }
+
+ /**
+ * Returns the L1/Satellite system (R), satellite number (slot number in sat. constellation).
+ */
+ @IntRange(from = 1, to = 25)
+ public int getSlotNumber() {
+ return mSlotNumber;
+ }
+
+ /** Returns the health state (0=healthy, 1=unhealthy). */
+ @IntRange(from = 0, to = 1)
+ public int getHealthState() {
+ return mHealthState;
+ }
+
+ /** Returns the message frame time in seconds of the UTC week (tk+nd*86400). */
+ @FloatRange(from = 0.0f)
+ public double getFrameTimeSeconds() {
+ return mFrameTimeSeconds;
+ }
+
+ /** Returns the age of current information in days (E). */
+ @IntRange(from = 0, to = 31)
+ public int getAgeInDays() {
+ return mAgeInDays;
+ }
+
+ /** Returns the satellite clock model. */
+ @NonNull
+ public GlonassSatelliteClockModel getSatelliteClockModel() {
+ return mSatelliteClockModel;
+ }
+
+ /** Returns the satellite orbit model. */
+ @NonNull
+ public GlonassSatelliteOrbitModel getSatelliteOrbitModel() {
+ return mSatelliteOrbitModel;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mSlotNumber);
+ dest.writeInt(mHealthState);
+ dest.writeDouble(mFrameTimeSeconds);
+ dest.writeInt(mAgeInDays);
+ dest.writeTypedObject(mSatelliteClockModel, flags);
+ dest.writeTypedObject(mSatelliteOrbitModel, flags);
+ }
+
+ public static final @NonNull Parcelable.Creator<GlonassSatelliteEphemeris> CREATOR =
+ new Parcelable.Creator<GlonassSatelliteEphemeris>() {
+ @Override
+ public GlonassSatelliteEphemeris createFromParcel(@NonNull Parcel source) {
+ return new GlonassSatelliteEphemeris.Builder()
+ .setSlotNumber(source.readInt())
+ .setHealthState(source.readInt())
+ .setFrameTimeSeconds(source.readDouble())
+ .setAgeInDays(source.readInt())
+ .setSatelliteClockModel(
+ source.readTypedObject(GlonassSatelliteClockModel.CREATOR))
+ .setSatelliteOrbitModel(
+ source.readTypedObject(GlonassSatelliteOrbitModel.CREATOR))
+ .build();
+ }
+
+ @Override
+ public GlonassSatelliteEphemeris[] newArray(int size) {
+ return new GlonassSatelliteEphemeris[size];
+ }
+ };
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GlonassSatelliteEphemeris[");
+ builder.append("slotNumber = ").append(mSlotNumber);
+ builder.append(", healthState = ").append(mHealthState);
+ builder.append(", frameTimeSeconds = ").append(mFrameTimeSeconds);
+ builder.append(", ageInDays = ").append(mAgeInDays);
+ builder.append(", satelliteClockModel = ").append(mSatelliteClockModel);
+ builder.append(", satelliteOrbitModel = ").append(mSatelliteOrbitModel);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GlonassSatelliteEphemeris}. */
+ public static final class Builder {
+ private int mSlotNumber;
+ private int mHealthState;
+ private double mFrameTimeSeconds;
+ private int mAgeInDays;
+ private GlonassSatelliteClockModel mSatelliteClockModel;
+ private GlonassSatelliteOrbitModel mSatelliteOrbitModel;
+
+ /**
+ * Sets the L1/Satellite system (R), satellite number (slot number in sat. constellation).
+ */
+ @NonNull
+ public Builder setSlotNumber(@IntRange(from = 1, to = 25) int slotNumber) {
+ mSlotNumber = slotNumber;
+ return this;
+ }
+
+ /** Sets the health state (0=healthy, 1=unhealthy). */
+ @NonNull
+ public Builder setHealthState(@IntRange(from = 0, to = 1) int healthState) {
+ mHealthState = healthState;
+ return this;
+ }
+
+ /** Sets the message frame time in seconds of the UTC week (tk+nd*86400). */
+ @NonNull
+ public Builder setFrameTimeSeconds(@FloatRange(from = 0.0f) double frameTimeSeconds) {
+ mFrameTimeSeconds = frameTimeSeconds;
+ return this;
+ }
+
+ /** Sets the age of current information in days (E). */
+ @NonNull
+ public Builder setAgeInDays(@IntRange(from = 0, to = 31) int ageInDays) {
+ mAgeInDays = ageInDays;
+ return this;
+ }
+
+ /** Sets the satellite clock model. */
+ @NonNull
+ public Builder setSatelliteClockModel(
+ @NonNull GlonassSatelliteClockModel satelliteClockModel) {
+ mSatelliteClockModel = satelliteClockModel;
+ return this;
+ }
+
+ /** Sets the satellite orbit model. */
+ @NonNull
+ public Builder setSatelliteOrbitModel(
+ @NonNull GlonassSatelliteOrbitModel satelliteOrbitModel) {
+ mSatelliteOrbitModel = satelliteOrbitModel;
+ return this;
+ }
+
+ /** Builds a {@link GlonassSatelliteEphemeris}. */
+ @NonNull
+ public GlonassSatelliteEphemeris build() {
+ return new GlonassSatelliteEphemeris(this);
+ }
+ }
+
+ /**
+ * A class contains the set of parameters needed for Glonass satellite clock correction.
+ *
+ * <p>This is defined in RINEX 3.05 APPENDIX 10 and Glonass ICD v5.1 section 4.4.
+ */
+ public static final class GlonassSatelliteClockModel implements Parcelable {
+ /**
+ * Time of the clock in seconds (UTC)
+ *
+ * <p>Corresponds to the 'Epoch' field within the 'SV/EPOCH/SV CLK' record of Glonass
+ * navigation message in RINEX 3.05 Table A10.
+ */
+ private final long mTimeOfClockSeconds;
+
+ /** Clock bias in seconds (-TauN). */
+ private final double mClockBias;
+
+ /** Frequency bias (+GammaN). */
+ private final double mFrequencyBias;
+
+ /** Frequency number. */
+ private final int mFrequencyNumber;
+
+ private GlonassSatelliteClockModel(Builder builder) {
+ Preconditions.checkArgument(builder.mTimeOfClockSeconds >= 0);
+ Preconditions.checkArgumentInRange(builder.mClockBias, -0.002f, 0.002f, "ClockBias");
+ Preconditions.checkArgumentInRange(
+ builder.mFrequencyBias, -9.32e-10f, 9.32e-10f, "FrequencyBias");
+ Preconditions.checkArgumentInRange(builder.mFrequencyNumber, -7, 6, "FrequencyNumber");
+ mTimeOfClockSeconds = builder.mTimeOfClockSeconds;
+ mClockBias = builder.mClockBias;
+ mFrequencyBias = builder.mFrequencyBias;
+ mFrequencyNumber = builder.mFrequencyNumber;
+ }
+
+ /** Returns the time of clock in seconds (UTC). */
+ @IntRange(from = 0)
+ public long getTimeOfClockSeconds() {
+ return mTimeOfClockSeconds;
+ }
+
+ /** Returns the clock bias in seconds (-TauN). */
+ @FloatRange(from = -0.002f, to = 0.002f)
+ public double getClockBias() {
+ return mClockBias;
+ }
+
+ /** Returns the frequency bias (+GammaN). */
+ @FloatRange(from = -9.32e-10f, to = 9.32e-10f)
+ public double getFrequencyBias() {
+ return mFrequencyBias;
+ }
+
+ /** Returns the frequency number. */
+ @IntRange(from = -7, to = 6)
+ public int getFrequencyNumber() {
+ return mFrequencyNumber;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeLong(mTimeOfClockSeconds);
+ dest.writeDouble(mClockBias);
+ dest.writeDouble(mFrequencyBias);
+ dest.writeInt(mFrequencyNumber);
+ }
+
+ public static final @NonNull Parcelable.Creator<GlonassSatelliteClockModel> CREATOR =
+ new Parcelable.Creator<GlonassSatelliteClockModel>() {
+ @Override
+ public GlonassSatelliteClockModel createFromParcel(@NonNull Parcel source) {
+ return new GlonassSatelliteClockModel.Builder()
+ .setTimeOfClockSeconds(source.readLong())
+ .setClockBias(source.readDouble())
+ .setFrequencyBias(source.readDouble())
+ .setFrequencyNumber(source.readInt())
+ .build();
+ }
+
+ @Override
+ public GlonassSatelliteClockModel[] newArray(int size) {
+ return new GlonassSatelliteClockModel[size];
+ }
+ };
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GlonassSatelliteClockModel[");
+ builder.append("timeOfClockSeconds = ").append(mTimeOfClockSeconds);
+ builder.append(", clockBias = ").append(mClockBias);
+ builder.append(", frequencyBias = ").append(mFrequencyBias);
+ builder.append(", frequencyNumber = ").append(mFrequencyNumber);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GlonassSatelliteClockModel}. */
+ public static final class Builder {
+ private long mTimeOfClockSeconds;
+ private double mClockBias;
+ private double mFrequencyBias;
+ private int mFrequencyNumber;
+
+ /** Sets the time of clock in seconds (UTC). */
+ @NonNull
+ public Builder setTimeOfClockSeconds(@IntRange(from = 0) long timeOfClockSeconds) {
+ mTimeOfClockSeconds = timeOfClockSeconds;
+ return this;
+ }
+
+ /** Sets the clock bias in seconds (-TauN). */
+ @NonNull
+ public Builder setClockBias(@FloatRange(from = -0.002f, to = 0.002f) double clockBias) {
+ mClockBias = clockBias;
+ return this;
+ }
+
+ /** Sets the frequency bias (+GammaN). */
+ @NonNull
+ public Builder setFrequencyBias(
+ @FloatRange(from = -9.32e-10f, to = 9.32e-10f) double frequencyBias) {
+ mFrequencyBias = frequencyBias;
+ return this;
+ }
+
+ /** Sets the frequency number. */
+ @NonNull
+ public Builder setFrequencyNumber(@IntRange(from = -7, to = 6) int frequencyNumber) {
+ mFrequencyNumber = frequencyNumber;
+ return this;
+ }
+
+ /** Builds a {@link GlonassSatelliteClockModel}. */
+ @NonNull
+ public GlonassSatelliteClockModel build() {
+ return new GlonassSatelliteClockModel(this);
+ }
+ }
+ }
+
+ /**
+ * A class contains the set of parameters needed for Glonass satellite orbit correction.
+ *
+ * <p>This is defined in RINEX 3.05 APPENDIX 10 and Glonass ICD v5.1 section 4.4.
+ */
+ public static final class GlonassSatelliteOrbitModel implements Parcelable {
+ /** X position in kilometers. */
+ private final double mX;
+
+ /** X velocity in kilometers per second. */
+ private final double mXDot;
+
+ /** X acceleration in kilometers per second squared. */
+ private final double mXAccel;
+
+ /** Y position in kilometers. */
+ private final double mY;
+
+ /** Y velocity in kilometers per second. */
+ private final double mYDot;
+
+ /** Y acceleration in kilometers per second squared. */
+ private final double mYAccel;
+
+ /** Z position in kilometers. */
+ private final double mZ;
+
+ /** Z velocity in kilometers per second. */
+ private final double mZDot;
+
+ /** Z acceleration in kilometers per second squared. */
+ private final double mZAccel;
+
+ private GlonassSatelliteOrbitModel(Builder builder) {
+ Preconditions.checkArgumentInRange(builder.mX, -2.7e4f, 2.7e4f, "X");
+ Preconditions.checkArgumentInRange(builder.mXDot, -4.3f, 4.3f, "XDot");
+ Preconditions.checkArgumentInRange(builder.mXAccel, -6.2e-9f, 6.2e-9f, "XAccel");
+ Preconditions.checkArgumentInRange(builder.mY, -2.7e4f, 2.7e4f, "Y");
+ Preconditions.checkArgumentInRange(builder.mYDot, -4.3f, 4.3f, "YDot");
+ Preconditions.checkArgumentInRange(builder.mYAccel, -6.2e-9f, 6.2e-9f, "YAccel");
+ Preconditions.checkArgumentInRange(builder.mZ, -2.7e4f, 2.7e4f, "Z");
+ Preconditions.checkArgumentInRange(builder.mZDot, -4.3f, 4.3f, "ZDot");
+ Preconditions.checkArgumentInRange(builder.mZAccel, -6.2e-9f, 6.2e-9f, "ZAccel");
+ mX = builder.mX;
+ mXDot = builder.mXDot;
+ mXAccel = builder.mXAccel;
+ mY = builder.mY;
+ mYDot = builder.mYDot;
+ mYAccel = builder.mYAccel;
+ mZ = builder.mZ;
+ mZDot = builder.mZDot;
+ mZAccel = builder.mZAccel;
+ }
+
+ /** Returns the X position in kilometers. */
+ @FloatRange(from = -2.7e4f, to = 2.7e4f)
+ public double getX() {
+ return mX;
+ }
+
+ /** Returns the X velocity in kilometers per second. */
+ @FloatRange(from = -4.3f, to = 4.3f)
+ public double getXDot() {
+ return mXDot;
+ }
+
+ /** Returns the X acceleration in kilometers per second squared. */
+ @FloatRange(from = -6.2e-9f, to = 6.2e-9f)
+ public double getXAccel() {
+ return mXAccel;
+ }
+
+ /** Returns the Y position in kilometers. */
+ @FloatRange(from = -2.7e4f, to = 2.7e4f)
+ public double getY() {
+ return mY;
+ }
+
+ /** Returns the Y velocity in kilometers per second. */
+ @FloatRange(from = -4.3f, to = 4.3f)
+ public double getYDot() {
+ return mYDot;
+ }
+
+ /** Returns the Y acceleration in kilometers per second squared. */
+ @FloatRange(from = -6.2e-9f, to = 6.2e-9f)
+ public double getYAccel() {
+ return mYAccel;
+ }
+
+ /** Returns the Z position in kilometers. */
+ @FloatRange(from = -2.7e4f, to = 2.7e4f)
+ public double getZ() {
+ return mZ;
+ }
+
+ /** Returns the Z velocity in kilometers per second. */
+ @FloatRange(from = -4.3f, to = 4.3f)
+ public double getZDot() {
+ return mZDot;
+ }
+
+ /** Returns the Z acceleration in kilometers per second squared. */
+ @FloatRange(from = -6.2e-9f, to = 6.2e-9f)
+ public double getZAccel() {
+ return mZAccel;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeDouble(mX);
+ dest.writeDouble(mXDot);
+ dest.writeDouble(mXAccel);
+ dest.writeDouble(mY);
+ dest.writeDouble(mYDot);
+ dest.writeDouble(mYAccel);
+ dest.writeDouble(mZ);
+ dest.writeDouble(mZDot);
+ dest.writeDouble(mZAccel);
+ }
+
+ public static final @NonNull Parcelable.Creator<GlonassSatelliteOrbitModel> CREATOR =
+ new Parcelable.Creator<GlonassSatelliteOrbitModel>() {
+ @Override
+ public GlonassSatelliteOrbitModel createFromParcel(@NonNull Parcel source) {
+ return new GlonassSatelliteOrbitModel.Builder()
+ .setX(source.readDouble())
+ .setXDot(source.readDouble())
+ .setXAccel(source.readDouble())
+ .setY(source.readDouble())
+ .setYDot(source.readDouble())
+ .setYAccel(source.readDouble())
+ .setZ(source.readDouble())
+ .setZDot(source.readDouble())
+ .setZAccel(source.readDouble())
+ .build();
+ }
+
+ @Override
+ public GlonassSatelliteOrbitModel[] newArray(int size) {
+ return new GlonassSatelliteOrbitModel[size];
+ }
+ };
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GlonassSatelliteOrbitModel[");
+ builder.append("x = ").append(mX);
+ builder.append(", xDot = ").append(mXDot);
+ builder.append(", xAccel = ").append(mXAccel);
+ builder.append(", y = ").append(mY);
+ builder.append(", yDot = ").append(mYDot);
+ builder.append(", yAccel = ").append(mYAccel);
+ builder.append(", z = ").append(mZ);
+ builder.append(", zDot = ").append(mZDot);
+ builder.append(", zAccel = ").append(mZAccel);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GlonassSatelliteOrbitModel}. */
+ public static final class Builder {
+ private double mX;
+ private double mXDot;
+ private double mXAccel;
+ private double mY;
+ private double mYDot;
+ private double mYAccel;
+ private double mZ;
+ private double mZDot;
+ private double mZAccel;
+
+ /** Sets the X position in kilometers. */
+ @NonNull
+ public Builder setX(@FloatRange(from = -2.7e4f, to = 2.7e4f) double x) {
+ mX = x;
+ return this;
+ }
+
+ /** Sets the X velocity in kilometers per second. */
+ @NonNull
+ public Builder setXDot(@FloatRange(from = -4.3f, to = 4.3f) double xDot) {
+ mXDot = xDot;
+ return this;
+ }
+
+ /** Sets the X acceleration in kilometers per second squared. */
+ @NonNull
+ public Builder setXAccel(@FloatRange(from = -6.2e-9f, to = 6.2e-9f) double xAccel) {
+ mXAccel = xAccel;
+ return this;
+ }
+
+ /** Sets the Y position in kilometers. */
+ @NonNull
+ public Builder setY(@FloatRange(from = -2.7e4f, to = 2.7e4f) double y) {
+ mY = y;
+ return this;
+ }
+
+ /** Sets the Y velocity in kilometers per second. */
+ @NonNull
+ public Builder setYDot(@FloatRange(from = -4.3f, to = 4.3f) double yDot) {
+ mYDot = yDot;
+ return this;
+ }
+
+ /** Sets the Y acceleration in kilometers per second squared. */
+ @NonNull
+ public Builder setYAccel(@FloatRange(from = -6.2e-9f, to = 6.2e-9f) double yAccel) {
+ mYAccel = yAccel;
+ return this;
+ }
+
+ /** Sets the Z position in kilometers. */
+ @NonNull
+ public Builder setZ(@FloatRange(from = -2.7e4f, to = 2.7e4f) double z) {
+ mZ = z;
+ return this;
+ }
+
+ /** Sets the Z velocity in kilometers per second. */
+ @NonNull
+ public Builder setZDot(@FloatRange(from = -4.3f, to = 4.3f) double zDot) {
+ mZDot = zDot;
+ return this;
+ }
+
+ /** Sets the Z acceleration in kilometers per second squared. */
+ @NonNull
+ public Builder setZAccel(@FloatRange(from = -6.2e-9f, to = 6.2e-9f) double zAccel) {
+ mZAccel = zAccel;
+ return this;
+ }
+
+ /** Builds a {@link GlonassSatelliteOrbitModel}. */
+ @NonNull
+ public GlonassSatelliteOrbitModel build() {
+ return new GlonassSatelliteOrbitModel(this);
+ }
+ }
+ }
+}
diff --git a/location/java/android/location/GnssAlmanac.java b/location/java/android/location/GnssAlmanac.java
new file mode 100644
index 0000000..6466e45a
--- /dev/null
+++ b/location/java/android/location/GnssAlmanac.java
@@ -0,0 +1,619 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains almanac parameters for GPS, QZSS, Galileo, Beidou.
+ *
+ * <p>For Beidou, this is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.15.
+ *
+ * <p>For GPS, this is defined in IS-GPS-200 section 20.3.3.5.1.2.
+ *
+ * <p>For QZSS, this is defined in IS-QZSS-PNT section 4.1.2.6.
+ *
+ * <p>For Galileo, this is defined in Galileo-OS-SIS-ICD-v2.1 section 5.1.10.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GnssAlmanac implements Parcelable {
+ /**
+ * Almanac issue date in milliseconds (UTC).
+ *
+ * <p>This is unused for GPS/QZSS/Baidou.
+ */
+ private final long mIssueDateMillis;
+
+ /**
+ * Almanac issue of data.
+ *
+ * <p>This is unused for GPS/QZSS/Baidou.
+ */
+ private final int mIod;
+
+ /**
+ * Almanac reference week number.
+ *
+ * <p>For GPS and QZSS, this is GPS week number (modulo 1024).
+ *
+ * <p>For Beidou, this is Baidou week number (modulo 8192).
+ *
+ * <p>For Galileo, this is modulo 4 representation of the Galileo week number.
+ */
+ private final int mWeekNumber;
+
+ /** Almanac reference time in seconds. */
+ private final int mToaSeconds;
+
+ /** The list of GnssSatelliteAlmanacs. */
+ @NonNull private final List<GnssSatelliteAlmanac> mGnssSatelliteAlmanacs;
+
+ private GnssAlmanac(Builder builder) {
+ Preconditions.checkArgument(builder.mIssueDateMillis >= 0);
+ Preconditions.checkArgument(builder.mIod >= 0);
+ Preconditions.checkArgument(builder.mWeekNumber >= 0);
+ Preconditions.checkArgumentInRange(builder.mToaSeconds, 0, 604800, "ToaSeconds");
+ Preconditions.checkNotNull(
+ builder.mGnssSatelliteAlmanacs, "GnssSatelliteAlmanacs cannot be null");
+ mIssueDateMillis = builder.mIssueDateMillis;
+ mIod = builder.mIod;
+ mWeekNumber = builder.mWeekNumber;
+ mToaSeconds = builder.mToaSeconds;
+ mGnssSatelliteAlmanacs =
+ Collections.unmodifiableList(new ArrayList<>(builder.mGnssSatelliteAlmanacs));
+ }
+
+ /** Returns the almanac issue date in milliseconds (UTC). */
+ @IntRange(from = 0)
+ public long getIssueDateMillis() {
+ return mIssueDateMillis;
+ }
+
+ /** Returns the almanac issue of data. */
+ @IntRange(from = 0)
+ public int getIod() {
+ return mIod;
+ }
+
+ /**
+ * Returns the almanac reference week number.
+ *
+ * <p>For GPS and QZSS, this is GPS week number (modulo 1024).
+ *
+ * <p>For Beidou, this is Baidou week number (modulo 8192).
+ *
+ * <p>For Galileo, this is modulo 4 representation of the Galileo week number.
+ */
+ @IntRange(from = 0)
+ public int getWeekNumber() {
+ return mWeekNumber;
+ }
+
+ /** Returns the almanac reference time in seconds. */
+ @IntRange(from = 0, to = 604800)
+ public int getToaSeconds() {
+ return mToaSeconds;
+ }
+
+ /** Returns the list of GnssSatelliteAlmanacs. */
+ @NonNull
+ public List<GnssSatelliteAlmanac> getGnssSatelliteAlmanacs() {
+ return mGnssSatelliteAlmanacs;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeLong(mIssueDateMillis);
+ dest.writeInt(mIod);
+ dest.writeInt(mWeekNumber);
+ dest.writeInt(mToaSeconds);
+ dest.writeTypedList(mGnssSatelliteAlmanacs);
+ }
+
+ public static final @NonNull Creator<GnssAlmanac> CREATOR =
+ new Creator<GnssAlmanac>() {
+ @Override
+ public GnssAlmanac createFromParcel(Parcel in) {
+ GnssAlmanac.Builder gnssAlmanac = new GnssAlmanac.Builder();
+ gnssAlmanac.setIssueDateMillis(in.readLong());
+ gnssAlmanac.setIod(in.readInt());
+ gnssAlmanac.setWeekNumber(in.readInt());
+ gnssAlmanac.setToaSeconds(in.readInt());
+ List<GnssSatelliteAlmanac> satelliteAlmanacs = new ArrayList<>();
+ in.readTypedList(satelliteAlmanacs, GnssSatelliteAlmanac.CREATOR);
+ gnssAlmanac.setGnssSatelliteAlmanacs(satelliteAlmanacs);
+ return gnssAlmanac.build();
+ }
+
+ @Override
+ public GnssAlmanac[] newArray(int size) {
+ return new GnssAlmanac[size];
+ }
+ };
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GnssAlmanac[");
+ builder.append("issueDateMillis=").append(mIssueDateMillis);
+ builder.append(", iod=").append(mIod);
+ builder.append(", weekNumber=").append(mWeekNumber);
+ builder.append(", toaSeconds=").append(mToaSeconds);
+ builder.append(", satelliteAlmanacs=").append(mGnssSatelliteAlmanacs);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GnssAlmanac}. */
+ public static final class Builder {
+ private long mIssueDateMillis;
+ private int mIod;
+ private int mWeekNumber;
+ private int mToaSeconds;
+ private List<GnssSatelliteAlmanac> mGnssSatelliteAlmanacs;
+
+ /** Sets the almanac issue date in milliseconds (UTC). */
+ @NonNull
+ public Builder setIssueDateMillis(@IntRange(from = 0) long issueDateMillis) {
+ mIssueDateMillis = issueDateMillis;
+ return this;
+ }
+
+ /** Sets the almanac issue of data. */
+ @NonNull
+ public Builder setIod(@IntRange(from = 0) int iod) {
+ mIod = iod;
+ return this;
+ }
+
+ /**
+ * Sets the almanac reference week number.
+ *
+ * <p>For GPS and QZSS, this is GPS week number (modulo 1024).
+ *
+ * <p>For Beidou, this is Baidou week number (modulo 8192).
+ *
+ * <p>For Galileo, this is modulo 4 representation of the Galileo week number.
+ */
+ @NonNull
+ public Builder setWeekNumber(@IntRange(from = 0) int weekNumber) {
+ mWeekNumber = weekNumber;
+ return this;
+ }
+
+ /** Sets the almanac reference time in seconds. */
+ @NonNull
+ public Builder setToaSeconds(@IntRange(from = 0, to = 604800) int toaSeconds) {
+ mToaSeconds = toaSeconds;
+ return this;
+ }
+
+ /** Sets the list of GnssSatelliteAlmanacs. */
+ @NonNull
+ public Builder setGnssSatelliteAlmanacs(
+ @NonNull List<GnssSatelliteAlmanac> gnssSatelliteAlmanacs) {
+ mGnssSatelliteAlmanacs = gnssSatelliteAlmanacs;
+ return this;
+ }
+
+ /** Builds a {@link GnssAlmanac} instance as specified by this builder. */
+ @NonNull
+ public GnssAlmanac build() {
+ return new GnssAlmanac(this);
+ }
+ }
+
+ /**
+ * A class contains almanac parameters for GPS, QZSS, Galileo, Beidou.
+ *
+ * <p>For Beidou, this is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.15.
+ *
+ * <p>For GPS, this is defined in IS-GPS-200 section 20.3.3.5.1.2.
+ *
+ * <p>For QZSS, this is defined in IS-QZSS-PNT section 4.1.2.6.
+ *
+ * <p>For Galileo, this is defined in Galileo-OS-SIS-ICD-v2.1 section 5.1.10.
+ */
+ public static final class GnssSatelliteAlmanac implements Parcelable {
+ /** The PRN number of the GNSS satellite. */
+ private final int mSvid;
+
+ /**
+ * Satellite health information.
+ *
+ * <p>For GPS, this is satellite subframe 4 and 5, page 25 6-bit health code as defined in
+ * IS-GPS-200 Table 20-VIII expressed in integer form.
+ *
+ * <p>For QZSS, this is the 5-bit health code as defined in IS-QZSS-PNT, Table 4.1.2-5-2
+ * expressed in integer form.
+ *
+ * <p>For Beidou, this is 1-bit health information. (0=healthy, 1=unhealthy).
+ *
+ * <p>For Galileo, this is 6-bit health, bit 0 and 1 is for E5a, bit 2 and 3 is for E5b, bit
+ * 4 and 5 is for E1b.
+ */
+ private final int mSvHealth;
+
+ /** Eccentricity. */
+ private final double mEccentricity;
+
+ /**
+ * Inclination in semi-circles.
+ *
+ * <p>For GPS and Galileo, this is the difference between the inclination angle at reference
+ * time and the nominal inclination in semi-circles.
+ *
+ * <p>For Beidou and QZSS, this is the inclination angle at reference time in semi-circles.
+ */
+ private final double mInclination;
+
+ /** Argument of perigee in semi-circles. */
+ private final double mOmega;
+
+ /** Longitude of ascending node of orbital plane at weekly epoch in semi-circles. */
+ private final double mOmega0;
+
+ /** Rate of right ascension in semi-circles per second. */
+ private final double mOmegaDot;
+
+ /**
+ * Square root of semi-major axis in square root of meters.
+ *
+ * <p>For Galileo, this is the difference with respect to the square root of the nominal
+ * semi-major axis in square root of meters.
+ */
+ private final double mRootA;
+
+ /** Mean anomaly at reference time in semi-circles. */
+ private final double mM0;
+
+ /** Satellite clock time bias correction coefficient in seconds. */
+ private final double mAf0;
+
+ /** Satellite clock time drift correction coefficient in seconds per second. */
+ private final double mAf1;
+
+ private GnssSatelliteAlmanac(Builder builder) {
+ Preconditions.checkArgument(builder.mSvid > 0);
+ Preconditions.checkArgument(builder.mSvHealth >= 0);
+ Preconditions.checkArgument(builder.mEccentricity >= 0.0f);
+ Preconditions.checkArgumentInRange(builder.mInclination, -1.0f, 1.0f, "Inclination");
+ Preconditions.checkArgumentInRange(builder.mOmega, -1.0f, 1.0f, "Omega");
+ Preconditions.checkArgumentInRange(builder.mOmega0, -1.0f, 1.0f, "Omega0");
+ Preconditions.checkArgumentInRange(builder.mOmegaDot, -1.0f, 1.0f, "OmegaDot");
+ Preconditions.checkArgumentInRange(builder.mRootA, 0.0f, 8192.0f, "RootA");
+ Preconditions.checkArgumentInRange(builder.mM0, -1.0f, 1.0f, "M0");
+ Preconditions.checkArgumentInRange(builder.mAf0, -0.0625f, 0.0625f, "Af0");
+ Preconditions.checkArgumentInRange(builder.mAf1, -1.5e-8f, 1.5e-8f, "Af1");
+ mSvid = builder.mSvid;
+ mSvHealth = builder.mSvHealth;
+ mEccentricity = builder.mEccentricity;
+ mInclination = builder.mInclination;
+ mOmega = builder.mOmega;
+ mOmega0 = builder.mOmega0;
+ mOmegaDot = builder.mOmegaDot;
+ mRootA = builder.mRootA;
+ mM0 = builder.mM0;
+ mAf0 = builder.mAf0;
+ mAf1 = builder.mAf1;
+ }
+
+ /** Returns the PRN number of the GNSS satellite. */
+ @IntRange(from = 1)
+ public int getSvid() {
+ return mSvid;
+ }
+
+ /**
+ * Returns the satellite health information.
+ *
+ * <p>For GPS, this is satellite subframe 4 and 5, page 25 6-bit health code as defined in
+ * IS-GPS-200 Table 20-VIII expressed in integer form.
+ *
+ * <p>For QZSS, this is the 5-bit health code as defined in IS-QZSS-PNT, Table 4.1.2-5-2
+ * expressed in integer form.
+ *
+ * <p>For Beidou, this is 1-bit health information. (0=healthy, 1=unhealthy).
+ *
+ * <p>For Galileo, this is 6-bit health, bit 0 and 1 is for E5a, bit 2 and 3 is for E5b,
+ * bit 4 and 5 is for E1b.
+ */
+ @IntRange(from = 0)
+ public int getSvHealth() {
+ return mSvHealth;
+ }
+
+ /** Returns the eccentricity. */
+ @FloatRange(from = 0.0f)
+ public double getEccentricity() {
+ return mEccentricity;
+ }
+
+ /**
+ * Returns the inclination in semi-circles.
+ *
+ * <p>For GPS and Galileo, this is the difference between the inclination angle at reference
+ * time and the nominal inclination in semi-circles.
+ *
+ * <p>For Beidou and QZSS, this is the inclination angle at reference time in semi-circles.
+ */
+ @FloatRange(from = -1.0f, to = 1.0f)
+ public double getInclination() {
+ return mInclination;
+ }
+
+ /** Returns the argument of perigee in semi-circles. */
+ @FloatRange(from = -1.0f, to = 1.0f)
+ public double getOmega() {
+ return mOmega;
+ }
+
+ /**
+ * Returns the longitude of ascending node of orbital plane at weekly epoch in semi-circles.
+ */
+ @FloatRange(from = -1.0f, to = 1.0f)
+ public double getOmega0() {
+ return mOmega0;
+ }
+
+ /** Returns the rate of right ascension in semi-circles per second. */
+ @FloatRange(from = -1.0f, to = 1.0f)
+ public double getOmegaDot() {
+ return mOmegaDot;
+ }
+
+ /**
+ * Returns the square root of semi-major axis in square root of meters.
+ *
+ * <p>For Galileo, this is the difference with respect to the square root of the nominal
+ * semi-major axis in square root of meters.
+ */
+ @FloatRange(from = 0.0f, to = 8192.0f)
+ public double getRootA() {
+ return mRootA;
+ }
+
+ /** Returns the mean anomaly at reference time in semi-circles. */
+ @FloatRange(from = -1.0f, to = 1.0f)
+ public double getM0() {
+ return mM0;
+ }
+
+ /** Returns the satellite clock time bias correction coefficient in seconds. */
+ @FloatRange(from = -0.0625f, to = 0.0625f)
+ public double getAf0() {
+ return mAf0;
+ }
+
+ /** Returns the satellite clock time drift correction coefficient in seconds per second. */
+ @FloatRange(from = -1.5e-8f, to = 1.5e-8f)
+ public double getAf1() {
+ return mAf1;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mSvid);
+ dest.writeInt(mSvHealth);
+ dest.writeDouble(mEccentricity);
+ dest.writeDouble(mInclination);
+ dest.writeDouble(mOmega);
+ dest.writeDouble(mOmega0);
+ dest.writeDouble(mOmegaDot);
+ dest.writeDouble(mRootA);
+ dest.writeDouble(mM0);
+ dest.writeDouble(mAf0);
+ dest.writeDouble(mAf1);
+ }
+
+ public static final @NonNull Creator<GnssSatelliteAlmanac> CREATOR =
+ new Creator<GnssSatelliteAlmanac>() {
+ @Override
+ public GnssSatelliteAlmanac createFromParcel(Parcel in) {
+ return new GnssSatelliteAlmanac(
+ new Builder()
+ .setSvid(in.readInt())
+ .setSvHealth(in.readInt())
+ .setEccentricity(in.readDouble())
+ .setInclination(in.readDouble())
+ .setOmega(in.readDouble())
+ .setOmega0(in.readDouble())
+ .setOmegaDot(in.readDouble())
+ .setRootA(in.readDouble())
+ .setM0(in.readDouble())
+ .setAf0(in.readDouble())
+ .setAf1(in.readDouble()));
+ }
+
+ @Override
+ public GnssSatelliteAlmanac[] newArray(int size) {
+ return new GnssSatelliteAlmanac[size];
+ }
+ };
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GnssSatelliteAlmanac[");
+ builder.append("svid = ").append(mSvid);
+ builder.append(", svHealth = ").append(mSvHealth);
+ builder.append(", eccentricity = ").append(mEccentricity);
+ builder.append(", inclination = ").append(mInclination);
+ builder.append(", omega = ").append(mOmega);
+ builder.append(", omega0 = ").append(mOmega0);
+ builder.append(", omegaDot = ").append(mOmegaDot);
+ builder.append(", rootA = ").append(mRootA);
+ builder.append(", m0 = ").append(mM0);
+ builder.append(", af0 = ").append(mAf0);
+ builder.append(", af1 = ").append(mAf1);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GnssSatelliteAlmanac}. */
+ public static final class Builder {
+ private int mSvid;
+ private int mSvHealth;
+ private double mEccentricity;
+ private double mInclination;
+ private double mOmega;
+ private double mOmega0;
+ private double mOmegaDot;
+ private double mRootA;
+ private double mM0;
+ private double mAf0;
+ private double mAf1;
+
+ /** Sets the PRN number of the GNSS satellite. */
+ @NonNull
+ public Builder setSvid(@IntRange(from = 1) int svid) {
+ mSvid = svid;
+ return this;
+ }
+
+ /**
+ * Sets the satellite health information.
+ *
+ * <p>For GPS, this is satellite subframe 4 and 5, page 25 6-bit health code as defined
+ * in IS-GPS-200 Table 20-VIII expressed in integer form.
+ *
+ * <p>For QZSS, this is the 5-bit health code as defined in IS-QZSS-PNT, Table 4.1.2-5-2
+ * expressed in integer form.
+ *
+ * <p>For Beidou, this is 1-bit health information. (0=healthy, 1=unhealthy).
+ *
+ * <p>For Galileo, this is 6-bit health, bit 0 and 1 is for E5a,
+ * bit 2 and 3 is for E5b, bit 4 and 5 is for E1b.
+ */
+ @NonNull
+ public Builder setSvHealth(@IntRange(from = 0) int svHealth) {
+ mSvHealth = svHealth;
+ return this;
+ }
+
+ /** Sets the eccentricity. */
+ @NonNull
+ public Builder setEccentricity(@FloatRange(from = 0.0f) double eccentricity) {
+ mEccentricity = eccentricity;
+ return this;
+ }
+
+ /**
+ * Sets the inclination in semi-circles.
+ *
+ * <p>For GPS and Galileo, this is the difference between the inclination angle at
+ * reference time and the nominal inclination in semi-circles.
+ *
+ * <p>For Beidou and QZSS, this is the inclination angle at reference time in
+ * semi-circles.
+ */
+ @NonNull
+ public Builder setInclination(@FloatRange(from = -1.0f, to = 1.0f) double inclination) {
+ mInclination = inclination;
+ return this;
+ }
+
+ /** Sets the argument of perigee in semi-circles. */
+ @NonNull
+ public Builder setOmega(@FloatRange(from = -1.0f, to = 1.0f) double omega) {
+ mOmega = omega;
+ return this;
+ }
+
+ /**
+ * Sets the longitude of ascending node of orbital plane at weekly epoch in
+ * semi-circles.
+ */
+ @NonNull
+ public Builder setOmega0(@FloatRange(from = -1.0f, to = 1.0f) double omega0) {
+ mOmega0 = omega0;
+ return this;
+ }
+
+ /** Sets the rate of right ascension in semi-circles per second. */
+ @NonNull
+ public Builder setOmegaDot(@FloatRange(from = -1.0f, to = 1.0f) double omegaDot) {
+ mOmegaDot = omegaDot;
+ return this;
+ }
+
+ /**
+ * Sets the square root of semi-major axis in square root of meters.
+ *
+ * <p>For Galileo, this is the difference with respect to the square root of the nominal
+ * semi-major axis in square root of meters.
+ */
+ @NonNull
+ public Builder setRootA(@FloatRange(from = 0.0f, to = 8192.0f) double rootA) {
+ mRootA = rootA;
+ return this;
+ }
+
+ /** Sets the mean anomaly at reference time in semi-circles. */
+ @NonNull
+ public Builder setM0(@FloatRange(from = -1.0f, to = 1.0f) double m0) {
+ mM0 = m0;
+ return this;
+ }
+
+ /** Sets the satellite clock time bias correction coefficient in seconds. */
+ @NonNull
+ public Builder setAf0(@FloatRange(from = -0.0625f, to = 0.0625f) double af0) {
+ mAf0 = af0;
+ return this;
+ }
+
+ /** Sets the satellite clock time drift correction coefficient in seconds per second. */
+ @NonNull
+ public Builder setAf1(@FloatRange(from = -1.5e-8f, to = 1.5e-8f) double af1) {
+ mAf1 = af1;
+ return this;
+ }
+
+ /** Builds a {@link GnssSatelliteAlmanac} instance as specified by this builder. */
+ @NonNull
+ public GnssSatelliteAlmanac build() {
+ return new GnssSatelliteAlmanac(this);
+ }
+ }
+ }
+}
diff --git a/location/java/android/location/GnssAssistance.aidl b/location/java/android/location/GnssAssistance.aidl
new file mode 100644
index 0000000..2745683
--- /dev/null
+++ b/location/java/android/location/GnssAssistance.aidl
@@ -0,0 +1,18 @@
+/*
+ * 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.location;
+
+parcelable GnssAssistance;
\ No newline at end of file
diff --git a/location/java/android/location/GnssAssistance.java b/location/java/android/location/GnssAssistance.java
new file mode 100644
index 0000000..e941122
--- /dev/null
+++ b/location/java/android/location/GnssAssistance.java
@@ -0,0 +1,310 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains GNSS assistance.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GnssAssistance implements Parcelable {
+
+ /** GPS assistance. */
+ @Nullable private final GpsAssistance mGpsAssistance;
+
+ /** Glonass assistance. */
+ @Nullable private final GlonassAssistance mGlonassAssistance;
+
+ /** Galileo assistance. */
+ @Nullable private final GalileoAssistance mGalileoAssistance;
+
+ /** Beidou assistance. */
+ @Nullable private final BeidouAssistance mBeidouAssistance;
+
+ /** QZSS assistance. */
+ @Nullable private final QzssAssistance mQzssAssistance;
+
+ private GnssAssistance(Builder builder) {
+ mGpsAssistance = builder.mGpsAssistance;
+ mGlonassAssistance = builder.mGlonassAssistance;
+ mGalileoAssistance = builder.mGalileoAssistance;
+ mBeidouAssistance = builder.mBeidouAssistance;
+ mQzssAssistance = builder.mQzssAssistance;
+ }
+
+ /** Returns the GPS assistance. */
+ @Nullable
+ public GpsAssistance getGpsAssistance() {
+ return mGpsAssistance;
+ }
+
+ /** Returns the Glonass assistance. */
+ @Nullable
+ public GlonassAssistance getGlonassAssistance() {
+ return mGlonassAssistance;
+ }
+
+ /** Returns the Galileo assistance. */
+ @Nullable
+ public GalileoAssistance getGalileoAssistance() {
+ return mGalileoAssistance;
+ }
+
+ /** Returns the Beidou assistance. */
+ @Nullable
+ public BeidouAssistance getBeidouAssistance() {
+ return mBeidouAssistance;
+ }
+
+ /** Returns the Qzss assistance. */
+ @Nullable
+ public QzssAssistance getQzssAssistance() {
+ return mQzssAssistance;
+ }
+
+ public static final @NonNull Creator<GnssAssistance> CREATOR =
+ new Creator<GnssAssistance>() {
+ @Override
+ @NonNull
+ public GnssAssistance createFromParcel(Parcel in) {
+ return new GnssAssistance.Builder()
+ .setGpsAssistance(in.readTypedObject(GpsAssistance.CREATOR))
+ .setGlonassAssistance(in.readTypedObject(GlonassAssistance.CREATOR))
+ .setGalileoAssistance(in.readTypedObject(GalileoAssistance.CREATOR))
+ .setBeidouAssistance(in.readTypedObject(BeidouAssistance.CREATOR))
+ .setQzssAssistance(in.readTypedObject(QzssAssistance.CREATOR))
+ .build();
+ }
+
+ @Override
+ public GnssAssistance[] newArray(int size) {
+ return new GnssAssistance[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeTypedObject(mGpsAssistance, flags);
+ parcel.writeTypedObject(mGlonassAssistance, flags);
+ parcel.writeTypedObject(mGalileoAssistance, flags);
+ parcel.writeTypedObject(mBeidouAssistance, flags);
+ parcel.writeTypedObject(mQzssAssistance, flags);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GnssAssistance[");
+ builder.append("gpsAssistance = ").append(mGpsAssistance);
+ builder.append(", glonassAssistance = ").append(mGlonassAssistance);
+ builder.append(", galileoAssistance = ").append(mGalileoAssistance);
+ builder.append(", beidouAssistance = ").append(mBeidouAssistance);
+ builder.append(", qzssAssistance = ").append(mQzssAssistance);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GnssAssistance}. */
+ public static final class Builder {
+ private GpsAssistance mGpsAssistance;
+ private GlonassAssistance mGlonassAssistance;
+ private GalileoAssistance mGalileoAssistance;
+ private BeidouAssistance mBeidouAssistance;
+ private QzssAssistance mQzssAssistance;
+
+ /** Sets the GPS assistance. */
+ @NonNull
+ public Builder setGpsAssistance(@Nullable GpsAssistance gpsAssistance) {
+ mGpsAssistance = gpsAssistance;
+ return this;
+ }
+
+ /** Sets the Glonass assistance. */
+ @NonNull
+ public Builder setGlonassAssistance(@Nullable GlonassAssistance glonassAssistance) {
+ mGlonassAssistance = glonassAssistance;
+ return this;
+ }
+
+ /** Sets the Galileo assistance. */
+ @NonNull
+ public Builder setGalileoAssistance(@Nullable GalileoAssistance galileoAssistance) {
+ mGalileoAssistance = galileoAssistance;
+ return this;
+ }
+
+ /** Sets the Beidou assistance. */
+ @NonNull
+ public Builder setBeidouAssistance(@Nullable BeidouAssistance beidouAssistance) {
+ mBeidouAssistance = beidouAssistance;
+ return this;
+ }
+
+ /** Sets the QZSS assistance. */
+ @NonNull
+ public Builder setQzssAssistance(@Nullable QzssAssistance qzssAssistance) {
+ mQzssAssistance = qzssAssistance;
+ return this;
+ }
+
+ /** Builds a {@link GnssAssistance} instance as specified by this builder. */
+ @NonNull
+ public GnssAssistance build() {
+ return new GnssAssistance(this);
+ }
+ }
+
+ /** A class contains GNSS corrections for satellites. */
+ public static final class GnssSatelliteCorrections implements Parcelable {
+ /**
+ * Pseudo-random or satellite ID number for the satellite, a.k.a. Space Vehicle (SV), or OSN
+ * number for Glonass.
+ *
+ * <p>The distinction is made by looking at the constellation field. Values must be in the
+ * range of:
+ *
+ * <p>- GPS: 1-32
+ *
+ * <p>- GLONASS: 1-25
+ *
+ * <p>- QZSS: 183-206
+ *
+ * <p>- Galileo: 1-36
+ *
+ * <p>- Beidou: 1-63
+ */
+ @IntRange(from = 1, to = 206)
+ int mSvid;
+
+ /** List of Ionospheric corrections */
+ @NonNull List<IonosphericCorrection> mIonosphericCorrections;
+
+ /**
+ * Creates a new {@link GnssSatelliteCorrections} instance.
+ *
+ * @param svid The Pseudo-random or satellite ID number for the satellite, a.k.a. Space
+ * Vehicle (SV), or OSN number for Glonass.
+ * <p>The distinction is made by looking at the constellation field. Values must be in
+ * the range of:
+ * <p>- GPS: 1-32
+ * <p>- GLONASS: 1-25
+ * <p>- QZSS: 183-206
+ * <p>- Galileo: 1-36
+ * <p>- Beidou: 1-63
+ * @param ionosphericCorrections The list of Ionospheric corrections.
+ */
+ public GnssSatelliteCorrections(
+ @IntRange(from = 1, to = 206) int svid,
+ @NonNull final List<IonosphericCorrection> ionosphericCorrections) {
+ // Allow SV ID beyond the range to support potential future extensibility.
+ Preconditions.checkArgument(svid >= 1);
+ Preconditions.checkNotNull(
+ ionosphericCorrections, "IonosphericCorrections cannot be null");
+ mSvid = svid;
+ mIonosphericCorrections =
+ Collections.unmodifiableList(new ArrayList<>(ionosphericCorrections));
+ }
+
+ /**
+ * Returns the Pseudo-random or satellite ID number for the satellite, a.k.a. Space Vehicle
+ * (SV), or OSN number for Glonass.
+ *
+ * <p>The distinction is made by looking at the constellation field. Values must be in the
+ * range of:
+ *
+ * <p>- GPS: 1-32
+ *
+ * <p>- GLONASS: 1-25
+ *
+ * <p>- QZSS: 183-206
+ *
+ * <p>- Galileo: 1-36
+ *
+ * <p>- Beidou: 1-63
+ */
+ @IntRange(from = 1, to = 206)
+ public int getSvid() {
+ return mSvid;
+ }
+
+ /** Returns the list of Ionospheric corrections. */
+ @NonNull
+ public List<IonosphericCorrection> getIonosphericCorrections() {
+ return mIonosphericCorrections;
+ }
+
+ public static final @NonNull Creator<GnssSatelliteCorrections> CREATOR =
+ new Creator<GnssSatelliteCorrections>() {
+ @Override
+ @NonNull
+ public GnssSatelliteCorrections createFromParcel(Parcel in) {
+ int svid = in.readInt();
+ List<IonosphericCorrection> ionosphericCorrections = new ArrayList<>();
+ in.readTypedList(ionosphericCorrections, IonosphericCorrection.CREATOR);
+ return new GnssSatelliteCorrections(svid, ionosphericCorrections);
+ }
+
+ @Override
+ public GnssSatelliteCorrections[] newArray(int size) {
+ return new GnssSatelliteCorrections[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mSvid);
+ parcel.writeTypedList(mIonosphericCorrections, flags);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GnssSatelliteCorrections[");
+ builder.append("svid = ").append(mSvid);
+ builder.append(", ionosphericCorrections = ").append(mIonosphericCorrections);
+ builder.append("]");
+ return builder.toString();
+ }
+ }
+}
diff --git a/location/java/android/location/GnssCorrectionComponent.java b/location/java/android/location/GnssCorrectionComponent.java
new file mode 100644
index 0000000..f55dde1
--- /dev/null
+++ b/location/java/android/location/GnssCorrectionComponent.java
@@ -0,0 +1,300 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class that contains Gnss correction associated with a component (e.g. the Ionospheric error).
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GnssCorrectionComponent implements Parcelable {
+ /**
+ * Uniquely identifies the source of correction (e.g. "Klobuchar" for ionospheric corrections).
+ * Clients should not depend on the value of the source key but, rather, can compare
+ * before/after to detect changes.
+ */
+ @NonNull private final String mSourceKey;
+
+ /** The correction is only applicable during this time interval. */
+ @NonNull private final GnssInterval mValidityInterval;
+
+ /** Pseudorange correction. */
+ @NonNull private final PseudorangeCorrection mPseudorangeCorrection;
+
+ /**
+ * Creates a GnssCorrectionComponent.
+ *
+ * @param sourceKey Uniquely identifies the source of correction (e.g. "Klobuchar" for
+ * ionospheric corrections). Clients should not depend on the value of the source key but,
+ * rather, can compare before/after to detect changes.
+ * @param validityInterval The correction is only applicable during this time interval.
+ * @param pseudorangeCorrection Pseudorange correction.
+ */
+ public GnssCorrectionComponent(
+ @NonNull String sourceKey,
+ @NonNull GnssInterval validityInterval,
+ @NonNull PseudorangeCorrection pseudorangeCorrection) {
+ Preconditions.checkNotNull(sourceKey, "SourceKey cannot be null");
+ Preconditions.checkNotNull(validityInterval, "ValidityInterval cannot be null");
+ Preconditions.checkNotNull(pseudorangeCorrection, "PseudorangeCorrection cannot be null");
+ mSourceKey = sourceKey;
+ mValidityInterval = validityInterval;
+ mPseudorangeCorrection = pseudorangeCorrection;
+ }
+
+ /** Returns the source key of the correction. */
+ @NonNull
+ public String getSourceKey() {
+ return mSourceKey;
+ }
+
+ /** Returns the validity interval of the correction. */
+ @NonNull
+ public GnssInterval getValidityInterval() {
+ return mValidityInterval;
+ }
+
+ /** Returns the pseudorange correction. */
+ @NonNull
+ public PseudorangeCorrection getPseudorangeCorrection() {
+ return mPseudorangeCorrection;
+ }
+
+ public static final @NonNull Creator<GnssCorrectionComponent> CREATOR =
+ new Creator<GnssCorrectionComponent>() {
+ @Override
+ @NonNull
+ public GnssCorrectionComponent createFromParcel(Parcel in) {
+ String sourceKey = in.readString8();
+ GnssInterval validityInterval = in.readTypedObject(GnssInterval.CREATOR);
+ PseudorangeCorrection pseudorangeCorrection =
+ in.readTypedObject(PseudorangeCorrection.CREATOR);
+ return new GnssCorrectionComponent(
+ sourceKey, validityInterval, pseudorangeCorrection);
+ }
+
+ @Override
+ public GnssCorrectionComponent[] newArray(int size) {
+ return new GnssCorrectionComponent[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString8(mSourceKey);
+ dest.writeTypedObject(mValidityInterval, flags);
+ dest.writeTypedObject(mPseudorangeCorrection, flags);
+ }
+
+ /**
+ * Time interval referenced against the GPS epoch. The start must be less than or equal to the
+ * end. When the start equals the end, the interval is empty.
+ */
+ public static final class GnssInterval implements Parcelable {
+ /**
+ * Inclusive start of the interval in milliseconds since the GPS epoch. A timestamp matching
+ * this interval will have to be the same or after the start. Required as a reference time
+ * for the initial correction value and its rate of change over time.
+ */
+ private final long mStartMillisSinceGpsEpoch;
+
+ /**
+ * Exclusive end of the interval in milliseconds since the GPS epoch. If specified, a
+ * timestamp matching this interval will have to be before the end.
+ */
+ private final long mEndMillisSinceGpsEpoch;
+
+ /**
+ * Creates a GnssInterval.
+ *
+ * @param startMillisSinceGpsEpoch Inclusive start of the interval in milliseconds since the
+ * GPS epoch. A timestamp matching this interval will have to be the same or after the
+ * start. Required as a reference time for the initial correction value and its rate of
+ * change over time.
+ * @param endMillisSinceGpsEpoch Exclusive end of the interval in milliseconds since the GPS
+ * epoch. If specified, a timestamp matching this interval will have to be before the
+ * end.
+ */
+ public GnssInterval(
+ @IntRange(from = 0) long startMillisSinceGpsEpoch,
+ @IntRange(from = 0) long endMillisSinceGpsEpoch) {
+ Preconditions.checkArgument(startMillisSinceGpsEpoch >= 0);
+ Preconditions.checkArgument(endMillisSinceGpsEpoch >= 0);
+ mStartMillisSinceGpsEpoch = startMillisSinceGpsEpoch;
+ mEndMillisSinceGpsEpoch = endMillisSinceGpsEpoch;
+ }
+
+ /** Returns the inclusive start of the interval in milliseconds since the GPS epoch. */
+ @IntRange(from = 0)
+ public long getStartMillisSinceGpsEpoch() {
+ return mStartMillisSinceGpsEpoch;
+ }
+
+ /** Returns the exclusive end of the interval in milliseconds since the GPS epoch. */
+ @IntRange(from = 0)
+ public long getEndMillisSinceGpsEpoch() {
+ return mEndMillisSinceGpsEpoch;
+ }
+
+ public static final @NonNull Creator<GnssInterval> CREATOR =
+ new Creator<GnssInterval>() {
+ @Override
+ @NonNull
+ public GnssInterval createFromParcel(Parcel in) {
+ return new GnssInterval(in.readLong(), in.readLong());
+ }
+
+ @Override
+ public GnssInterval[] newArray(int size) {
+ return new GnssInterval[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeLong(mStartMillisSinceGpsEpoch);
+ parcel.writeLong(mEndMillisSinceGpsEpoch);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GnssInterval[");
+ builder.append("startMillisSinceGpsEpoch = ").append(mStartMillisSinceGpsEpoch);
+ builder.append(", endMillisSinceGpsEpoch = ").append(mEndMillisSinceGpsEpoch);
+ builder.append("]");
+ return builder.toString();
+ }
+ }
+
+ /** Pseudorange correction. */
+ public static final class PseudorangeCorrection implements Parcelable {
+
+ /** Correction to be added to the measured pseudorange, in meters. */
+ private final double mCorrectionMeters;
+
+ /** Uncertainty of the correction, in meters. */
+ private final double mCorrectionUncertaintyMeters;
+
+ /**
+ * Linear approximation of the change in correction over time. Intended usage is to adjust
+ * the correction using the formula: correctionMeters + correctionRateMetersPerSecond *
+ * delta_seconds Where `delta_seconds` is the number of elapsed seconds since the beginning
+ * of the correction validity interval.
+ */
+ private final double mCorrectionRateMetersPerSecond;
+
+ /**
+ * Creates a PseudorangeCorrection.
+ *
+ * @param correctionMeters Correction to be added to the measured pseudorange, in meters.
+ * @param correctionUncertaintyMeters Uncertainty of the correction, in meters.
+ * @param correctionRateMetersPerSecond Linear approximation of the change in correction
+ * over time. Intended usage is to adjust the correction using the formula:
+ * correctionMeters + correctionRateMetersPerSecond * delta_seconds Where
+ * `delta_seconds` is the number of elapsed seconds since the beginning of the
+ * correction validity interval.
+ */
+ public PseudorangeCorrection(
+ double correctionMeters,
+ double correctionUncertaintyMeters,
+ double correctionRateMetersPerSecond) {
+ Preconditions.checkArgument(correctionUncertaintyMeters >= 0);
+ mCorrectionMeters = correctionMeters;
+ mCorrectionUncertaintyMeters = correctionUncertaintyMeters;
+ mCorrectionRateMetersPerSecond = correctionRateMetersPerSecond;
+ }
+
+ /** Returns the correction to be added to the measured pseudorange, in meters. */
+ public double getCorrectionMeters() {
+ return mCorrectionMeters;
+ }
+
+ /** Returns the uncertainty of the correction, in meters. */
+ @FloatRange(from = 0.0f)
+ public double getCorrectionUncertaintyMeters() {
+ return mCorrectionUncertaintyMeters;
+ }
+
+ /** Returns the linear approximation of the change in correction over time. */
+ public double getCorrectionRateMetersPerSecond() {
+ return mCorrectionRateMetersPerSecond;
+ }
+
+ public static final @NonNull Creator<PseudorangeCorrection> CREATOR =
+ new Creator<PseudorangeCorrection>() {
+ @Override
+ @NonNull
+ public PseudorangeCorrection createFromParcel(Parcel in) {
+ return new PseudorangeCorrection(
+ in.readDouble(), in.readDouble(), in.readDouble());
+ }
+
+ @Override
+ public PseudorangeCorrection[] newArray(int size) {
+ return new PseudorangeCorrection[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeDouble(mCorrectionMeters);
+ parcel.writeDouble(mCorrectionUncertaintyMeters);
+ parcel.writeDouble(mCorrectionRateMetersPerSecond);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("PseudorangeCorrection[");
+ builder.append("correctionMeters = ").append(mCorrectionMeters);
+ builder.append(", correctionUncertaintyMeters = ").append(mCorrectionUncertaintyMeters);
+ builder.append(", correctionRateMetersPerSecond = ")
+ .append(mCorrectionRateMetersPerSecond);
+ builder.append("]");
+ return builder.toString();
+ }
+ }
+}
diff --git a/location/java/android/location/GpsAssistance.java b/location/java/android/location/GpsAssistance.java
new file mode 100644
index 0000000..5202fc4
--- /dev/null
+++ b/location/java/android/location/GpsAssistance.java
@@ -0,0 +1,289 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.location.GnssAssistance.GnssSatelliteCorrections;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains GPS assistance.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GpsAssistance implements Parcelable {
+
+ /** The GPS almanac. */
+ @Nullable private final GnssAlmanac mAlmanac;
+
+ /** The Klobuchar ionospheric model. */
+ @Nullable private final KlobucharIonosphericModel mIonosphericModel;
+
+ /** The UTC model. */
+ @Nullable private final UtcModel mUtcModel;
+
+ /** The leap seconds model. */
+ @Nullable private final LeapSecondsModel mLeapSecondsModel;
+
+ /** The list of time models. */
+ @NonNull private final List<TimeModel> mTimeModels;
+
+ /** The list of GPS ephemeris. */
+ @NonNull private final List<GpsSatelliteEphemeris> mSatelliteEphemeris;
+
+ /** The list of real time integrity models. */
+ @NonNull private final List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+
+ /** The list of GPS satellite corrections. */
+ @NonNull private final List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+ private GpsAssistance(Builder builder) {
+ mAlmanac = builder.mAlmanac;
+ mIonosphericModel = builder.mIonosphericModel;
+ mUtcModel = builder.mUtcModel;
+ mLeapSecondsModel = builder.mLeapSecondsModel;
+ if (builder.mTimeModels != null) {
+ mTimeModels = Collections.unmodifiableList(new ArrayList<>(builder.mTimeModels));
+ } else {
+ mTimeModels = new ArrayList<>();
+ }
+ if (builder.mSatelliteEphemeris != null) {
+ mSatelliteEphemeris =
+ Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteEphemeris));
+ } else {
+ mSatelliteEphemeris = new ArrayList<>();
+ }
+ if (builder.mRealTimeIntegrityModels != null) {
+ mRealTimeIntegrityModels =
+ Collections.unmodifiableList(new ArrayList<>(builder.mRealTimeIntegrityModels));
+ } else {
+ mRealTimeIntegrityModels = new ArrayList<>();
+ }
+ if (builder.mSatelliteCorrections != null) {
+ mSatelliteCorrections =
+ Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteCorrections));
+ } else {
+ mSatelliteCorrections = new ArrayList<>();
+ }
+ }
+
+ /** Returns the GPS almanac. */
+ @Nullable
+ public GnssAlmanac getAlmanac() {
+ return mAlmanac;
+ }
+
+ /** Returns the Klobuchar ionospheric model. */
+ @Nullable
+ public KlobucharIonosphericModel getIonosphericModel() {
+ return mIonosphericModel;
+ }
+
+ /** Returns the UTC model. */
+ @Nullable
+ public UtcModel getUtcModel() {
+ return mUtcModel;
+ }
+
+ /** Returns the leap seconds model. */
+ @Nullable
+ public LeapSecondsModel getLeapSecondsModel() {
+ return mLeapSecondsModel;
+ }
+
+ /** Returns the list of time models. */
+ @NonNull
+ public List<TimeModel> getTimeModels() {
+ return mTimeModels;
+ }
+
+ /** Returns the list of GPS ephemeris. */
+ @NonNull
+ public List<GpsSatelliteEphemeris> getSatelliteEphemeris() {
+ return mSatelliteEphemeris;
+ }
+
+ /** Returns the list of real time integrity models. */
+ @NonNull
+ public List<RealTimeIntegrityModel> getRealTimeIntegrityModels() {
+ return mRealTimeIntegrityModels;
+ }
+
+ /** Returns the list of GPS satellite corrections. */
+ @NonNull
+ public List<GnssSatelliteCorrections> getSatelliteCorrections() {
+ return mSatelliteCorrections;
+ }
+
+ public static final @NonNull Creator<GpsAssistance> CREATOR =
+ new Creator<GpsAssistance>() {
+ @Override
+ @NonNull
+ public GpsAssistance createFromParcel(Parcel in) {
+ return new GpsAssistance.Builder()
+ .setAlmanac(in.readTypedObject(GnssAlmanac.CREATOR))
+ .setIonosphericModel(
+ in.readTypedObject(KlobucharIonosphericModel.CREATOR))
+ .setUtcModel(in.readTypedObject(UtcModel.CREATOR))
+ .setLeapSecondsModel(in.readTypedObject(LeapSecondsModel.CREATOR))
+ .setTimeModels(in.createTypedArrayList(TimeModel.CREATOR))
+ .setSatelliteEphemeris(
+ in.createTypedArrayList(GpsSatelliteEphemeris.CREATOR))
+ .setRealTimeIntegrityModels(
+ in.createTypedArrayList(RealTimeIntegrityModel.CREATOR))
+ .setSatelliteCorrections(
+ in.createTypedArrayList(GnssSatelliteCorrections.CREATOR))
+ .build();
+ }
+
+ @Override
+ public GpsAssistance[] newArray(int size) {
+ return new GpsAssistance[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeTypedObject(mAlmanac, flags);
+ dest.writeTypedObject(mIonosphericModel, flags);
+ dest.writeTypedObject(mUtcModel, flags);
+ dest.writeTypedObject(mLeapSecondsModel, flags);
+ dest.writeTypedList(mTimeModels);
+ dest.writeTypedList(mSatelliteEphemeris);
+ dest.writeTypedList(mRealTimeIntegrityModels);
+ dest.writeTypedList(mSatelliteCorrections);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GnssAssistance[");
+ builder.append("almanac = ").append(mAlmanac);
+ builder.append(", ionosphericModel = ").append(mIonosphericModel);
+ builder.append(", utcModel = ").append(mUtcModel);
+ builder.append(", leapSecondsModel = ").append(mLeapSecondsModel);
+ builder.append(", timeModels = ").append(mTimeModels);
+ builder.append(", satelliteEphemeris = ").append(mSatelliteEphemeris);
+ builder.append(", realTimeIntegrityModels = ").append(mRealTimeIntegrityModels);
+ builder.append(", satelliteCorrections = ").append(mSatelliteCorrections);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GpsAssistance}. */
+ public static final class Builder {
+ private GnssAlmanac mAlmanac;
+ private KlobucharIonosphericModel mIonosphericModel;
+ private UtcModel mUtcModel;
+ private LeapSecondsModel mLeapSecondsModel;
+ private List<TimeModel> mTimeModels;
+ private List<GpsSatelliteEphemeris> mSatelliteEphemeris;
+ private List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+ private List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+ /** Sets the GPS almanac. */
+ @NonNull
+ public Builder setAlmanac(
+ @Nullable @SuppressLint("NullableCollection") GnssAlmanac almanac) {
+ mAlmanac = almanac;
+ return this;
+ }
+
+ /** Sets the Klobuchar ionospheric model. */
+ @NonNull
+ public Builder setIonosphericModel(
+ @Nullable @SuppressLint("NullableCollection")
+ KlobucharIonosphericModel ionosphericModel) {
+ mIonosphericModel = ionosphericModel;
+ return this;
+ }
+
+ /** Sets the UTC model. */
+ @NonNull
+ public Builder setUtcModel(
+ @Nullable @SuppressLint("NullableCollection") UtcModel utcModel) {
+ mUtcModel = utcModel;
+ return this;
+ }
+
+ /** Sets the leap seconds model. */
+ @NonNull
+ public Builder setLeapSecondsModel(
+ @Nullable @SuppressLint("NullableCollection") LeapSecondsModel leapSecondsModel) {
+ mLeapSecondsModel = leapSecondsModel;
+ return this;
+ }
+
+ /** Sets the list of time models. */
+ @NonNull
+ public Builder setTimeModels(
+ @Nullable @SuppressLint("NullableCollection") List<TimeModel> timeModels) {
+ mTimeModels = timeModels;
+ return this;
+ }
+
+ /** Sets the list of GPS ephemeris. */
+ @NonNull
+ public Builder setSatelliteEphemeris(
+ @Nullable @SuppressLint("NullableCollection")
+ List<GpsSatelliteEphemeris> satelliteEphemeris) {
+ mSatelliteEphemeris = satelliteEphemeris;
+ return this;
+ }
+
+ /** Sets the list of real time integrity models. */
+ @NonNull
+ public Builder setRealTimeIntegrityModels(
+ @Nullable @SuppressLint("NullableCollection")
+ List<RealTimeIntegrityModel> realTimeIntegrityModels) {
+ mRealTimeIntegrityModels = realTimeIntegrityModels;
+ return this;
+ }
+
+ /** Sets the list of GPS satellite corrections. */
+ @NonNull
+ public Builder setSatelliteCorrections(
+ @Nullable @SuppressLint("NullableCollection")
+ List<GnssSatelliteCorrections> satelliteCorrections) {
+ mSatelliteCorrections = satelliteCorrections;
+ return this;
+ }
+
+ /** Builds a {@link GpsAssistance} instance as specified by this builder. */
+ @NonNull
+ public GpsAssistance build() {
+ return new GpsAssistance(this);
+ }
+ }
+}
diff --git a/location/java/android/location/GpsSatelliteEphemeris.java b/location/java/android/location/GpsSatelliteEphemeris.java
new file mode 100644
index 0000000..ec6bc59
--- /dev/null
+++ b/location/java/android/location/GpsSatelliteEphemeris.java
@@ -0,0 +1,632 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * This class contains ephemeris parameters specific to GPS satellites.
+ *
+ * <p>This is defined in IS-GPS-200 section 20.3.3.3.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class GpsSatelliteEphemeris implements Parcelable {
+ /** Satellite PRN */
+ private final int mPrn;
+
+ /** L2 parameters. */
+ @NonNull private final GpsL2Params mGpsL2Params;
+
+ /** Clock model. */
+ @NonNull private final GpsSatelliteClockModel mSatelliteClockModel;
+
+ /** Orbit model. */
+ @NonNull private final KeplerianOrbitModel mSatelliteOrbitModel;
+
+ /** Satellite health. */
+ @NonNull private final GpsSatelliteHealth mSatelliteHealth;
+
+ /** Ephemeris time. */
+ @NonNull private final SatelliteEphemerisTime mSatelliteEphemerisTime;
+
+ private GpsSatelliteEphemeris(Builder builder) {
+ // Allow PRN beyond the range to support potential future extensibility.
+ Preconditions.checkArgument(builder.mPrn >= 1);
+ Preconditions.checkNotNull(builder.mGpsL2Params, "GPSL2Params cannot be null");
+ Preconditions.checkNotNull(builder.mSatelliteClockModel,
+ "SatelliteClockModel cannot be null");
+ Preconditions.checkNotNull(builder.mSatelliteOrbitModel,
+ "SatelliteOrbitModel cannot be null");
+ Preconditions.checkNotNull(builder.mSatelliteHealth,
+ "SatelliteHealth cannot be null");
+ Preconditions.checkNotNull(builder.mSatelliteEphemerisTime,
+ "SatelliteEphemerisTime cannot be null");
+ mPrn = builder.mPrn;
+ mGpsL2Params = builder.mGpsL2Params;
+ mSatelliteClockModel = builder.mSatelliteClockModel;
+ mSatelliteOrbitModel = builder.mSatelliteOrbitModel;
+ mSatelliteHealth = builder.mSatelliteHealth;
+ mSatelliteEphemerisTime = builder.mSatelliteEphemerisTime;
+ }
+
+ /** Returns the PRN of the satellite. */
+ @IntRange(from = 1, to = 32)
+ public int getPrn() {
+ return mPrn;
+ }
+
+ /** Returns the L2 parameters of the satellite. */
+ @NonNull
+ public GpsL2Params getGpsL2Params() {
+ return mGpsL2Params;
+ }
+
+ /** Returns the clock model of the satellite. */
+ @NonNull
+ public GpsSatelliteClockModel getSatelliteClockModel() {
+ return mSatelliteClockModel;
+ }
+
+ /** Returns the orbit model of the satellite. */
+ @NonNull
+ public KeplerianOrbitModel getSatelliteOrbitModel() {
+ return mSatelliteOrbitModel;
+ }
+
+ /** Returns the satellite health. */
+ @NonNull
+ public GpsSatelliteHealth getSatelliteHealth() {
+ return mSatelliteHealth;
+ }
+
+ /** Returns the ephemeris time. */
+ @NonNull
+ public SatelliteEphemerisTime getSatelliteEphemerisTime() {
+ return mSatelliteEphemerisTime;
+ }
+
+ public static final @NonNull Creator<GpsSatelliteEphemeris> CREATOR =
+ new Creator<GpsSatelliteEphemeris>() {
+ @Override
+ @NonNull
+ public GpsSatelliteEphemeris createFromParcel(Parcel in) {
+ final GpsSatelliteEphemeris.Builder gpsSatelliteEphemeris =
+ new Builder()
+ .setPrn(in.readInt())
+ .setGpsL2Params(in.readTypedObject(GpsL2Params.CREATOR))
+ .setSatelliteClockModel(
+ in.readTypedObject(GpsSatelliteClockModel.CREATOR))
+ .setSatelliteOrbitModel(
+ in.readTypedObject(KeplerianOrbitModel.CREATOR))
+ .setSatelliteHealth(
+ in.readTypedObject(GpsSatelliteHealth.CREATOR))
+ .setSatelliteEphemerisTime(
+ in.readTypedObject(SatelliteEphemerisTime.CREATOR));
+ return gpsSatelliteEphemeris.build();
+ }
+
+ @Override
+ public GpsSatelliteEphemeris[] newArray(int size) {
+ return new GpsSatelliteEphemeris[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mPrn);
+ parcel.writeTypedObject(mGpsL2Params, flags);
+ parcel.writeTypedObject(mSatelliteClockModel, flags);
+ parcel.writeTypedObject(mSatelliteOrbitModel, flags);
+ parcel.writeTypedObject(mSatelliteHealth, flags);
+ parcel.writeTypedObject(mSatelliteEphemerisTime, flags);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GpsSatelliteEphemeris[");
+ builder.append("prn = ").append(mPrn);
+ builder.append(", gpsL2Params = ").append(mGpsL2Params);
+ builder.append(", satelliteClockModel = ").append(mSatelliteClockModel);
+ builder.append(", satelliteOrbitModel = ").append(mSatelliteOrbitModel);
+ builder.append(", satelliteHealth = ").append(mSatelliteHealth);
+ builder.append(", satelliteEphemerisTime = ").append(mSatelliteEphemerisTime);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GpsSatelliteEphemeris} */
+ public static final class Builder {
+ private int mPrn = 0;
+ private GpsL2Params mGpsL2Params;
+ private GpsSatelliteClockModel mSatelliteClockModel;
+ private KeplerianOrbitModel mSatelliteOrbitModel;
+ private GpsSatelliteHealth mSatelliteHealth;
+ private SatelliteEphemerisTime mSatelliteEphemerisTime;
+
+ /** Sets the PRN of the satellite. */
+ @NonNull
+ public Builder setPrn(@IntRange(from = 1, to = 32) int prn) {
+ mPrn = prn;
+ return this;
+ }
+
+ /** Sets the L2 parameters of the satellite. */
+ @NonNull
+ public Builder setGpsL2Params(@NonNull GpsL2Params gpsL2Params) {
+ mGpsL2Params = gpsL2Params;
+ return this;
+ }
+
+ /** Sets the clock model of the satellite. */
+ @NonNull
+ public Builder setSatelliteClockModel(@NonNull GpsSatelliteClockModel satelliteClockModel) {
+ mSatelliteClockModel = satelliteClockModel;
+ return this;
+ }
+
+ /** Sets the orbit model of the satellite. */
+ @NonNull
+ public Builder setSatelliteOrbitModel(@NonNull KeplerianOrbitModel satelliteOrbitModel) {
+ mSatelliteOrbitModel = satelliteOrbitModel;
+ return this;
+ }
+
+ /** Sets the satellite health. */
+ @NonNull
+ public Builder setSatelliteHealth(@NonNull GpsSatelliteHealth satelliteHealth) {
+ mSatelliteHealth = satelliteHealth;
+ return this;
+ }
+
+ /** Sets the ephemeris time. */
+ @NonNull
+ public Builder setSatelliteEphemerisTime(
+ @NonNull SatelliteEphemerisTime satelliteEphemerisTime) {
+ mSatelliteEphemerisTime = satelliteEphemerisTime;
+ return this;
+ }
+
+ /** Builds a {@link GpsSatelliteEphemeris} instance as specified by this builder. */
+ @NonNull
+ public GpsSatelliteEphemeris build() {
+ return new GpsSatelliteEphemeris(this);
+ }
+ }
+
+ /**
+ * A class contains information about GPS health. The information is tied to Legacy Navigation
+ * (LNAV) data, not Civil Navigation (CNAV) data.
+ */
+ public static final class GpsSatelliteHealth implements Parcelable {
+ /**
+ * Represents "SV health" in the "BROADCAST ORBIT - 6" record of RINEX 3.05. Table A6,
+ * pp.68.
+ */
+ private final int mSvHealth;
+
+ /**
+ * Represents "SV accuracy" in meters in the "BROADCAST ORBIT - 6" record of RINEX 3.05.
+ * Table A6, pp.68.
+ */
+ private final double mSvAccur;
+
+ /**
+ * Represents the "Fit Interval" in hours in the "BROADCAST ORBIT - 7" record of RINEX 3.05.
+ * Table A6, pp.69.
+ */
+ private final double mFitInt;
+
+ /** Returns the SV health. */
+ @IntRange(from = 0, to = 63)
+ public int getSvHealth() {
+ return mSvHealth;
+ }
+
+ /** Returns the SV accuracy in meters. */
+ @FloatRange(from = 0.0f, to = 8192.0f)
+ public double getSvAccur() {
+ return mSvAccur;
+ }
+
+ /** Returns the fit interval in hours. */
+ @FloatRange(from = 0.0f)
+ public double getFitInt() {
+ return mFitInt;
+ }
+
+ private GpsSatelliteHealth(Builder builder) {
+ // Allow SV health beyond the range to support potential future extensibility.
+ Preconditions.checkArgument(builder.mSvHealth >= 0);
+ Preconditions.checkArgumentInRange(builder.mSvAccur, 0.0f, 8192.0f, "SvAccur");
+ Preconditions.checkArgument(builder.mFitInt >= 0.0f);
+ mSvHealth = builder.mSvHealth;
+ mSvAccur = builder.mSvAccur;
+ mFitInt = builder.mFitInt;
+ }
+
+ public static final @NonNull Creator<GpsSatelliteHealth> CREATOR =
+ new Creator<GpsSatelliteHealth>() {
+ @Override
+ @NonNull
+ public GpsSatelliteHealth createFromParcel(Parcel in) {
+ final GpsSatelliteHealth.Builder gpsSatelliteHealth =
+ new Builder()
+ .setSvHealth(in.readInt())
+ .setSvAccur(in.readDouble())
+ .setFitInt(in.readDouble());
+ return gpsSatelliteHealth.build();
+ }
+
+ @Override
+ public GpsSatelliteHealth[] newArray(int size) {
+ return new GpsSatelliteHealth[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mSvHealth);
+ parcel.writeDouble(mSvAccur);
+ parcel.writeDouble(mFitInt);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GpsSatelliteHealth[");
+ builder.append("svHealth = ").append(mSvHealth);
+ builder.append(", svAccur = ").append(mSvAccur);
+ builder.append(", fitInt = ").append(mFitInt);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GpsSatelliteHealth}. */
+ public static final class Builder {
+ private int mSvHealth;
+ private double mSvAccur;
+ private double mFitInt;
+
+ /** Sets the SV health. */
+ @NonNull
+ public Builder setSvHealth(@IntRange(from = 0, to = 63) int svHealth) {
+ mSvHealth = svHealth;
+ return this;
+ }
+
+ /** Sets the SV accuracy in meters. */
+ @NonNull
+ public Builder setSvAccur(@FloatRange(from = 0.0f, to = 8192.0f) double svAccur) {
+ mSvAccur = svAccur;
+ return this;
+ }
+
+ /** Sets the fit interval in hours. */
+ @NonNull
+ public Builder setFitInt(@FloatRange(from = 0.0f) double fitInt) {
+ mFitInt = fitInt;
+ return this;
+ }
+
+ /** Builds a {@link GpsSatelliteHealth} instance as specified by this builder. */
+ @NonNull
+ public GpsSatelliteHealth build() {
+ return new GpsSatelliteHealth(this);
+ }
+ }
+ }
+
+ /** A class contains L2 parameters specific to GPS satellites. */
+ public static final class GpsL2Params implements Parcelable {
+ /** Code(s) on L2 Channel. */
+ private final int mL2Code;
+
+ /** Data Flag for L2 P-Code. */
+ private final int mL2Flag;
+
+ /** Returns the code(s) on L2 channel. */
+ @IntRange(from = 0, to = 3)
+ public int getL2Code() {
+ return mL2Code;
+ }
+
+ /** Returns the data flag for L2 P-code. */
+ @IntRange(from = 0, to = 1)
+ public int getL2Flag() {
+ return mL2Flag;
+ }
+
+ private GpsL2Params(Builder builder) {
+ Preconditions.checkArgumentInRange(builder.mL2Code, 0, 3, "L2 code");
+ Preconditions.checkArgumentInRange(builder.mL2Flag, 0, 1, "L2 flag");
+ mL2Code = builder.mL2Code;
+ mL2Flag = builder.mL2Flag;
+ }
+
+ public static final @NonNull Creator<GpsL2Params> CREATOR =
+ new Creator<GpsL2Params>() {
+ @Override
+ @NonNull
+ public GpsL2Params createFromParcel(Parcel in) {
+ final GpsL2Params.Builder gpsL2Params =
+ new Builder().setL2Code(in.readInt()).setL2Flag(in.readInt());
+ return gpsL2Params.build();
+ }
+
+ @Override
+ public GpsL2Params[] newArray(int size) {
+ return new GpsL2Params[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mL2Code);
+ parcel.writeInt(mL2Flag);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GpsL2Params[");
+ builder.append("l2Code = ").append(mL2Code);
+ builder.append(", l2Flag = ").append(mL2Flag);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GpsL2Params}. */
+ public static final class Builder {
+ private int mL2Code = 0;
+ private int mL2Flag = 0;
+
+ /** Sets the code(s) on L2 channel. */
+ @NonNull
+ public Builder setL2Code(@IntRange(from = 0, to = 3) int l2Code) {
+ mL2Code = l2Code;
+ return this;
+ }
+
+ /** Sets the data flag for L2 P-code. */
+ @NonNull
+ public Builder setL2Flag(@IntRange(from = 0, to = 1) int l2Flag) {
+ mL2Flag = l2Flag;
+ return this;
+ }
+
+ /** Builds a {@link GpsL2Params} instance as specified by this builder. */
+ @NonNull
+ public GpsL2Params build() {
+ return new GpsL2Params(this);
+ }
+ }
+ }
+
+ /** A class contains the set of parameters needed for GPS satellite clock correction. */
+ public static final class GpsSatelliteClockModel implements Parcelable {
+ /**
+ * Time of the clock in seconds since GPS epoch.
+ *
+ * <p>Corresponds to the 'Epoch' field within the 'SV/EPOCH/SV CLK' record of GPS
+ * navigation message in RINEX 3.05 Table A6.
+ */
+ private final long mTimeOfClockSeconds;
+
+ /** SV clock bias in seconds. */
+ private final double mAf0;
+
+ /** SV clock drift in seconds per second. */
+ private final double mAf1;
+
+ /** Clock drift rate in seconds per second squared. */
+ private final double mAf2;
+
+ /** Group delay differential in seconds. */
+ private final double mTgd;
+
+ /** Issue of data, clock. */
+ private final int mIodc;
+
+ private GpsSatelliteClockModel(Builder builder) {
+ Preconditions.checkArgument(builder.mTimeOfClockSeconds >= 0);
+ Preconditions.checkArgumentInRange(builder.mAf0, -9.77e-3f, 9.77e-3f, "Af0");
+ Preconditions.checkArgumentInRange(builder.mAf1, -3.73e-9f, 3.73e-9f, "Af1");
+ Preconditions.checkArgumentInRange(builder.mAf2, -3.56e-15f, 3.56e-15f, "Af2");
+ Preconditions.checkArgumentInRange(builder.mTgd, -5.97e-8f, 5.97e-8f, "Tgd");
+ Preconditions.checkArgumentInRange(builder.mIodc, 0, 1023, "Iodc");
+ mTimeOfClockSeconds = builder.mTimeOfClockSeconds;
+ mAf0 = builder.mAf0;
+ mAf1 = builder.mAf1;
+ mAf2 = builder.mAf2;
+ mTgd = builder.mTgd;
+ mIodc = builder.mIodc;
+ }
+
+ /** Returns the time of the clock in seconds since GPS epoch. */
+ @IntRange(from = 0)
+ public long getTimeOfClockSeconds() {
+ return mTimeOfClockSeconds;
+ }
+
+ /** Returns the SV clock bias in seconds. */
+ @FloatRange(from = -9.77e-3f, to = 9.77e-3f)
+ public double getAf0() {
+ return mAf0;
+ }
+
+ /** Returns the SV clock drift in seconds per second. */
+ @FloatRange(from = -3.73e-9f, to = 3.73e-9f)
+ public double getAf1() {
+ return mAf1;
+ }
+
+ /** Returns the clock drift rate in seconds per second squared. */
+ @FloatRange(from = -3.56e-15f, to = 3.56e-15f)
+ public double getAf2() {
+ return mAf2;
+ }
+
+ /** Returns the group delay differential in seconds. */
+ @FloatRange(from = -5.97e-8f, to = 5.97e-8f)
+ public double getTgd() {
+ return mTgd;
+ }
+
+ /** Returns the issue of data, clock. */
+ @IntRange(from = 0, to = 1023)
+ public int getIodc() {
+ return mIodc;
+ }
+
+ public static final @NonNull Creator<GpsSatelliteClockModel> CREATOR =
+ new Creator<GpsSatelliteClockModel>() {
+ @Override
+ @NonNull
+ public GpsSatelliteClockModel createFromParcel(Parcel in) {
+ final GpsSatelliteClockModel.Builder gpsSatelliteClockModel =
+ new Builder()
+ .setTimeOfClockSeconds(in.readLong())
+ .setAf0(in.readDouble())
+ .setAf1(in.readDouble())
+ .setAf2(in.readDouble())
+ .setTgd(in.readDouble())
+ .setIodc(in.readInt());
+ return gpsSatelliteClockModel.build();
+ }
+
+ @Override
+ public GpsSatelliteClockModel[] newArray(int size) {
+ return new GpsSatelliteClockModel[size];
+ }
+ };
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeLong(mTimeOfClockSeconds);
+ parcel.writeDouble(mAf0);
+ parcel.writeDouble(mAf1);
+ parcel.writeDouble(mAf2);
+ parcel.writeDouble(mTgd);
+ parcel.writeInt(mIodc);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("GpsSatelliteClockModel[");
+ builder.append("timeOfClockSeconds = ").append(mTimeOfClockSeconds);
+ builder.append(", af0 = ").append(mAf0);
+ builder.append(", af1 = ").append(mAf1);
+ builder.append(", af2 = ").append(mAf2);
+ builder.append(", tgd = ").append(mTgd);
+ builder.append(", iodc = ").append(mIodc);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link GpsSatelliteClockModel}. */
+ public static final class Builder {
+ private long mTimeOfClockSeconds;
+ private double mAf0;
+ private double mAf1;
+ private double mAf2;
+ private double mTgd;
+ private int mIodc;
+
+ /** Sets the time of the clock in seconds since GPS epoch. */
+ @NonNull
+ public Builder setTimeOfClockSeconds(@IntRange(from = 0) long timeOfClockSeconds) {
+ mTimeOfClockSeconds = timeOfClockSeconds;
+ return this;
+ }
+
+ /** Sets the SV clock bias in seconds. */
+ @NonNull
+ public Builder setAf0(@FloatRange(from = -9.77e-3f, to = 9.77e-3f) double af0) {
+ mAf0 = af0;
+ return this;
+ }
+
+ /** Sets the SV clock drift in seconds per second. */
+ @NonNull
+ public Builder setAf1(@FloatRange(from = -3.73e-9f, to = 3.73e-9f) double af1) {
+ mAf1 = af1;
+ return this;
+ }
+
+ /** Sets the clock drift rate in seconds per second squared. */
+ @NonNull
+ public Builder setAf2(@FloatRange(from = -3.56e-15f, to = 3.56e-15f) double af2) {
+ mAf2 = af2;
+ return this;
+ }
+
+ /** Sets the group delay differential in seconds. */
+ @NonNull
+ public Builder setTgd(@FloatRange(from = -5.97e-8f, to = 5.97e-8f) double tgd) {
+ mTgd = tgd;
+ return this;
+ }
+
+ /** Sets the issue of data, clock. */
+ @NonNull
+ public Builder setIodc(@IntRange(from = 0, to = 1023) int iodc) {
+ mIodc = iodc;
+ return this;
+ }
+
+ /** Builds a {@link GpsSatelliteClockModel} instance as specified by this builder. */
+ @NonNull
+ public GpsSatelliteClockModel build() {
+ return new GpsSatelliteClockModel(this);
+ }
+ }
+ }
+}
diff --git a/location/java/android/location/IonosphericCorrection.java b/location/java/android/location/IonosphericCorrection.java
new file mode 100644
index 0000000..aafcf83
--- /dev/null
+++ b/location/java/android/location/IonosphericCorrection.java
@@ -0,0 +1,112 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains ionospheric correction.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class IonosphericCorrection implements Parcelable {
+
+ /** Carrier frequency in Hz to differentiate signals from the same satellite. e.g. GPS L1/L5 */
+ private final long mCarrierFrequencyHz;
+
+ /** Ionospheric correction. */
+ @NonNull private final GnssCorrectionComponent mIonosphericCorrection;
+
+ /**
+ * Creates a new {@link IonosphericCorrection} instance.
+ *
+ * @param carrierFrequencyHz Carrier frequency in Hz to differentiate signals from the
+ * samesatellite. e.g. GPS L1/L5
+ * @param ionosphericCorrection Ionospheric correction.
+ */
+ public IonosphericCorrection(
+ @IntRange(from = 0) long carrierFrequencyHz,
+ @NonNull GnssCorrectionComponent ionosphericCorrection) {
+ Preconditions.checkArgument(carrierFrequencyHz > 0);
+ Preconditions.checkNotNull(ionosphericCorrection, "IonosphericCorrection cannot be null");
+ mCarrierFrequencyHz = carrierFrequencyHz;
+ mIonosphericCorrection = ionosphericCorrection;
+ }
+
+ /**
+ * Returns the carrier frequency in Hz to differentiate signals from the same satellite. e.g.
+ * GPS L1/L5
+ */
+ @IntRange(from = 0)
+ public long getCarrierFrequencyHz() {
+ return mCarrierFrequencyHz;
+ }
+
+ /** Returns the Ionospheric correction. */
+ @NonNull
+ public GnssCorrectionComponent getIonosphericCorrection() {
+ return mIonosphericCorrection;
+ }
+
+ public static final @NonNull Creator<IonosphericCorrection> CREATOR =
+ new Creator<IonosphericCorrection>() {
+ @Override
+ @NonNull
+ public IonosphericCorrection createFromParcel(Parcel in) {
+ long carrierFrequencyHz = in.readLong();
+ GnssCorrectionComponent ionosphericCorrection =
+ in.readTypedObject(GnssCorrectionComponent.CREATOR);
+ return new IonosphericCorrection(carrierFrequencyHz, ionosphericCorrection);
+ }
+
+ @Override
+ public IonosphericCorrection[] newArray(int size) {
+ return new IonosphericCorrection[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeLong(mCarrierFrequencyHz);
+ dest.writeTypedObject(mIonosphericCorrection, flags);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("IonosphericCorrection[");
+ builder.append("carrierFrequencyHz = ").append(mCarrierFrequencyHz);
+ builder.append(", ionosphericCorrection = ").append(mIonosphericCorrection);
+ builder.append("]");
+ return builder.toString();
+ }
+}
diff --git a/location/java/android/location/KeplerianOrbitModel.java b/location/java/android/location/KeplerianOrbitModel.java
new file mode 100644
index 0000000..a118274
--- /dev/null
+++ b/location/java/android/location/KeplerianOrbitModel.java
@@ -0,0 +1,518 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Contains Keplerian orbit model parameters for GPS/Galileo/QZSS/Beidou.
+ * <p>For GPS, this is defined in IS-GPS-200 Table 20-II.
+ * <p>For Galileo, this is defined in Galileo-OS-SIS-ICD-v2.1 section 5.1.1.
+ * <p>For QZSS, this is defined in IS-QZSS-PNT section 4.1.2.
+ * <p>For Baidou, this is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.12.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class KeplerianOrbitModel implements Parcelable {
+ /** Square root of the semi-major axis in square root of meters. */
+ private final double mRootA;
+
+ /** Eccentricity. */
+ private final double mEccentricity;
+
+ /** Inclination angle at reference time in radians. */
+ private final double mI0;
+
+ /** Rate of change of inclination angle in radians per second. */
+ private final double mIDot;
+
+ /** Argument of perigee in radians. */
+ private final double mOmega;
+
+ /** Longitude of ascending node of orbit plane at beginning of week in radians. */
+ private final double mOmega0;
+
+ /** Rate of right ascension in radians per second. */
+ private final double mOmegaDot;
+
+ /** Mean anomaly at reference time in radians. */
+ private final double mM0;
+
+ /** Mean motion difference from computed value in radians per second. */
+ private final double mDeltaN;
+
+ /** Second-order harmonic perturbations. */
+ SecondOrderHarmonicPerturbation mSecondOrderHarmonicPerturbation;
+
+ private KeplerianOrbitModel(Builder builder) {
+ Preconditions.checkArgumentInRange(builder.mRootA, 0.0f, 8192.0f, "RootA");
+ Preconditions.checkArgumentInRange(builder.mEccentricity, 0.0f, 0.5f, "Eccentricity");
+ Preconditions.checkArgumentInRange(builder.mI0, -3.15f, 3.15f, "I0");
+ Preconditions.checkArgumentInRange(builder.mIDot, -2.94e-9f, 2.94e-9f, "IDot");
+ Preconditions.checkArgumentInRange(builder.mOmega, -3.15f, 3.15f, "Omega");
+ Preconditions.checkArgumentInRange(builder.mOmega0, -3.15f, 3.15f, "Omega0");
+ Preconditions.checkArgumentInRange(builder.mOmegaDot, -3.1e-6f, 3.1e-6f, "OmegaDot");
+ Preconditions.checkArgumentInRange(builder.mM0, -3.15f, 3.15f, "M0");
+ Preconditions.checkArgumentInRange(builder.mDeltaN, -1.18e-8f, 1.18e-8f, "DeltaN");
+ mRootA = builder.mRootA;
+ mEccentricity = builder.mEccentricity;
+ mI0 = builder.mI0;
+ mIDot = builder.mIDot;
+ mOmega = builder.mOmega;
+ mOmega0 = builder.mOmega0;
+ mOmegaDot = builder.mOmegaDot;
+ mM0 = builder.mM0;
+ mDeltaN = builder.mDeltaN;
+ mSecondOrderHarmonicPerturbation = builder.mSecondOrderHarmonicPerturbation;
+ }
+
+ /** Get the square root of the semi-major axis in square root of meters. */
+ @FloatRange(from = 0.0f, to = 8192.0f)
+ public double getRootA() {
+ return mRootA;
+ }
+
+ /** Get the eccentricity. */
+ @FloatRange(from = 0.0f, to = 0.5f)
+ public double getEccentricity() {
+ return mEccentricity;
+ }
+
+ /** Get the inclination angle at reference time in radians. */
+ @FloatRange(from = -3.15f, to = 3.15f)
+ public double getI0() {
+ return mI0;
+ }
+
+ /** Get the rate of change of inclination angle in radians per second. */
+ @FloatRange(from = -2.94e-9f, to = 2.94e-9f)
+ public double getIDot() {
+ return mIDot;
+ }
+
+ /** Get the argument of perigee in radians. */
+ @FloatRange(from = -3.15f, to = 3.15f)
+ public double getOmega() {
+ return mOmega;
+ }
+
+ /** Get the longitude of ascending node of orbit plane at beginning of week in radians. */
+ @FloatRange(from = -3.15f, to = 3.15f)
+ public double getOmega0() {
+ return mOmega0;
+ }
+
+ /** Get the rate of right ascension in radians per second. */
+ @FloatRange(from = -3.1e-6f, to = 3.1e-6f)
+ public double getOmegaDot() {
+ return mOmegaDot;
+ }
+
+ /** Get the mean anomaly at reference time in radians. */
+ @FloatRange(from = -3.15f, to = 3.15f)
+ public double getM0() {
+ return mM0;
+ }
+
+ /** Get the mean motion difference from computed value in radians per second. */
+ @FloatRange(from = -1.18e-8f, to = 1.18e-8f)
+ public double getDeltaN() {
+ return mDeltaN;
+ }
+
+ /** Get the second-order harmonic perturbations. */
+ @NonNull
+ public SecondOrderHarmonicPerturbation getSecondOrderHarmonicPerturbation() {
+ return mSecondOrderHarmonicPerturbation;
+ }
+
+ public static final @NonNull Creator<KeplerianOrbitModel> CREATOR =
+ new Creator<KeplerianOrbitModel>() {
+ @Override
+ @NonNull
+ public KeplerianOrbitModel createFromParcel(Parcel in) {
+ final KeplerianOrbitModel.Builder keplerianOrbitModel =
+ new Builder()
+ .setRootA(in.readDouble())
+ .setEccentricity(in.readDouble())
+ .setI0(in.readDouble())
+ .setIDot(in.readDouble())
+ .setOmega(in.readDouble())
+ .setOmega0(in.readDouble())
+ .setOmegaDot(in.readDouble())
+ .setM0(in.readDouble())
+ .setDeltaN(in.readDouble())
+ .setSecondOrderHarmonicPerturbation(
+ in.readTypedObject(
+ SecondOrderHarmonicPerturbation.CREATOR));
+ return keplerianOrbitModel.build();
+ }
+
+ @Override
+ public KeplerianOrbitModel[] newArray(int size) {
+ return new KeplerianOrbitModel[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeDouble(mRootA);
+ parcel.writeDouble(mEccentricity);
+ parcel.writeDouble(mI0);
+ parcel.writeDouble(mIDot);
+ parcel.writeDouble(mOmega);
+ parcel.writeDouble(mOmega0);
+ parcel.writeDouble(mOmegaDot);
+ parcel.writeDouble(mM0);
+ parcel.writeDouble(mDeltaN);
+ parcel.writeTypedObject(mSecondOrderHarmonicPerturbation, flags);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("KeplerianOrbitModel[");
+ builder.append("rootA = ").append(mRootA);
+ builder.append(", eccentricity = ").append(mEccentricity);
+ builder.append(", i0 = ").append(mI0);
+ builder.append(", iDot = ").append(mIDot);
+ builder.append(", omega = ").append(mOmega);
+ builder.append(", omega0 = ").append(mOmega0);
+ builder.append(", omegaDot = ").append(mOmegaDot);
+ builder.append(", m0 = ").append(mM0);
+ builder.append(", deltaN = ").append(mDeltaN);
+ builder.append(", secondOrderHarmonicPerturbation = ")
+ .append(mSecondOrderHarmonicPerturbation);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link KeplerianOrbitModel} */
+ public static final class Builder {
+ private double mRootA;
+ private double mEccentricity;
+ private double mI0;
+ private double mIDot;
+ private double mOmega;
+ private double mOmega0;
+ private double mOmegaDot;
+ private double mM0;
+ private double mDeltaN;
+ private SecondOrderHarmonicPerturbation mSecondOrderHarmonicPerturbation;
+
+ /** Sets the square root of the semi-major axis in square root of meters. */
+ @NonNull
+ public Builder setRootA(@FloatRange(from = 0.0f, to = 8192.0f) double rootA) {
+ mRootA = rootA;
+ return this;
+ }
+
+ /** Sets the eccentricity. */
+ @NonNull
+ public Builder setEccentricity(@FloatRange(from = 0.0f, to = 0.5f) double eccentricity) {
+ mEccentricity = eccentricity;
+ return this;
+ }
+
+ /** Sets the inclination angle at reference time in radians. */
+ @NonNull
+ public Builder setI0(@FloatRange(from = -3.15f, to = 3.15f) double i0) {
+ mI0 = i0;
+ return this;
+ }
+
+ /** Sets the rate of change of inclination angle in radians per second. */
+ @NonNull
+ public Builder setIDot(@FloatRange(from = -2.94e-9f, to = 2.94e-9f) double iDot) {
+ mIDot = iDot;
+ return this;
+ }
+
+ /** Sets the argument of perigee in radians. */
+ @NonNull
+ public Builder setOmega(@FloatRange(from = -3.15f, to = 3.15f) double omega) {
+ mOmega = omega;
+ return this;
+ }
+
+ /**
+ * Sets the longitude of ascending node of orbit plane at beginning of week in radians.
+ */
+ @NonNull
+ public Builder setOmega0(@FloatRange(from = -3.15f, to = 3.15f) double omega0) {
+ mOmega0 = omega0;
+ return this;
+ }
+
+ /** Sets the rate of right ascension in radians per second. */
+ @NonNull
+ public Builder setOmegaDot(@FloatRange(from = -3.1e-6f, to = 3.1e-6f) double omegaDot) {
+ mOmegaDot = omegaDot;
+ return this;
+ }
+
+ /** Sets the mean anomaly at reference time in radians. */
+ @NonNull
+ public Builder setM0(@FloatRange(from = -3.15f, to = 3.15f) double m0) {
+ mM0 = m0;
+ return this;
+ }
+
+ /** Sets the mean motion difference from computed value in radians per second. */
+ @NonNull
+ public Builder setDeltaN(@FloatRange(from = -1.18e-8f, to = 1.18e-8f) double deltaN) {
+ mDeltaN = deltaN;
+ return this;
+ }
+
+ /** Sets the second-order harmonic perturbations. */
+ @NonNull
+ public Builder setSecondOrderHarmonicPerturbation(
+ @NonNull SecondOrderHarmonicPerturbation secondOrderHarmonicPerturbation) {
+ mSecondOrderHarmonicPerturbation = secondOrderHarmonicPerturbation;
+ return this;
+ }
+
+ /** Builds a {@link KeplerianOrbitModel} instance as specified by this builder. */
+ @NonNull
+ public KeplerianOrbitModel build() {
+ return new KeplerianOrbitModel(this);
+ }
+ }
+
+ /** A class contains second-order harmonic perturbations. */
+ public static final class SecondOrderHarmonicPerturbation implements Parcelable {
+ /** Amplitude of cosine harmonic correction term to angle of inclination in radians. */
+ private final double mCic;
+
+ /** Amplitude of sine harmonic correction term to angle of inclination in radians. */
+ private final double mCis;
+
+ /** Amplitude of cosine harmonic correction term to the orbit in meters. */
+ private final double mCrc;
+
+ /** Amplitude of sine harmonic correction term to the orbit in meters. */
+ private final double mCrs;
+
+ /** Amplitude of cosine harmonic correction term to the argument of latitude in radians. */
+ private final double mCuc;
+
+ /** Amplitude of sine harmonic correction term to the argument of latitude in radians. */
+ private final double mCus;
+
+ private SecondOrderHarmonicPerturbation(Builder builder) {
+ Preconditions.checkArgumentInRange(builder.mCic, -6.11e-5f, 6.11e-5f, "Cic");
+ Preconditions.checkArgumentInRange(builder.mCis, -6.11e-5f, 6.11e-5f, "Cis");
+ Preconditions.checkArgumentInRange(builder.mCrc, -2048.0f, 2048.0f, "Crc");
+ Preconditions.checkArgumentInRange(builder.mCrs, -2048.0f, 2048.0f, "Crs");
+ Preconditions.checkArgumentInRange(builder.mCuc, -6.11e-5f, 6.11e-5f, "Cuc");
+ Preconditions.checkArgumentInRange(builder.mCus, -6.11e-5f, 6.11e-5f, "Cus");
+ mCic = builder.mCic;
+ mCrc = builder.mCrc;
+ mCis = builder.mCis;
+ mCrs = builder.mCrs;
+ mCuc = builder.mCuc;
+ mCus = builder.mCus;
+ }
+
+ /**
+ * Get the amplitude of cosine harmonic correction term to angle of inclination in radians.
+ */
+ @FloatRange(from = -6.11e-5f, to = 6.11e-5f)
+ public double getCic() {
+ return mCic;
+ }
+
+ /**
+ * Get the amplitude of sine harmonic correction term to angle of inclination in radians.
+ */
+ @FloatRange(from = -6.11e-5f, to = 6.11e-5f)
+ public double getCis() {
+ return mCis;
+ }
+
+ /** Get the amplitude of cosine harmonic correction term to the orbit in meters. */
+ @FloatRange(from = -2048.0f, to = 2048.0f)
+ public double getCrc() {
+ return mCrc;
+ }
+
+ /** Get the amplitude of sine harmonic correction term to the orbit in meters. */
+ @FloatRange(from = -2048.0f, to = 2048.0f)
+ public double getCrs() {
+ return mCrs;
+ }
+
+ /**
+ * Get the amplitude of cosine harmonic correction term to the argument of latitude in
+ * radians.
+ */
+ @FloatRange(from = -6.11e-5f, to = 6.11e-5f)
+ public double getCuc() {
+ return mCuc;
+ }
+
+ /**
+ * Get the amplitude of sine harmonic correction term to the argument of latitude in
+ * radians.
+ */
+ @FloatRange(from = -6.11e-5f, to = 6.11e-5f)
+ public double getCus() {
+ return mCus;
+ }
+
+ public static final @NonNull Creator<SecondOrderHarmonicPerturbation> CREATOR =
+ new Creator<SecondOrderHarmonicPerturbation>() {
+ @Override
+ @NonNull
+ public SecondOrderHarmonicPerturbation createFromParcel(Parcel in) {
+ final SecondOrderHarmonicPerturbation.Builder
+ secondOrderHarmonicPerturbation =
+ new Builder()
+ .setCic(in.readDouble())
+ .setCis(in.readDouble())
+ .setCrc(in.readDouble())
+ .setCrs(in.readDouble())
+ .setCuc(in.readDouble())
+ .setCus(in.readDouble());
+ return secondOrderHarmonicPerturbation.build();
+ }
+
+ @Override
+ public SecondOrderHarmonicPerturbation[] newArray(int size) {
+ return new SecondOrderHarmonicPerturbation[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeDouble(mCic);
+ parcel.writeDouble(mCis);
+ parcel.writeDouble(mCrc);
+ parcel.writeDouble(mCrs);
+ parcel.writeDouble(mCuc);
+ parcel.writeDouble(mCus);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("SecondOrderHarmonicPerturbation[");
+ builder.append("cic = ").append(mCic);
+ builder.append(", cis = ").append(mCis);
+ builder.append(", crc = ").append(mCrc);
+ builder.append(", crs = ").append(mCrs);
+ builder.append(", cuc = ").append(mCuc);
+ builder.append(", cus = ").append(mCus);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link SecondOrderHarmonicPerturbation} */
+ public static final class Builder {
+ private double mCic;
+ private double mCis;
+ private double mCrc;
+ private double mCrs;
+ private double mCuc;
+ private double mCus;
+
+ /**
+ * Sets the amplitude of cosine harmonic correction term to angle of inclination in
+ * radians.
+ */
+ @NonNull
+ public Builder setCic(@FloatRange(from = -6.11e-5f, to = 6.11e-5f) double cic) {
+ mCic = cic;
+ return this;
+ }
+
+ /**
+ * Sets the amplitude of sine harmonic correction term to angle of inclination in
+ * radians.
+ */
+ @NonNull
+ public Builder setCis(@FloatRange(from = -6.11e-5f, to = 6.11e-5f) double cis) {
+ mCis = cis;
+ return this;
+ }
+
+ /** Sets the amplitude of cosine harmonic correction term to the orbit in meters. */
+ @NonNull
+ public Builder setCrc(@FloatRange(from = -2048.0f, to = 2048.0f) double crc) {
+ mCrc = crc;
+ return this;
+ }
+
+ /** Sets the amplitude of sine harmonic correction term to the orbit in meters. */
+ @NonNull
+ public Builder setCrs(@FloatRange(from = -2048.0f, to = 2048.0f) double crs) {
+ mCrs = crs;
+ return this;
+ }
+
+ /**
+ * Sets the amplitude of cosine harmonic correction term to the argument of latitude in
+ * radians.
+ */
+ @NonNull
+ public Builder setCuc(@FloatRange(from = -6.11e-5f, to = 6.11e-5f) double cuc) {
+ mCuc = cuc;
+ return this;
+ }
+
+ /**
+ * Sets the amplitude of sine harmonic correction term to the argument of latitude in
+ * radians.
+ */
+ @NonNull
+ public Builder setCus(@FloatRange(from = -6.11e-5f, to = 6.11e-5f) double cus) {
+ mCus = cus;
+ return this;
+ }
+
+ /**
+ * Builds a {@link SecondOrderHarmonicPerturbation} instance as specified by this
+ * builder.
+ */
+ @NonNull
+ public SecondOrderHarmonicPerturbation build() {
+ return new SecondOrderHarmonicPerturbation(this);
+ }
+ }
+ }
+}
diff --git a/location/java/android/location/KlobucharIonosphericModel.java b/location/java/android/location/KlobucharIonosphericModel.java
new file mode 100644
index 0000000..d239c87
--- /dev/null
+++ b/location/java/android/location/KlobucharIonosphericModel.java
@@ -0,0 +1,252 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains Klobuchar ionospheric model coefficients used by GPS, BDS, QZSS.
+ *
+ * <p>This is defined in IS-GPS-200 section 20.3.3.5.1.7.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class KlobucharIonosphericModel implements Parcelable {
+ /** Alpha0 coefficientin seconds. */
+ double mAlpha0;
+ /** Alpha1 coefficient in seconds per semi-circle. */
+ double mAlpha1;
+ /** Alpha2 coefficient in seconds per semi-circle squared. */
+ double mAlpha2;
+ /** Alpha3 coefficient in seconds per semi-circle cubed. */
+ double mAlpha3;
+ /** Beta0 coefficient in seconds. */
+ double mBeta0;
+ /** Beta1 coefficient in seconds per semi-circle. */
+ double mBeta1;
+ /** Beta2 coefficient in seconds per semi-circle squared. */
+ double mBeta2;
+ /** Beta3 coefficient in seconds per semi-circle cubed. */
+ double mBeta3;
+
+ private KlobucharIonosphericModel(Builder builder) {
+ Preconditions.checkArgumentInRange(builder.mAlpha0, -1.193e-7f, 1.193e-7f, "Alpha0");
+ Preconditions.checkArgumentInRange(builder.mAlpha1, -9.54e-7f, 9.54e-7f, "Alpha1");
+ Preconditions.checkArgumentInRange(builder.mAlpha2, -7.63e-6f, 7.63e-6f, "Alpha2");
+ Preconditions.checkArgumentInRange(builder.mAlpha3, -7.63e-6f, 7.63e-6f, "Alpha3");
+ Preconditions.checkArgumentInRange(builder.mBeta0, -262144.0f, 262144.0f, "Beta0");
+ Preconditions.checkArgumentInRange(builder.mBeta1, -2097152.0f, 2097152.0f, "Beta1");
+ Preconditions.checkArgumentInRange(builder.mBeta2, -8388608.0f, 8388608.0f, "Beta2");
+ Preconditions.checkArgumentInRange(builder.mBeta3, -8388608.0f, 8388608.0f, "Beta3");
+ mAlpha0 = builder.mAlpha0;
+ mAlpha1 = builder.mAlpha1;
+ mAlpha2 = builder.mAlpha2;
+ mAlpha3 = builder.mAlpha3;
+ mBeta0 = builder.mBeta0;
+ mBeta1 = builder.mBeta1;
+ mBeta2 = builder.mBeta2;
+ mBeta3 = builder.mBeta3;
+ }
+
+ /** Returns the alpha0 coefficient in seconds. */
+ @FloatRange(from = -1.193e-7f, to = 1.193e-7f)
+ public double getAlpha0() {
+ return mAlpha0;
+ }
+
+ /** Returns the alpha1 coefficient in seconds per semi-circle. */
+ @FloatRange(from = -9.54e-7f, to = 9.54e-7f)
+ public double getAlpha1() {
+ return mAlpha1;
+ }
+
+ /** Returns the alpha2 coefficient in seconds per semi-circle squared. */
+ @FloatRange(from = -7.63e-6f, to = 7.63e-6f)
+ public double getAlpha2() {
+ return mAlpha2;
+ }
+
+ /** Returns the alpha3 coefficient in seconds per semi-circle cubed. */
+ @FloatRange(from = -7.63e-6f, to = 7.63e-6f)
+ public double getAlpha3() {
+ return mAlpha3;
+ }
+
+ /** Returns the beta0 coefficient in seconds. */
+ @FloatRange(from = -262144.0f, to = 262144.0f)
+ public double getBeta0() {
+ return mBeta0;
+ }
+
+ /** Returns the beta1 coefficient in seconds per semi-circle. */
+ @FloatRange(from = -2097152.0f, to = 2097152.0f)
+ public double getBeta1() {
+ return mBeta1;
+ }
+
+ /** Returns the beta2 coefficient in seconds per semi-circle squared. */
+ @FloatRange(from = -8388608.0f, to = 8388608.0f)
+ public double getBeta2() {
+ return mBeta2;
+ }
+
+ /** Returns the beta3 coefficient in seconds per semi-circle cubed. */
+ @FloatRange(from = -8388608.0f, to = 8388608.0f)
+ public double getBeta3() {
+ return mBeta3;
+ }
+
+ public static final @NonNull Creator<KlobucharIonosphericModel> CREATOR =
+ new Creator<KlobucharIonosphericModel>() {
+ @Override
+ @NonNull
+ public KlobucharIonosphericModel createFromParcel(Parcel in) {
+ return new KlobucharIonosphericModel.Builder()
+ .setAlpha0(in.readDouble())
+ .setAlpha1(in.readDouble())
+ .setAlpha2(in.readDouble())
+ .setAlpha3(in.readDouble())
+ .setBeta0(in.readDouble())
+ .setBeta1(in.readDouble())
+ .setBeta2(in.readDouble())
+ .setBeta3(in.readDouble())
+ .build();
+ }
+ @Override
+ public KlobucharIonosphericModel[] newArray(int size) {
+ return new KlobucharIonosphericModel[size];
+ }
+ };
+
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeDouble(mAlpha0);
+ parcel.writeDouble(mAlpha1);
+ parcel.writeDouble(mAlpha2);
+ parcel.writeDouble(mAlpha3);
+ parcel.writeDouble(mBeta0);
+ parcel.writeDouble(mBeta1);
+ parcel.writeDouble(mBeta2);
+ parcel.writeDouble(mBeta3);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("KlobucharIonosphericModel[");
+ builder.append("alpha0 = ").append(mAlpha0);
+ builder.append(", alpha1 = ").append(mAlpha1);
+ builder.append(", alpha2 = ").append(mAlpha2);
+ builder.append(", alpha3 = ").append(mAlpha3);
+ builder.append(", beta0 = ").append(mBeta0);
+ builder.append(", beta1 = ").append(mBeta1);
+ builder.append(", beta2 = ").append(mBeta2);
+ builder.append(", beta3 = ").append(mBeta3);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link KlobucharIonosphericModel} */
+ public static final class Builder {
+ private double mAlpha0;
+ private double mAlpha1;
+ private double mAlpha2;
+ private double mAlpha3;
+ private double mBeta0;
+ private double mBeta1;
+ private double mBeta2;
+ private double mBeta3;
+
+ /** Sets the alpha0 coefficient in seconds. */
+ @NonNull
+ public Builder setAlpha0(@FloatRange(from = -1.193e-7f, to = 1.193e-7f) double alpha0) {
+ mAlpha0 = alpha0;
+ return this;
+ }
+
+ /** Sets the alpha1 coefficient in seconds per semi-circle. */
+ @NonNull
+ public Builder setAlpha1(@FloatRange(from = -9.54e-7f, to = 9.54e-7f) double alpha1) {
+ mAlpha1 = alpha1;
+ return this;
+ }
+
+ /** Sets the alpha2 coefficient in seconds per semi-circle squared. */
+ @NonNull
+ public Builder setAlpha2(@FloatRange(from = -7.63e-6f, to = 7.63e-6f) double alpha2) {
+ mAlpha2 = alpha2;
+ return this;
+ }
+
+ /** Sets the alpha3 coefficient in seconds per semi-circle cubed. */
+ @NonNull
+ public Builder setAlpha3(@FloatRange(from = -7.63e-6f, to = 7.63e-6f) double alpha3) {
+ mAlpha3 = alpha3;
+ return this;
+ }
+
+ /** Sets the beta0 coefficient in seconds. */
+ @NonNull
+ public Builder setBeta0(@FloatRange(from = -262144.0f, to = 262144.0f) double beta0) {
+ mBeta0 = beta0;
+ return this;
+ }
+
+ /** Sets the beta1 coefficient in seconds per semi-circle. */
+ @NonNull
+ public Builder setBeta1(@FloatRange(from = -2097152.0f, to = 2097152.0f) double beta1) {
+ mBeta1 = beta1;
+ return this;
+ }
+
+ /** Sets the beta2 coefficient in seconds per semi-circle squared. */
+ @NonNull
+ public Builder setBeta2(@FloatRange(from = -8388608.0f, to = 8388608.0f) double beta2) {
+ mBeta2 = beta2;
+ return this;
+ }
+
+ /** Sets the beta3 coefficient in seconds per semi-circle cubed. */
+ @NonNull
+ public Builder setBeta3(@FloatRange(from = -8388608.0f, to = 8388608.0f) double beta3) {
+ mBeta3 = beta3;
+ return this;
+ }
+
+ /** Builds a {@link KlobucharIonosphericModel} instance as specified by this builder. */
+ @NonNull
+ public KlobucharIonosphericModel build() {
+ return new KlobucharIonosphericModel(this);
+ }
+ }
+}
diff --git a/location/java/android/location/LeapSecondsModel.java b/location/java/android/location/LeapSecondsModel.java
new file mode 100644
index 0000000..bc132ad
--- /dev/null
+++ b/location/java/android/location/LeapSecondsModel.java
@@ -0,0 +1,171 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Contains the leap seconds set of parameters needed for GNSS time.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class LeapSecondsModel implements Parcelable {
+ /** Time difference due to leap seconds before the event in seconds. (UTC) */
+ private final int mLeapSeconds;
+
+ /** Time difference due to leap seconds after the event in seconds. (UTC) */
+ private final int mLeapSecondsFuture;
+
+ /** GNSS week number in which the leap second event will occur. (UTC) */
+ private final int mWeekNumberLeapSecondsFuture;
+
+ /** Day number when the next leap second will occur. */
+ private final int mDayNumberLeapSecondsFuture;
+
+ private LeapSecondsModel(Builder builder) {
+ Preconditions.checkArgument(builder.mLeapSeconds >= 0);
+ Preconditions.checkArgument(builder.mLeapSecondsFuture >= 0);
+ Preconditions.checkArgument(builder.mWeekNumberLeapSecondsFuture >= 0);
+ Preconditions.checkArgument(builder.mDayNumberLeapSecondsFuture >= 0);
+ mLeapSeconds = builder.mLeapSeconds;
+ mLeapSecondsFuture = builder.mLeapSecondsFuture;
+ mWeekNumberLeapSecondsFuture = builder.mWeekNumberLeapSecondsFuture;
+ mDayNumberLeapSecondsFuture = builder.mDayNumberLeapSecondsFuture;
+ }
+
+ /** Returns the time difference due to leap seconds before the event in seconds. (UTC) */
+ @IntRange(from = 0)
+ public int getLeapSeconds() {
+ return mLeapSeconds;
+ }
+
+ /** Returns the time difference due to leap seconds after the event in seconds. (UTC) */
+ @IntRange(from = 0)
+ public int getLeapSecondsFuture() {
+ return mLeapSecondsFuture;
+ }
+
+ /** Returns the GNSS week number in which the leap second event will occur. (UTC) */
+ @IntRange(from = 0)
+ public int getWeekNumberLeapSecondsFuture() {
+ return mWeekNumberLeapSecondsFuture;
+ }
+
+ /** Returns the day number when the next leap second will occur. */
+ @IntRange(from = 0)
+ public int getDayNumberLeapSecondsFuture() {
+ return mDayNumberLeapSecondsFuture;
+ }
+
+ public static final @NonNull Creator<LeapSecondsModel> CREATOR =
+ new Creator<LeapSecondsModel>() {
+ @Override
+ @NonNull
+ public LeapSecondsModel createFromParcel(Parcel in) {
+ final LeapSecondsModel.Builder leapSecondsModel = new Builder();
+ leapSecondsModel.setLeapSeconds(in.readInt());
+ leapSecondsModel.setLeapSecondsFuture(in.readInt());
+ leapSecondsModel.setWeekNumberLeapSecondsFuture(in.readInt());
+ leapSecondsModel.setDayNumberLeapSecondsFuture(in.readInt());
+ return leapSecondsModel.build();
+ }
+
+ @Override
+ public LeapSecondsModel[] newArray(int size) {
+ return new LeapSecondsModel[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mLeapSeconds);
+ parcel.writeInt(mLeapSecondsFuture);
+ parcel.writeInt(mWeekNumberLeapSecondsFuture);
+ parcel.writeInt(mDayNumberLeapSecondsFuture);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("LeapSecondsModel[");
+ builder.append("leapSeconds = ").append(mLeapSeconds);
+ builder.append(", leapSecondsFuture = ").append(mLeapSecondsFuture);
+ builder.append(", weekNumberLeapSecondsFuture = ").append(mWeekNumberLeapSecondsFuture);
+ builder.append(", dayNumberLeapSecondsFuture = ").append(mDayNumberLeapSecondsFuture);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link LeapSecondsModel} */
+ public static final class Builder {
+ private int mLeapSeconds;
+ private int mLeapSecondsFuture;
+ private int mWeekNumberLeapSecondsFuture;
+ private int mDayNumberLeapSecondsFuture;
+
+ /** Sets the time difference due to leap seconds before the event in seconds. (UTC) */
+ @NonNull
+ public Builder setLeapSeconds(@IntRange(from = 0) int leapSeconds) {
+ mLeapSeconds = leapSeconds;
+ return this;
+ }
+
+ /** Sets the time difference due to leap seconds after the event in seconds. (UTC) */
+ @NonNull
+ public Builder setLeapSecondsFuture(@IntRange(from = 0) int leapSecondsFuture) {
+ mLeapSecondsFuture = leapSecondsFuture;
+ return this;
+ }
+
+ /** Sets the GNSS week number in which the leap second event will occur. (UTC) */
+ @NonNull
+ public Builder setWeekNumberLeapSecondsFuture(
+ @IntRange(from = 0) int weekNumberLeapSecondsFuture) {
+ mWeekNumberLeapSecondsFuture = weekNumberLeapSecondsFuture;
+ return this;
+ }
+
+ /** Sets the day number when the next leap second will occur. */
+ @NonNull
+ public Builder setDayNumberLeapSecondsFuture(
+ @IntRange(from = 0) int dayNumberLeapSecondsFuture) {
+ mDayNumberLeapSecondsFuture = dayNumberLeapSecondsFuture;
+ return this;
+ }
+
+ /** Builds a {@link LeapSecondsModel} instance as specified by this builder. */
+ @NonNull
+ public LeapSecondsModel build() {
+ return new LeapSecondsModel(this);
+ }
+ }
+}
diff --git a/location/java/android/location/QzssAssistance.java b/location/java/android/location/QzssAssistance.java
new file mode 100644
index 0000000..9383ce3
--- /dev/null
+++ b/location/java/android/location/QzssAssistance.java
@@ -0,0 +1,282 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.location.GnssAssistance.GnssSatelliteCorrections;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class contains QZSS assistance.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class QzssAssistance implements Parcelable {
+
+ /** The QZSS almanac. */
+ @Nullable private final GnssAlmanac mAlmanac;
+
+ /** The Klobuchar ionospheric model. */
+ @Nullable private final KlobucharIonosphericModel mIonosphericModel;
+
+ /** The UTC model. */
+ @Nullable private final UtcModel mUtcModel;
+
+ /** The leap seconds model. */
+ @Nullable private final LeapSecondsModel mLeapSecondsModel;
+
+ /** The list of time models. */
+ @NonNull private final List<TimeModel> mTimeModels;
+
+ /** The list of QZSS ephemeris. */
+ @NonNull private final List<QzssSatelliteEphemeris> mSatelliteEphemeris;
+
+ /** The list of real time integrity models. */
+ @NonNull private final List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+
+ /** The list of QZSS satellite corrections. */
+ @NonNull private final List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+ private QzssAssistance(Builder builder) {
+ mAlmanac = builder.mAlmanac;
+ mIonosphericModel = builder.mIonosphericModel;
+ mUtcModel = builder.mUtcModel;
+ mLeapSecondsModel = builder.mLeapSecondsModel;
+ if (builder.mTimeModels != null) {
+ mTimeModels = Collections.unmodifiableList(new ArrayList<>(builder.mTimeModels));
+ } else {
+ mTimeModels = new ArrayList<>();
+ }
+ if (builder.mSatelliteEphemeris != null) {
+ mSatelliteEphemeris =
+ Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteEphemeris));
+ } else {
+ mSatelliteEphemeris = new ArrayList<>();
+ }
+ if (builder.mRealTimeIntegrityModels != null) {
+ mRealTimeIntegrityModels =
+ Collections.unmodifiableList(new ArrayList<>(builder.mRealTimeIntegrityModels));
+ } else {
+ mRealTimeIntegrityModels = new ArrayList<>();
+ }
+ if (builder.mSatelliteCorrections != null) {
+ mSatelliteCorrections =
+ Collections.unmodifiableList(new ArrayList<>(builder.mSatelliteCorrections));
+ } else {
+ mSatelliteCorrections = new ArrayList<>();
+ }
+ }
+
+ /** Returns the QZSS almanac. */
+ @Nullable
+ public GnssAlmanac getAlmanac() {
+ return mAlmanac;
+ }
+
+ /** Returns the Klobuchar ionospheric model. */
+ @Nullable
+ public KlobucharIonosphericModel getIonosphericModel() {
+ return mIonosphericModel;
+ }
+
+ /** Returns the UTC model. */
+ @Nullable
+ public UtcModel getUtcModel() {
+ return mUtcModel;
+ }
+
+ /** Returns the leap seconds model. */
+ @Nullable
+ public LeapSecondsModel getLeapSecondsModel() {
+ return mLeapSecondsModel;
+ }
+
+ /** Returns the list of time models. */
+ @NonNull
+ public List<TimeModel> getTimeModels() {
+ return mTimeModels;
+ }
+
+ /** Returns the list of QZSS ephemeris. */
+ @NonNull
+ public List<QzssSatelliteEphemeris> getSatelliteEphemeris() {
+ return mSatelliteEphemeris;
+ }
+
+ /** Returns the list of real time integrity models. */
+ @NonNull
+ public List<RealTimeIntegrityModel> getRealTimeIntegrityModels() {
+ return mRealTimeIntegrityModels;
+ }
+
+ /** Returns the list of QZSS satellite corrections. */
+ @NonNull
+ public List<GnssSatelliteCorrections> getSatelliteCorrections() {
+ return mSatelliteCorrections;
+ }
+
+ public static final @NonNull Creator<QzssAssistance> CREATOR =
+ new Creator<QzssAssistance>() {
+ @Override
+ @NonNull
+ public QzssAssistance createFromParcel(Parcel in) {
+ return new QzssAssistance.Builder()
+ .setAlmanac(in.readTypedObject(GnssAlmanac.CREATOR))
+ .setIonosphericModel(in.readTypedObject(KlobucharIonosphericModel.CREATOR))
+ .setUtcModel(in.readTypedObject(UtcModel.CREATOR))
+ .setLeapSecondsModel(in.readTypedObject(LeapSecondsModel.CREATOR))
+ .setTimeModels(in.createTypedArrayList(TimeModel.CREATOR))
+ .setSatelliteEphemeris(
+ in.createTypedArrayList(QzssSatelliteEphemeris.CREATOR))
+ .setRealTimeIntegrityModels(
+ in.createTypedArrayList(RealTimeIntegrityModel.CREATOR))
+ .setSatelliteCorrections(
+ in.createTypedArrayList(GnssSatelliteCorrections.CREATOR))
+ .build();
+ }
+ @Override
+ public QzssAssistance[] newArray(int size) {
+ return new QzssAssistance[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeTypedObject(mAlmanac, flags);
+ dest.writeTypedObject(mIonosphericModel, flags);
+ dest.writeTypedObject(mUtcModel, flags);
+ dest.writeTypedObject(mLeapSecondsModel, flags);
+ dest.writeTypedList(mTimeModels);
+ dest.writeTypedList(mSatelliteEphemeris);
+ dest.writeTypedList(mRealTimeIntegrityModels);
+ dest.writeTypedList(mSatelliteCorrections);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("QzssAssistance[");
+ builder.append("almanac = ").append(mAlmanac);
+ builder.append(", ionosphericModel = ").append(mIonosphericModel);
+ builder.append(", utcModel = ").append(mUtcModel);
+ builder.append(", leapSecondsModel = ").append(mLeapSecondsModel);
+ builder.append(", timeModels = ").append(mTimeModels);
+ builder.append(", satelliteEphemeris = ").append(mSatelliteEphemeris);
+ builder.append(", realTimeIntegrityModels = ").append(mRealTimeIntegrityModels);
+ builder.append(", satelliteCorrections = ").append(mSatelliteCorrections);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link QzssAssistance}. */
+ public static final class Builder {
+ private GnssAlmanac mAlmanac;
+ private KlobucharIonosphericModel mIonosphericModel;
+ private UtcModel mUtcModel;
+ private LeapSecondsModel mLeapSecondsModel;
+ private List<TimeModel> mTimeModels;
+ private List<QzssSatelliteEphemeris> mSatelliteEphemeris;
+ private List<RealTimeIntegrityModel> mRealTimeIntegrityModels;
+ private List<GnssSatelliteCorrections> mSatelliteCorrections;
+
+ /** Sets the QZSS almanac. */
+ @NonNull
+ public Builder setAlmanac(@Nullable GnssAlmanac almanac) {
+ mAlmanac = almanac;
+ return this;
+ }
+
+ /** Sets the Klobuchar ionospheric model. */
+ @NonNull
+ public Builder setIonosphericModel(@Nullable KlobucharIonosphericModel ionosphericModel) {
+ mIonosphericModel = ionosphericModel;
+ return this;
+ }
+
+ /** Sets the UTC model. */
+ @NonNull
+ public Builder setUtcModel(@Nullable UtcModel utcModel) {
+ mUtcModel = utcModel;
+ return this;
+ }
+
+ /** Sets the leap seconds model. */
+ @NonNull
+ public Builder setLeapSecondsModel(@Nullable LeapSecondsModel leapSecondsModel) {
+ mLeapSecondsModel = leapSecondsModel;
+ return this;
+ }
+
+ /** Sets the list of time models. */
+ @NonNull
+ public Builder setTimeModels(
+ @Nullable @SuppressLint("NullableCollection") List<TimeModel> timeModels) {
+ mTimeModels = timeModels;
+ return this;
+ }
+
+ /** Sets the list of QZSS ephemeris. */
+ @NonNull
+ public Builder setSatelliteEphemeris(
+ @Nullable @SuppressLint("NullableCollection")
+ List<QzssSatelliteEphemeris> satelliteEphemeris) {
+ mSatelliteEphemeris = satelliteEphemeris;
+ return this;
+ }
+
+ /** Sets the list of real time integrity model. */
+ @NonNull
+ public Builder setRealTimeIntegrityModels(
+ @Nullable @SuppressLint("NullableCollection")
+ List<RealTimeIntegrityModel> realTimeIntegrityModels) {
+ mRealTimeIntegrityModels = realTimeIntegrityModels;
+ return this;
+ }
+
+ /** Sets the list of QZSS satellite correction. */
+ @NonNull
+ public Builder setSatelliteCorrections(
+ @Nullable @SuppressLint("NullableCollection")
+ List<GnssSatelliteCorrections> satelliteCorrections) {
+ mSatelliteCorrections = satelliteCorrections;
+ return this;
+ }
+
+ /** Builds a {@link QzssAssistance} instance as specified by this builder. */
+ @NonNull
+ public QzssAssistance build() {
+ return new QzssAssistance(this);
+ }
+ }
+}
diff --git a/location/java/android/location/QzssSatelliteEphemeris.java b/location/java/android/location/QzssSatelliteEphemeris.java
new file mode 100644
index 0000000..96203d9
--- /dev/null
+++ b/location/java/android/location/QzssSatelliteEphemeris.java
@@ -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.
+ */
+
+package android.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.GpsSatelliteEphemeris.GpsL2Params;
+import android.location.GpsSatelliteEphemeris.GpsSatelliteClockModel;
+import android.location.GpsSatelliteEphemeris.GpsSatelliteHealth;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains ephemeris parameters specific to QZSS satellites.
+ *
+ * <p>This is defined in IS-QZSS-PNT section 4.1.2.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class QzssSatelliteEphemeris implements Parcelable {
+ /** Satellite PRN. */
+ private final int mPrn;
+
+ /** L2 parameters. */
+ @NonNull private final GpsL2Params mGpsL2Params;
+
+ /** Clock model. */
+ @NonNull private final GpsSatelliteClockModel mSatelliteClockModel;
+
+ /** Orbit model. */
+ @NonNull private final KeplerianOrbitModel mSatelliteOrbitModel;
+
+ /** Satellite health. */
+ @NonNull private final GpsSatelliteHealth mSatelliteHealth;
+
+ /** Ephemeris time. */
+ @NonNull private final SatelliteEphemerisTime mSatelliteEphemerisTime;
+
+ /** Returns the PRN of the satellite. */
+ @IntRange(from = 183, to = 206)
+ public int getPrn() {
+ return mPrn;
+ }
+
+ /** Returns the L2 parameters of the satellite. */
+ @NonNull
+ public GpsL2Params getGpsL2Params() {
+ return mGpsL2Params;
+ }
+
+ /** Returns the clock model of the satellite. */
+ @NonNull
+ public GpsSatelliteClockModel getSatelliteClockModel() {
+ return mSatelliteClockModel;
+ }
+
+ /** Returns the orbit model of the satellite. */
+ @NonNull
+ public KeplerianOrbitModel getSatelliteOrbitModel() {
+ return mSatelliteOrbitModel;
+ }
+
+ /** Returns the satellite health. */
+ @NonNull
+ public GpsSatelliteHealth getSatelliteHealth() {
+ return mSatelliteHealth;
+ }
+
+ /** Returns the ephemeris time. */
+ @NonNull
+ public SatelliteEphemerisTime getSatelliteEphemerisTime() {
+ return mSatelliteEphemerisTime;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mPrn);
+ parcel.writeTypedObject(mGpsL2Params, flags);
+ parcel.writeTypedObject(mSatelliteClockModel, flags);
+ parcel.writeTypedObject(mSatelliteOrbitModel, flags);
+ parcel.writeTypedObject(mSatelliteHealth, flags);
+ parcel.writeTypedObject(mSatelliteEphemerisTime, flags);
+ }
+
+ private QzssSatelliteEphemeris(Builder builder) {
+ // Allow PRN beyond the range to support potential future extensibility.
+ Preconditions.checkArgument(builder.mPrn >= 1);
+ Preconditions.checkNotNull(builder.mGpsL2Params, "GpsL2Params cannot be null");
+ Preconditions.checkNotNull(builder.mSatelliteClockModel,
+ "SatelliteClockModel cannot be null");
+ Preconditions.checkNotNull(builder.mSatelliteOrbitModel,
+ "SatelliteOrbitModel cannot be null");
+ Preconditions.checkNotNull(builder.mSatelliteHealth,
+ "SatelliteHealth cannot be null");
+ Preconditions.checkNotNull(builder.mSatelliteEphemerisTime,
+ "SatelliteEphemerisTime cannot be null");
+ mPrn = builder.mPrn;
+ mGpsL2Params = builder.mGpsL2Params;
+ mSatelliteClockModel = builder.mSatelliteClockModel;
+ mSatelliteOrbitModel = builder.mSatelliteOrbitModel;
+ mSatelliteHealth = builder.mSatelliteHealth;
+ mSatelliteEphemerisTime = builder.mSatelliteEphemerisTime;
+ }
+
+ public static final @NonNull Creator<QzssSatelliteEphemeris> CREATOR =
+ new Creator<QzssSatelliteEphemeris>() {
+ @Override
+ @NonNull
+ public QzssSatelliteEphemeris createFromParcel(Parcel in) {
+ final QzssSatelliteEphemeris.Builder qzssSatelliteEphemeris =
+ new Builder()
+ .setPrn(in.readInt())
+ .setGpsL2Params(in.readTypedObject(GpsL2Params.CREATOR))
+ .setSatelliteClockModel(
+ in.readTypedObject(GpsSatelliteClockModel.CREATOR))
+ .setSatelliteOrbitModel(
+ in.readTypedObject(KeplerianOrbitModel.CREATOR))
+ .setSatelliteHealth(
+ in.readTypedObject(GpsSatelliteHealth.CREATOR))
+ .setSatelliteEphemerisTime(
+ in.readTypedObject(SatelliteEphemerisTime.CREATOR));
+ return qzssSatelliteEphemeris.build();
+ }
+
+ @Override
+ public QzssSatelliteEphemeris[] newArray(int size) {
+ return new QzssSatelliteEphemeris[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("QzssSatelliteEphemeris[");
+ builder.append("prn=").append(mPrn);
+ builder.append(", gpsL2Params=").append(mGpsL2Params);
+ builder.append(", satelliteClockModel=").append(mSatelliteClockModel);
+ builder.append(", satelliteOrbitModel=").append(mSatelliteOrbitModel);
+ builder.append(", satelliteHealth=").append(mSatelliteHealth);
+ builder.append(", satelliteEphemerisTime=").append(mSatelliteEphemerisTime);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link QzssSatelliteEphemeris}. */
+ public static final class Builder {
+ private int mPrn;
+ private GpsL2Params mGpsL2Params;
+ private GpsSatelliteClockModel mSatelliteClockModel;
+ private KeplerianOrbitModel mSatelliteOrbitModel;
+ private GpsSatelliteHealth mSatelliteHealth;
+ private SatelliteEphemerisTime mSatelliteEphemerisTime;
+
+ /** Sets the PRN of the satellite. */
+ @NonNull
+ public Builder setPrn(@IntRange(from = 183, to = 206) int prn) {
+ mPrn = prn;
+ return this;
+ }
+
+ /** Sets the L2 parameters of the satellite. */
+ @NonNull
+ public Builder setGpsL2Params(@NonNull GpsL2Params gpsL2Params) {
+ mGpsL2Params = gpsL2Params;
+ return this;
+ }
+
+ /** Sets the clock model of the satellite. */
+ @NonNull
+ public Builder setSatelliteClockModel(@NonNull GpsSatelliteClockModel satelliteClockModel) {
+ mSatelliteClockModel = satelliteClockModel;
+ return this;
+ }
+
+ /** Sets the orbit model of the satellite. */
+ @NonNull
+ public Builder setSatelliteOrbitModel(@NonNull KeplerianOrbitModel satelliteOrbitModel) {
+ mSatelliteOrbitModel = satelliteOrbitModel;
+ return this;
+ }
+
+ /** Sets the satellite health. */
+ @NonNull
+ public Builder setSatelliteHealth(@NonNull GpsSatelliteHealth satelliteHealth) {
+ mSatelliteHealth = satelliteHealth;
+ return this;
+ }
+
+ /** Sets the ephemeris time. */
+ @NonNull
+ public Builder setSatelliteEphemerisTime(
+ @NonNull SatelliteEphemerisTime satelliteEphemerisTime) {
+ mSatelliteEphemerisTime = satelliteEphemerisTime;
+ return this;
+ }
+
+ /** Builds a {@link QzssSatelliteEphemeris} instance as specified by this builder. */
+ @NonNull
+ public QzssSatelliteEphemeris build() {
+ return new QzssSatelliteEphemeris(this);
+ }
+ }
+}
diff --git a/location/java/android/location/RealTimeIntegrityModel.java b/location/java/android/location/RealTimeIntegrityModel.java
new file mode 100644
index 0000000..d268926
--- /dev/null
+++ b/location/java/android/location/RealTimeIntegrityModel.java
@@ -0,0 +1,284 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains the real time integrity status of a GNSS satellite based on notice advisory.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class RealTimeIntegrityModel implements Parcelable {
+ /**
+ * Pseudo-random or satellite ID number for the satellite,
+ * a.k.a. Space Vehicle (SV), or OSN number for Glonass.
+ *
+ * <p>The distinction is made by looking at the constellation field. Values
+ * must be in the range of:
+ *
+ * <p> - GPS: 1-32
+ * <p> - GLONASS: 1-25
+ * <p> - QZSS: 183-206
+ * <p> - Galileo: 1-36
+ * <p> - Beidou: 1-63
+ */
+ private final int mSvid;
+
+ /** Indicates whether the satellite is currently usable for navigation. */
+ private final boolean mUsable;
+
+ /** UTC timestamp (in seconds) when the advisory was published. */
+ private final long mPublishDateSeconds;
+
+ /** UTC timestamp (in seconds) for the start of the event. */
+ private final long mStartDateSeconds;
+
+ /** UTC timestamp (in seconds) for the end of the event. */
+ private final long mEndDateSeconds;
+
+ /**
+ * Abbreviated type of the advisory, providing a concise summary of the event.
+ *
+ * <p>This field follows different definitions depending on the GNSS constellation:
+ * <p> - GPS: See NANU type definitions(https://www.navcen.uscg.gov/nanu-abbreviations-and-descriptions)
+ * <p> - Galileo: See NAGU type definitions(https://www.gsc-europa.eu/system-service-status/nagu-information)
+ * <p> - QZSS: See NAQU type definitions](https://sys.qzss.go.jp/dod/en/naqu/type.html)
+ * <p> - BeiDou: Not used; set to an empty string.
+ */
+ @NonNull private final String mAdvisoryType;
+
+ /**
+ * Unique identifier for the advisory within its constellation's system.
+ *
+ * <p>For BeiDou, this is not used and should be an empty string.
+ */
+ @NonNull private final String mAdvisoryNumber;
+
+ private RealTimeIntegrityModel(Builder builder) {
+ // Allow SV ID beyond the range to support potential future extensibility.
+ Preconditions.checkArgument(builder.mSvid >= 1);
+ Preconditions.checkArgument(builder.mPublishDateSeconds > 0);
+ Preconditions.checkArgument(builder.mStartDateSeconds > 0);
+ Preconditions.checkArgument(builder.mEndDateSeconds > 0);
+ Preconditions.checkNotNull(builder.mAdvisoryType, "AdvisoryType cannot be null");
+ Preconditions.checkNotNull(builder.mAdvisoryNumber, "AdvisoryNumber cannot be null");
+ mSvid = builder.mSvid;
+ mUsable = builder.mUsable;
+ mPublishDateSeconds = builder.mPublishDateSeconds;
+ mStartDateSeconds = builder.mStartDateSeconds;
+ mEndDateSeconds = builder.mEndDateSeconds;
+ mAdvisoryType = builder.mAdvisoryType;
+ mAdvisoryNumber = builder.mAdvisoryNumber;
+ }
+
+ /**
+ * Returns the Pseudo-random or satellite ID number for the satellite,
+ * a.k.a. Space Vehicle (SV), or OSN number for Glonass.
+ *
+ * <p>The distinction is made by looking at the constellation field. Values
+ * must be in the range of:
+ *
+ * <p> - GPS: 1-32
+ * <p> - GLONASS: 1-25
+ * <p> - QZSS: 183-206
+ * <p> - Galileo: 1-36
+ * <p> - Beidou: 1-63
+ */
+ @IntRange(from = 1, to = 206)
+ public int getSvid() {
+ return mSvid;
+ }
+
+ /** Returns whether the satellite is usable or not. */
+ public boolean isUsable() {
+ return mUsable;
+ }
+
+ /** Returns the UTC timestamp (in seconds) when the advisory was published */
+ @IntRange(from = 0)
+ public long getPublishDateSeconds() {
+ return mPublishDateSeconds;
+ }
+
+ /** Returns UTC timestamp (in seconds) for the start of the event. */
+ @IntRange(from = 0)
+ public long getStartDateSeconds() {
+ return mStartDateSeconds;
+ }
+
+ /** Returns UTC timestamp (in seconds) for the end of the event. */
+ @IntRange(from = 0)
+ public long getEndDateSeconds() {
+ return mEndDateSeconds;
+ }
+
+ /** Returns the abbreviated type of notice advisory. */
+ @NonNull
+ public String getAdvisoryType() {
+ return mAdvisoryType;
+ }
+
+ /** Returns the unique identifier for the advisory. */
+ @NonNull
+ public String getAdvisoryNumber() {
+ return mAdvisoryNumber;
+ }
+
+ public static final @NonNull Creator<RealTimeIntegrityModel> CREATOR =
+ new Creator<RealTimeIntegrityModel>() {
+ @Override
+ @NonNull
+ public RealTimeIntegrityModel createFromParcel(Parcel in) {
+ RealTimeIntegrityModel realTimeIntegrityModel =
+ new RealTimeIntegrityModel.Builder()
+ .setSvid(in.readInt())
+ .setUsable(in.readBoolean())
+ .setPublishDateSeconds(in.readLong())
+ .setStartDateSeconds(in.readLong())
+ .setEndDateSeconds(in.readLong())
+ .setAdvisoryType(in.readString8())
+ .setAdvisoryNumber(in.readString8())
+ .build();
+ return realTimeIntegrityModel;
+ }
+
+ @Override
+ public RealTimeIntegrityModel[] newArray(int size) {
+ return new RealTimeIntegrityModel[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mSvid);
+ parcel.writeBoolean(mUsable);
+ parcel.writeLong(mPublishDateSeconds);
+ parcel.writeLong(mStartDateSeconds);
+ parcel.writeLong(mEndDateSeconds);
+ parcel.writeString8(mAdvisoryType);
+ parcel.writeString8(mAdvisoryNumber);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("RealTimeIntegrityModel[");
+ builder.append("svid = ").append(mSvid);
+ builder.append(", usable = ").append(mUsable);
+ builder.append(", publishDateSeconds = ").append(mPublishDateSeconds);
+ builder.append(", startDateSeconds = ").append(mStartDateSeconds);
+ builder.append(", endDateSeconds = ").append(mEndDateSeconds);
+ builder.append(", advisoryType = ").append(mAdvisoryType);
+ builder.append(", advisoryNumber = ").append(mAdvisoryNumber);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link RealTimeIntegrityModel} */
+ public static final class Builder {
+ private int mSvid;
+ private boolean mUsable;
+ private long mPublishDateSeconds;
+ private long mStartDateSeconds;
+ private long mEndDateSeconds;
+ private String mAdvisoryType;
+ private String mAdvisoryNumber;
+
+ /**
+ * Sets the Pseudo-random or satellite ID number for the satellite,
+ * a.k.a. Space Vehicle (SV), or OSN number for Glonass.
+ *
+ * <p>The distinction is made by looking at the constellation field. Values
+ * must be in the range of:
+ *
+ * <p> - GPS: 1-32
+ * <p> - GLONASS: 1-25
+ * <p> - QZSS: 183-206
+ * <p> - Galileo: 1-36
+ * <p> - Beidou: 1-63
+ */
+ @NonNull
+ public Builder setSvid(@IntRange(from = 1, to = 206) int svid) {
+ mSvid = svid;
+ return this;
+ }
+
+ /** Sets whether the satellite is usable or not. */
+ @NonNull
+ public Builder setUsable(boolean usable) {
+ mUsable = usable;
+ return this;
+ }
+
+ /** Sets the UTC timestamp (in seconds) when the advisory was published. */
+ @NonNull
+ public Builder setPublishDateSeconds(@IntRange(from = 0) long publishDateSeconds) {
+ mPublishDateSeconds = publishDateSeconds;
+ return this;
+ }
+
+ /** Sets the UTC timestamp (in seconds) for the start of the event. */
+ @NonNull
+ public Builder setStartDateSeconds(@IntRange(from = 0) long startDateSeconds) {
+ mStartDateSeconds = startDateSeconds;
+ return this;
+ }
+
+ /** Sets the UTC timestamp (in seconds) for the end of the event. */
+ @NonNull
+ public Builder setEndDateSeconds(@IntRange(from = 0) long endDateSeconds) {
+ mEndDateSeconds = endDateSeconds;
+ return this;
+ }
+
+ /** Sets the abbreviated type of notice advisory. */
+ @NonNull
+ public Builder setAdvisoryType(@NonNull String advisoryType) {
+ mAdvisoryType = advisoryType;
+ return this;
+ }
+
+ /** Sets the unique identifier for the advisory. */
+ @NonNull
+ public Builder setAdvisoryNumber(@NonNull String advisoryNumber) {
+ mAdvisoryNumber = advisoryNumber;
+ return this;
+ }
+
+ /** Builds a {@link RealTimeIntegrityModel} instance as specified by this builder. */
+ @NonNull
+ public RealTimeIntegrityModel build() {
+ return new RealTimeIntegrityModel(this);
+ }
+ }
+}
diff --git a/location/java/android/location/SatelliteEphemerisTime.java b/location/java/android/location/SatelliteEphemerisTime.java
new file mode 100644
index 0000000..0ab3acf
--- /dev/null
+++ b/location/java/android/location/SatelliteEphemerisTime.java
@@ -0,0 +1,151 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains time of ephemeris for GPS, Galileo, and QZSS.
+ *
+ * <p>For GPS, this is defined in IS-GPS-200, section 20.3.3.4.1.
+ * <p>For Galileo, this is defined in Galileo-OS-SIS-ICD, section 5.1.2, 5.1.9.2.
+ * <p>For QZSS, this is defined in IS-QZSS-200, section 4.1.2.4.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class SatelliteEphemerisTime implements Parcelable {
+ /** The issue of ephemeris data. */
+ private final int mIode;
+
+ /** The satellite week number without rollover. */
+ private final int mWeekNumber;
+
+ /** The broadcast time of ephemeris in GNSS time of week in seconds. */
+ private final int mToeSeconds;
+
+ private SatelliteEphemerisTime(Builder builder) {
+ Preconditions.checkArgumentInRange(builder.mIode, 0, 1023, "Iode");
+ Preconditions.checkArgument(builder.mWeekNumber >= 0);
+ Preconditions.checkArgumentInRange(builder.mToeSeconds, 0, 604799, "ToeSeconds");
+ mIode = builder.mIode;
+ mWeekNumber = builder.mWeekNumber;
+ mToeSeconds = builder.mToeSeconds;
+ }
+
+ /** Returns the issue of ephemeris data. */
+ @IntRange(from = 0, to = 1023)
+ public int getIode() {
+ return mIode;
+ }
+
+ /** Returns the satellite week number without rollover. */
+ @IntRange(from = 0)
+ public int getWeekNumber() {
+ return mWeekNumber;
+ }
+
+ /** Returns the broadcast time of ephemeris in GNSS time of week in seconds. */
+ @IntRange(from = 0, to = 604799)
+ public int getToeSeconds() {
+ return mToeSeconds;
+ }
+
+ public static final @NonNull Creator<SatelliteEphemerisTime> CREATOR =
+ new Creator<SatelliteEphemerisTime>() {
+ @Override
+ public SatelliteEphemerisTime createFromParcel(Parcel in) {
+ final SatelliteEphemerisTime.Builder satelliteEphemerisTime =
+ new Builder()
+ .setIode(in.readInt())
+ .setWeekNumber(in.readInt())
+ .setToeSeconds(in.readInt());
+ return satelliteEphemerisTime.build();
+ }
+
+ @Override
+ public SatelliteEphemerisTime[] newArray(int size) {
+ return new SatelliteEphemerisTime[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeInt(mIode);
+ parcel.writeInt(mWeekNumber);
+ parcel.writeInt(mToeSeconds);
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("SatelliteEphemerisTime[");
+ builder.append("iode = ").append(mIode);
+ builder.append(", weekNumber = ").append(mWeekNumber);
+ builder.append(", toeSeconds = ").append(mToeSeconds);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /** Builder for {@link SatelliteEphemerisTime}. */
+ public static final class Builder {
+ private int mIode;
+ private int mWeekNumber;
+ private int mToeSeconds;
+
+ /** Sets the issue of ephemeris data. */
+ @NonNull
+ public Builder setIode(@IntRange(from = 0, to = 1023) int iode) {
+ mIode = iode;
+ return this;
+ }
+
+ /** Sets the satellite week number without rollover. */
+ @NonNull
+ public Builder setWeekNumber(@IntRange(from = 0) int weekNumber) {
+ mWeekNumber = weekNumber;
+ return this;
+ }
+
+ /** Sets the broadcast time of ephemeris in GNSS time of week in seconds. */
+ @NonNull
+ public Builder setToeSeconds(@IntRange(from = 0, to = 604799) int toeSeconds) {
+ mToeSeconds = toeSeconds;
+ return this;
+ }
+
+ /** Builds a {@link SatelliteEphemerisTime} instance as specified by this builder. */
+ @NonNull
+ public SatelliteEphemerisTime build() {
+ return new SatelliteEphemerisTime(this);
+ }
+ }
+}
diff --git a/location/java/android/location/TimeModel.java b/location/java/android/location/TimeModel.java
new file mode 100644
index 0000000..380f7b8
--- /dev/null
+++ b/location/java/android/location/TimeModel.java
@@ -0,0 +1,208 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.GnssStatus.ConstellationType;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains the GNSS-GNSS system time offset between the GNSS system time.
+ *
+ * <p>This is defined in IS-GPS-200 section 30.3.3.8.2.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class TimeModel implements Parcelable {
+ /*
+ * Model represents parameters to convert from current GNSS to GNSS system
+ * time indicated by toGnss.
+ */
+ private final @ConstellationType int mToGnss;
+
+ /** Bias coefficient of GNSS time scale relative to GNSS time scale in seconds. */
+ private final double mA0;
+
+ /** Drift coefficient of GNSS time scale relative to GNSS time scale in seconds per second. */
+ private final double mA1;
+
+ /** GNSS time of week in seconds. */
+ private final int mTimeOfWeek;
+
+ /** Week number of the GNSS time. */
+ private final int mWeekNumber;
+
+ private TimeModel(Builder builder) {
+ Preconditions.checkArgumentInRange(
+ builder.mToGnss,
+ GnssStatus.CONSTELLATION_UNKNOWN,
+ GnssStatus.CONSTELLATION_COUNT,
+ "ToGnss");
+ Preconditions.checkArgumentInRange(builder.mA0, -1.0f, 1.0f, "A0");
+ Preconditions.checkArgumentInRange(builder.mA1, -3.28e-6f, 3.28e-6f, "A1");
+ Preconditions.checkArgumentInRange(builder.mTimeOfWeek, 0, 604800, "TimeOfWeek");
+ Preconditions.checkArgument(builder.mWeekNumber >= 0);
+ mToGnss = builder.mToGnss;
+ mA0 = builder.mA0;
+ mA1 = builder.mA1;
+ mTimeOfWeek = builder.mTimeOfWeek;
+ mWeekNumber = builder.mWeekNumber;
+ }
+
+ /** Returns the constellation type to convert from current GNSS system time. */
+ @ConstellationType
+ public int getToGnss() {
+ return mToGnss;
+ }
+
+ /** Returns the bias coefficient of GNSS time scale relative to GNSS time scale in seconds. */
+ @FloatRange(from = -1.0f, to = 1.0f)
+ public double getA0() {
+ return mA0;
+ }
+
+ /**
+ * Returns the drift coefficient of GNSS time scale relative to GNSS time scale in seconds per
+ * second.
+ */
+ @FloatRange(from = -3.28e-6f, to = 3.28e-6f)
+ public double getA1() {
+ return mA1;
+ }
+
+ /** Returns the GNSS time of week in seconds. */
+ @IntRange(from = 0, to = 604800)
+ public int getTimeOfWeek() {
+ return mTimeOfWeek;
+ }
+
+ /** Returns the week number of the GNSS time. */
+ @IntRange(from = 0)
+ public int getWeekNumber() {
+ return mWeekNumber;
+ }
+
+ public static final @NonNull Creator<TimeModel> CREATOR =
+ new Creator<TimeModel>() {
+ @Override
+ public TimeModel createFromParcel(@NonNull Parcel source) {
+ return new TimeModel.Builder()
+ .setToGnss(source.readInt())
+ .setA0(source.readDouble())
+ .setA1(source.readDouble())
+ .setTimeOfWeek(source.readInt())
+ .setWeekNumber(source.readInt())
+ .build();
+ }
+
+ @Override
+ public TimeModel[] newArray(int size) {
+ return new TimeModel[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("TimeModel[");
+ builder.append("toGnss = ").append(mToGnss);
+ builder.append(", a0 = ").append(mA0);
+ builder.append(", a1 = ").append(mA1);
+ builder.append(", timeOfWeek = ").append(mTimeOfWeek);
+ builder.append(", weekNumber = ").append(mWeekNumber);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mToGnss);
+ dest.writeDouble(mA0);
+ dest.writeDouble(mA1);
+ dest.writeInt(mTimeOfWeek);
+ dest.writeInt(mWeekNumber);
+ }
+
+ /** Builder for {@link TimeModel} */
+ public static final class Builder {
+
+ private @ConstellationType int mToGnss;
+ private double mA0;
+ private double mA1;
+ private int mTimeOfWeek;
+ private int mWeekNumber;
+
+ /** Sets the constellation type to convert from current GNSS system time. */
+ @NonNull
+ public Builder setToGnss(@ConstellationType int toGnss) {
+ mToGnss = toGnss;
+ return this;
+ }
+
+ /** Sets the bias coefficient of GNSS time scale relative to GNSS time scale in seconds. */
+ @NonNull
+ public Builder setA0(@FloatRange(from = -1.0f, to = 1.0f) double a0) {
+ mA0 = a0;
+ return this;
+ }
+
+ /**
+ * Sets the drift coefficient of GNSS time scale relative to GNSS time scale in seconds per
+ * second.
+ */
+ @NonNull
+ public Builder setA1(@FloatRange(from = -3.28e-6f, to = 3.28e-6f) double a1) {
+ mA1 = a1;
+ return this;
+ }
+
+ /** Sets the GNSS time of week in seconds. */
+ @NonNull
+ public Builder setTimeOfWeek(@IntRange(from = 0, to = 604800) int timeOfWeek) {
+ mTimeOfWeek = timeOfWeek;
+ return this;
+ }
+
+ /** Sets the week number of the GNSS time. */
+ @NonNull
+ public Builder setWeekNumber(@IntRange(from = 0) int weekNumber) {
+ mWeekNumber = weekNumber;
+ return this;
+ }
+
+ /** Builds the {@link TimeModel} object. */
+ @NonNull
+ public TimeModel build() {
+ return new TimeModel(this);
+ }
+ }
+}
diff --git a/location/java/android/location/UtcModel.java b/location/java/android/location/UtcModel.java
new file mode 100644
index 0000000..6dc633d
--- /dev/null
+++ b/location/java/android/location/UtcModel.java
@@ -0,0 +1,176 @@
+/*
+ * 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.location;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.location.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class contains parameters to convert from current GNSS time to UTC time.
+ *
+ * <p>This is defined in RINEX 3.05 "TIME SYSTEM CORR" in table A5.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
+@SystemApi
+public final class UtcModel implements Parcelable {
+ /** Bias coefficient of GNSS time scale relative to UTC time scale in seconds. */
+ private final double mA0;
+
+ /** Drift coefficient of GNSS time scale relative to UTC time scale in seconds per second. */
+ private final double mA1;
+
+ /** Reference GNSS time of week in seconds. */
+ private final int mTimeOfWeek;
+
+ /** Reference GNSS week number. */
+ private final int mWeekNumber;
+
+ private UtcModel(Builder builder) {
+ Preconditions.checkArgumentInRange(builder.mA0, -2.0f, 2.0f, "A0");
+ Preconditions.checkArgumentInRange(builder.mA1, -7.45e-9f, 7.45e-9f, "A1");
+ Preconditions.checkArgumentInRange(builder.mTimeOfWeek, 0, 604800, "TimeOfWeek");
+ Preconditions.checkArgument(builder.mWeekNumber >= 0);
+ mA0 = builder.mA0;
+ mA1 = builder.mA1;
+ mTimeOfWeek = builder.mTimeOfWeek;
+ mWeekNumber = builder.mWeekNumber;
+ }
+
+ /** Returns the bias coefficient of GNSS time scale relative to UTC time scale in seconds. */
+ @FloatRange(from = -2.0f, to = 2.0f)
+ public double getA0() {
+ return mA0;
+ }
+
+ /**
+ * Returns the drift coefficient of GNSS time scale relative to UTC time scale in seconds per
+ * second.
+ */
+ @FloatRange(from = -7.45e-9f, to = 7.45e-9f)
+ public double getA1() {
+ return mA1;
+ }
+
+ /** Returns the reference GNSS time of week in seconds. */
+ @IntRange(from = 0, to = 604800)
+ public int getTimeOfWeek() {
+ return mTimeOfWeek;
+ }
+
+ /** Returns the reference GNSS week number. */
+ @IntRange(from = 0)
+ public int getWeekNumber() {
+ return mWeekNumber;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ @Override
+ @NonNull
+ public String toString() {
+ StringBuilder builder = new StringBuilder("UtcModel[");
+ builder.append("a0 = ").append(mA0);
+ builder.append(", a1 = ").append(mA1);
+ builder.append(", timeOfWeek = ").append(mTimeOfWeek);
+ builder.append(", weekNumber = ").append(mWeekNumber);
+ builder.append("]");
+ return builder.toString();
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeDouble(mA0);
+ dest.writeDouble(mA1);
+ dest.writeInt(mTimeOfWeek);
+ dest.writeInt(mWeekNumber);
+ }
+
+ public static final @NonNull Creator<UtcModel> CREATOR =
+ new Creator<UtcModel>() {
+ @Override
+ public UtcModel createFromParcel(@NonNull Parcel source) {
+ return new UtcModel.Builder()
+ .setA0(source.readDouble())
+ .setA1(source.readDouble())
+ .setTimeOfWeek(source.readInt())
+ .setWeekNumber(source.readInt())
+ .build();
+ }
+
+ @Override
+ public UtcModel[] newArray(int size) {
+ return new UtcModel[size];
+ }
+ };
+
+ /** Builder for {@link UtcModel}. */
+ public static final class Builder {
+ private double mA0;
+ private double mA1;
+ private int mTimeOfWeek;
+ private int mWeekNumber;
+
+ /** Sets the bias coefficient of GNSS time scale relative to UTC time scale in seconds. */
+ @NonNull
+ public Builder setA0(@FloatRange(from = -2.0f, to = 2.0f) double a0) {
+ mA0 = a0;
+ return this;
+ }
+
+ /**
+ * Sets the drift coefficient of GNSS time scale relative to UTC time scale in seconds per
+ * second.
+ */
+ @NonNull
+ public Builder setA1(@FloatRange(from = -7.45e-9f, to = 7.45e-9f) double a1) {
+ mA1 = a1;
+ return this;
+ }
+
+ /** Sets the reference GNSS time of week in seconds. */
+ @NonNull
+ public Builder setTimeOfWeek(@IntRange(from = 0, to = 604800) int timeOfWeek) {
+ mTimeOfWeek = timeOfWeek;
+ return this;
+ }
+
+ /** Sets the reference GNSS week number. */
+ @NonNull
+ public Builder setWeekNumber(@IntRange(from = 0) int weekNumber) {
+ mWeekNumber = weekNumber;
+ return this;
+ }
+
+ /** Builds a {@link UtcModel} instance as specified by this builder. */
+ @NonNull
+ public UtcModel build() {
+ return new UtcModel(this);
+ }
+ }
+}
diff --git a/location/java/android/location/flags/location.aconfig b/location/java/android/location/flags/location.aconfig
index 5395206..c02cc80 100644
--- a/location/java/android/location/flags/location.aconfig
+++ b/location/java/android/location/flags/location.aconfig
@@ -161,3 +161,10 @@
description: "Flag for gating the density-based coarse locations"
bug: "376198890"
}
+
+flag {
+ name: "gnss_assistance_interface"
+ namespace: "location"
+ description: "Flag for GNSS assistance interface"
+ bug: "209078566"
+}
\ No newline at end of file
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index b41f40f..5689df0 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -548,8 +548,45 @@
return counts;
}
+ /** @hide */
+ @IntDef(flag = true, prefix = "AudioFormat.CHANNEL_OUT_", value = {
+ AudioFormat.CHANNEL_INVALID,
+ AudioFormat.CHANNEL_OUT_DEFAULT,
+ AudioFormat.CHANNEL_OUT_FRONT_LEFT,
+ AudioFormat.CHANNEL_OUT_FRONT_RIGHT,
+ AudioFormat.CHANNEL_OUT_FRONT_CENTER,
+ AudioFormat.CHANNEL_OUT_LOW_FREQUENCY,
+ AudioFormat.CHANNEL_OUT_BACK_LEFT,
+ AudioFormat.CHANNEL_OUT_BACK_RIGHT,
+ AudioFormat.CHANNEL_OUT_FRONT_LEFT_OF_CENTER,
+ AudioFormat.CHANNEL_OUT_FRONT_RIGHT_OF_CENTER,
+ AudioFormat.CHANNEL_OUT_BACK_CENTER,
+ AudioFormat.CHANNEL_OUT_SIDE_LEFT,
+ AudioFormat.CHANNEL_OUT_SIDE_RIGHT,
+ AudioFormat.CHANNEL_OUT_TOP_CENTER,
+ AudioFormat.CHANNEL_OUT_TOP_FRONT_LEFT,
+ AudioFormat.CHANNEL_OUT_TOP_FRONT_CENTER,
+ AudioFormat.CHANNEL_OUT_TOP_FRONT_RIGHT,
+ AudioFormat.CHANNEL_OUT_TOP_BACK_LEFT,
+ AudioFormat.CHANNEL_OUT_TOP_BACK_CENTER,
+ AudioFormat.CHANNEL_OUT_TOP_BACK_RIGHT,
+ AudioFormat.CHANNEL_OUT_TOP_SIDE_LEFT,
+ AudioFormat.CHANNEL_OUT_TOP_SIDE_RIGHT,
+ AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_LEFT,
+ AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_CENTER,
+ AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_RIGHT,
+ AudioFormat.CHANNEL_OUT_LOW_FREQUENCY_2,
+ AudioFormat.CHANNEL_OUT_FRONT_WIDE_LEFT,
+ AudioFormat.CHANNEL_OUT_FRONT_WIDE_RIGHT}
+ )
+ @Retention(RetentionPolicy.SOURCE)
+ @FlaggedApi(FLAG_SPEAKER_LAYOUT_API)
+ public @interface SpeakerLayoutChannelMask {}
+
/**
- * @return A ChannelMask representing the physical output speaker layout of the device.
+ * @return A ChannelMask representing the speaker layout of a TYPE_BUILTIN_SPEAKER device.
+ *
+ * Valid only for speakers built-in to the device.
*
* The layout channel mask only indicates which speaker channels are present, the
* physical layout of the speakers should be informed by a standard for multi-channel
@@ -557,6 +594,7 @@
* @see AudioFormat
*/
@FlaggedApi(FLAG_SPEAKER_LAYOUT_API)
+ @SpeakerLayoutChannelMask
public int getSpeakerLayoutChannelMask() {
return mPort.speakerLayoutChannelMask();
}
diff --git a/media/java/android/media/IMediaRoute2ProviderService.aidl b/media/java/android/media/IMediaRoute2ProviderService.aidl
index eee3d22..714cacb 100644
--- a/media/java/android/media/IMediaRoute2ProviderService.aidl
+++ b/media/java/android/media/IMediaRoute2ProviderService.aidl
@@ -33,6 +33,23 @@
void requestCreateSession(long requestId, String packageName, String routeId,
in @nullable Bundle sessionHints);
+ /**
+ * Requests the creation of a system media routing session.
+ *
+ * @param requestId The id of the request.
+ * @param uid The uid of the package whose media to route, or
+ * {@link android.os.Process#INVALID_UID} if routing should not be restricted to a specific
+ * uid.
+ * @param packageName The name of the package whose media to route.
+ * @param routeId The id of the route to be initially selected.
+ * @param sessionHints An optional bundle with parameters.
+ */
+ void requestCreateSystemMediaSession(
+ long requestId,
+ int uid,
+ String packageName,
+ String routeId,
+ in @nullable Bundle sessionHints);
void selectRoute(long requestId, String sessionId, String routeId);
void deselectRoute(long requestId, String sessionId, String routeId);
void transferToRoute(long requestId, String sessionId, String routeId);
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index a3ad340..037b97a 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -917,6 +917,17 @@
}
/**
+ * Returns whether this route supports routing of the system media.
+ *
+ * @hide
+ */
+ public boolean supportsSystemMediaRouting() {
+ return (mRoutingTypeFlags
+ & (FLAG_ROUTING_TYPE_SYSTEM_VIDEO | FLAG_ROUTING_TYPE_SYSTEM_AUDIO))
+ != 0;
+ }
+
+ /**
* Returns true if the route info has all of the required field.
* A route is valid if and only if it is obtained from
* {@link com.android.server.media.MediaRouterService}.
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
index 547099f..09f40e0 100644
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -18,14 +18,21 @@
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+import static java.util.Objects.requireNonNull;
+
+import android.Manifest;
import android.annotation.CallSuper;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.app.Service;
import android.content.Intent;
+import android.media.audiopolicy.AudioMix;
+import android.media.audiopolicy.AudioMixingRule;
+import android.media.audiopolicy.AudioPolicy;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -36,6 +43,7 @@
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.LongSparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.media.flags.Flags;
@@ -47,7 +55,6 @@
import java.util.Collection;
import java.util.Deque;
import java.util.List;
-import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -83,8 +90,7 @@
public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService";
/**
- * {@link Intent} action that indicates that the declaring service supports routing of the
- * system media.
+ * A category that indicates that the declaring service supports routing of the system media.
*
* <p>Providers must include this action if they intend to publish routes that support the
* system media, as described by {@link MediaRoute2Info#getSupportedRoutingTypes()}.
@@ -94,7 +100,7 @@
*/
// TODO: b/362507305 - Unhide once the implementation and CTS are in place.
@FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
- @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ @SdkConstant(SdkConstant.SdkConstantType.INTENT_CATEGORY)
public static final String SERVICE_INTERFACE_SYSTEM_MEDIA =
"android.media.MediaRoute2ProviderService.SYSTEM_MEDIA";
@@ -165,6 +171,16 @@
@FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
public static final int REASON_UNIMPLEMENTED = 5;
+ /**
+ * The request has failed because the provider has failed to route system media.
+ *
+ * @see #notifyRequestFailed
+ * @hide
+ */
+ // TODO: b/362507305 - Unhide once the implementation and CTS are in place.
+ @FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
+ public static final int REASON_FAILED_TO_REROUTE_SYSTEM_MEDIA = 6;
+
/** @hide */
@IntDef(
prefix = "REASON_",
@@ -174,7 +190,8 @@
REASON_NETWORK_ERROR,
REASON_ROUTE_NOT_AVAILABLE,
REASON_INVALID_COMMAND,
- REASON_UNIMPLEMENTED
+ REASON_UNIMPLEMENTED,
+ REASON_FAILED_TO_REROUTE_SYSTEM_MEDIA
})
@Retention(RetentionPolicy.SOURCE)
public @interface Reason {}
@@ -187,15 +204,28 @@
private final AtomicBoolean mStatePublishScheduled = new AtomicBoolean(false);
private final AtomicBoolean mSessionUpdateScheduled = new AtomicBoolean(false);
private MediaRoute2ProviderServiceStub mStub;
+ /** Populated by system_server in {@link #setCallback}. Monotonically non-null. */
private IMediaRoute2ProviderServiceCallback mRemoteCallback;
private volatile MediaRoute2ProviderInfo mProviderInfo;
@GuardedBy("mRequestIdsLock")
private final Deque<Long> mRequestIds = new ArrayDeque<>(MAX_REQUEST_IDS_SIZE);
+ /**
+ * Maps system media session creation request ids to a package uid whose media to route. The
+ * value may be {@link Process#INVALID_UID} for routing sessions that don't affect a specific
+ * package (for example, if they affect the entire system).
+ */
+ @GuardedBy("mRequestIdsLock")
+ private final LongSparseArray<Integer> mSystemMediaSessionCreationRequests =
+ new LongSparseArray<>();
+
@GuardedBy("mSessionLock")
private final ArrayMap<String, RoutingSessionInfo> mSessionInfos = new ArrayMap<>();
+ @GuardedBy("mSessionLock")
+ private final ArrayMap<String, MediaStreams> mOngoingMediaStreams = new ArrayMap<>();
+
public MediaRoute2ProviderService() {
mHandler = new Handler(Looper.getMainLooper());
}
@@ -282,7 +312,7 @@
*/
public final void notifySessionCreated(long requestId,
@NonNull RoutingSessionInfo sessionInfo) {
- Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+ requireNonNull(sessionInfo, "sessionInfo must not be null");
if (DEBUG) {
Log.d(TAG, "notifySessionCreated: Creating a session. requestId=" + requestId
@@ -326,17 +356,129 @@
* @param formats the {@link MediaStreamsFormats} that describes the format for the {@link
* MediaStreams} to return.
* @return a {@link MediaStreams} instance that holds the media streams to route as part of the
- * newly created routing session.
+ * newly created routing session. May be null if system media capture failed, in which case
+ * you can ignore the return value, as you will receive a call to {@link #onReleaseSession}
+ * where you can clean up this session
* @hide
*/
// TODO: b/362507305 - Unhide once the implementation and CTS are in place.
@FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
- @NonNull
+ @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
+ @Nullable
public final MediaStreams notifySystemMediaSessionCreated(
long requestId,
@NonNull RoutingSessionInfo sessionInfo,
@NonNull MediaStreamsFormats formats) {
- throw new UnsupportedOperationException();
+ requireNonNull(sessionInfo, "sessionInfo must not be null");
+ requireNonNull(formats, "formats must not be null");
+ if (DEBUG) {
+ Log.d(
+ TAG,
+ "notifySystemMediaSessionCreated: Creating a session. requestId="
+ + requestId
+ + ", sessionInfo="
+ + sessionInfo);
+ }
+
+ Integer uid;
+ synchronized (mRequestIdsLock) {
+ uid = mSystemMediaSessionCreationRequests.get(requestId);
+ mSystemMediaSessionCreationRequests.remove(requestId);
+ }
+
+ if (uid == null) {
+ throw new IllegalStateException(
+ "Unexpected system routing session created (request id="
+ + requestId
+ + "):"
+ + sessionInfo);
+ }
+
+ if (mRemoteCallback == null) {
+ throw new IllegalStateException("Unexpected: remote callback is null.");
+ }
+
+ int routingTypes = 0;
+ var providerInfo = mProviderInfo;
+ for (String selectedRouteId : sessionInfo.getSelectedRoutes()) {
+ MediaRoute2Info route = providerInfo.mRoutes.get(selectedRouteId);
+ if (route == null) {
+ throw new IllegalArgumentException(
+ "Invalid selected route with id: " + selectedRouteId);
+ }
+ routingTypes |= route.getSupportedRoutingTypes();
+ }
+
+ if ((routingTypes & MediaRoute2Info.FLAG_ROUTING_TYPE_SYSTEM_AUDIO) == 0) {
+ // TODO: b/380431086 - Populate video stream once we add support for video.
+ throw new IllegalArgumentException(
+ "Selected routes for system media don't support any system media routing"
+ + " types.");
+ }
+
+ AudioFormat audioFormat = formats.mAudioFormat;
+ var mediaStreamsBuilder = new MediaStreams.Builder();
+ if (audioFormat != null) {
+ populateAudioStream(audioFormat, uid, mediaStreamsBuilder);
+ }
+ // TODO: b/380431086 - Populate video stream once we add support for video.
+
+ MediaStreams streams = mediaStreamsBuilder.build();
+ var audioRecord = streams.mAudioRecord;
+ if (audioRecord == null) {
+ Log.e(
+ TAG,
+ "Audio record is not populated. Returning an empty stream and scheduling the"
+ + " session release for: "
+ + sessionInfo);
+ mHandler.post(() -> onReleaseSession(REQUEST_ID_NONE, sessionInfo.getOriginalId()));
+ notifyRequestFailed(requestId, REASON_FAILED_TO_REROUTE_SYSTEM_MEDIA);
+ return null;
+ }
+
+ synchronized (mSessionLock) {
+ try {
+ mRemoteCallback.notifySessionCreated(requestId, sessionInfo);
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ }
+ mOngoingMediaStreams.put(sessionInfo.getOriginalId(), streams);
+ return streams;
+ }
+ }
+
+ @RequiresPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
+ private void populateAudioStream(
+ AudioFormat audioFormat, int uid, MediaStreams.Builder builder) {
+ var audioAttributes =
+ new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
+ var audioMixingRuleBuilder =
+ new AudioMixingRule.Builder()
+ .addRule(audioAttributes, AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE);
+ if (uid != Process.INVALID_UID) {
+ audioMixingRuleBuilder.addMixRule(AudioMixingRule.RULE_MATCH_UID, uid);
+ }
+
+ AudioMix mix =
+ new AudioMix.Builder(audioMixingRuleBuilder.build())
+ .setFormat(audioFormat)
+ .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK)
+ .build();
+ AudioPolicy audioPolicy =
+ new AudioPolicy.Builder(this).setLooper(mHandler.getLooper()).addMix(mix).build();
+ var audioManager = getSystemService(AudioManager.class);
+ if (audioManager == null) {
+ Log.e(TAG, "Couldn't fetch the audio manager.");
+ return;
+ }
+ audioManager.registerAudioPolicy(audioPolicy);
+ var audioRecord = audioPolicy.createAudioRecordSink(mix);
+ if (audioRecord == null) {
+ Log.e(TAG, "Audio record creation failed.");
+ audioManager.unregisterAudioPolicy(audioPolicy);
+ return;
+ }
+ builder.setAudioStream(audioPolicy, audioRecord);
}
/**
@@ -344,7 +486,7 @@
* {@link RoutingSessionInfo#getSelectedRoutes() selected routes} are changed.
*/
public final void notifySessionUpdated(@NonNull RoutingSessionInfo sessionInfo) {
- Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+ requireNonNull(sessionInfo, "sessionInfo must not be null");
if (DEBUG) {
Log.d(TAG, "notifySessionUpdated: Updating session id=" + sessionInfo);
@@ -379,6 +521,7 @@
RoutingSessionInfo sessionInfo;
synchronized (mSessionLock) {
sessionInfo = mSessionInfos.remove(sessionId);
+ maybeReleaseMediaStreams(sessionId);
if (sessionInfo == null) {
Log.w(TAG, "notifySessionReleased: Ignoring unknown session info.");
@@ -396,6 +539,34 @@
}
}
+ /** Releases any system media routing resources associated with the given {@code sessionId}. */
+ private void maybeReleaseMediaStreams(String sessionId) {
+ if (!Flags.enableMirroringInMediaRouter2()) {
+ return;
+ }
+ synchronized (mSessionLock) {
+ var streams = mOngoingMediaStreams.remove(sessionId);
+ if (streams != null) {
+ releaseAudioStream(streams.mAudioPolicy, streams.mAudioRecord);
+ // TODO: b/380431086: Release the video stream once implemented.
+ }
+ }
+ }
+
+ // We cannot reach the code that requires MODIFY_AUDIO_ROUTING without holding it.
+ @SuppressWarnings("MissingPermission")
+ private void releaseAudioStream(AudioPolicy audioPolicy, AudioRecord audioRecord) {
+ if (audioPolicy == null) {
+ return;
+ }
+ var audioManager = getSystemService(AudioManager.class);
+ if (audioManager == null) {
+ return;
+ }
+ audioRecord.stop();
+ audioManager.unregisterAudioPolicy(audioPolicy);
+ }
+
/**
* Notifies to the client that the request has failed.
*
@@ -569,7 +740,7 @@
* Updates routes of the provider and notifies the system media router service.
*/
public final void notifyRoutes(@NonNull Collection<MediaRoute2Info> routes) {
- Objects.requireNonNull(routes, "routes must not be null");
+ requireNonNull(routes, "routes must not be null");
List<MediaRoute2Info> sanitizedRoutes = new ArrayList<>(routes.size());
for (MediaRoute2Info route : routes) {
@@ -763,6 +934,32 @@
}
@Override
+ public void requestCreateSystemMediaSession(
+ long requestId,
+ int uid,
+ String packageName,
+ String routeId,
+ @Nullable Bundle sessionHints) {
+ if (!checkCallerIsSystem()) {
+ return;
+ }
+ if (!checkRouteIdIsValid(routeId, "requestCreateSession")) {
+ return;
+ }
+ synchronized (mRequestIdsLock) {
+ mSystemMediaSessionCreationRequests.put(requestId, uid);
+ }
+ mHandler.sendMessage(
+ obtainMessage(
+ MediaRoute2ProviderService::onCreateSystemRoutingSession,
+ MediaRoute2ProviderService.this,
+ requestId,
+ packageName,
+ routeId,
+ sessionHints));
+ }
+
+ @Override
public void selectRoute(long requestId, String sessionId, String routeId) {
if (!checkCallerIsSystem()) {
return;
@@ -825,6 +1022,10 @@
if (!checkSessionIdIsValid(sessionId, "releaseSession")) {
return;
}
+ // We proactively release the system media routing once the system requests it, to
+ // ensure it happens immediately.
+ maybeReleaseMediaStreams(sessionId);
+
addRequestId(requestId);
mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onReleaseSession,
MediaRoute2ProviderService.this, requestId, sessionId));
@@ -843,12 +1044,14 @@
@FlaggedApi(Flags.FLAG_ENABLE_MIRRORING_IN_MEDIA_ROUTER_2)
public static final class MediaStreams {
- private final AudioRecord mAudioRecord;
+ @Nullable private final AudioPolicy mAudioPolicy;
+ @Nullable private final AudioRecord mAudioRecord;
// TODO: b/380431086: Add the video equivalent.
- private MediaStreams(AudioRecord mAudioRecord) {
- this.mAudioRecord = mAudioRecord;
+ private MediaStreams(Builder builder) {
+ this.mAudioPolicy = builder.mAudioPolicy;
+ this.mAudioRecord = builder.mAudioRecord;
}
/**
@@ -859,8 +1062,33 @@
public AudioRecord getAudioRecord() {
return mAudioRecord;
}
+
+ /**
+ * Builder for {@link MediaStreams}.
+ *
+ * @hide
+ */
+ public static final class Builder {
+
+ @Nullable private AudioPolicy mAudioPolicy;
+ @Nullable private AudioRecord mAudioRecord;
+
+ /** Populates system media audio-related structures. */
+ public Builder setAudioStream(
+ @NonNull AudioPolicy audioPolicy, @NonNull AudioRecord audioRecord) {
+ mAudioPolicy = requireNonNull(audioPolicy);
+ mAudioRecord = requireNonNull(audioRecord);
+ return this;
+ }
+
+ /** Builds a {@link MediaStreams} instance. */
+ public MediaStreams build() {
+ return new MediaStreams(this);
+ }
+ }
}
+
/**
* Holds the formats to encode media data to be read from {@link MediaStreams}.
*
@@ -911,7 +1139,7 @@
*/
@NonNull
public Builder setAudioFormat(@NonNull AudioFormat audioFormat) {
- this.mAudioFormat = Objects.requireNonNull(audioFormat);
+ this.mAudioFormat = requireNonNull(audioFormat);
return this;
}
diff --git a/media/java/android/media/quality/ActiveProcessingPicture.aidl b/media/java/android/media/quality/ActiveProcessingPicture.aidl
new file mode 100644
index 0000000..2851306
--- /dev/null
+++ b/media/java/android/media/quality/ActiveProcessingPicture.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.media.quality;
+
+parcelable ActiveProcessingPicture;
\ No newline at end of file
diff --git a/media/java/android/media/quality/ActiveProcessingPicture.java b/media/java/android/media/quality/ActiveProcessingPicture.java
new file mode 100644
index 0000000..e16ad62
--- /dev/null
+++ b/media/java/android/media/quality/ActiveProcessingPicture.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 android.media.quality;
+
+import android.annotation.FlaggedApi;
+import android.media.tv.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Active picture represents an image or video undergoing picture processing which uses a picture
+ * profile. The picture profile is used to configure the picture processing parameters.
+ */
+@FlaggedApi(Flags.FLAG_MEDIA_QUALITY_FW)
+public final class ActiveProcessingPicture implements Parcelable {
+ private final int mId;
+ private final String mProfileId;
+
+ public ActiveProcessingPicture(int id, @NonNull String profileId) {
+ mId = id;
+ mProfileId = profileId;
+ }
+
+ /** @hide */
+ ActiveProcessingPicture(Parcel in) {
+ mId = in.readInt();
+ mProfileId = in.readString();
+ }
+
+ @NonNull
+ public static final Creator<ActiveProcessingPicture> CREATOR = new Creator<>() {
+ @Override
+ public ActiveProcessingPicture createFromParcel(Parcel in) {
+ return new ActiveProcessingPicture(in);
+ }
+
+ @Override
+ public ActiveProcessingPicture[] newArray(int size) {
+ return new ActiveProcessingPicture[size];
+ }
+ };
+
+ /**
+ * An ID that uniquely identifies the active content.
+ *
+ * <p>The ID is assigned by the system to distinguish different active contents.
+ */
+ public int getId() {
+ return mId;
+ }
+
+ /**
+ * The ID of the picture profile used to configure the content.
+ */
+ @NonNull
+ public String getProfileId() {
+ return mProfileId;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mId);
+ dest.writeString(mProfileId);
+ }
+}
diff --git a/media/java/android/media/quality/IMediaQualityManager.aidl b/media/java/android/media/quality/IMediaQualityManager.aidl
index 9daebca..253c2d8 100644
--- a/media/java/android/media/quality/IMediaQualityManager.aidl
+++ b/media/java/android/media/quality/IMediaQualityManager.aidl
@@ -25,51 +25,56 @@
import android.media.quality.PictureProfile;
import android.media.quality.SoundProfileHandle;
import android.media.quality.SoundProfile;
+import android.os.UserHandle;
/**
* Interface for Media Quality Manager
* @hide
*/
interface IMediaQualityManager {
- PictureProfile createPictureProfile(in PictureProfile pp, int userId);
- void updatePictureProfile(in String id, in PictureProfile pp, int userId);
- void removePictureProfile(in String id, int userId);
- PictureProfile getPictureProfile(in int type, in String name, int userId);
- List<PictureProfile> getPictureProfilesByPackage(in String packageName, int userId);
- List<PictureProfile> getAvailablePictureProfiles(int userId);
- boolean setDefaultPictureProfile(in String id, int userId);
- List<String> getPictureProfilePackageNames(int userId);
- List<String> getPictureProfileAllowList(int userId);
- void setPictureProfileAllowList(in List<String> packages, int userId);
- List<PictureProfileHandle> getPictureProfileHandle(in String[] id, int userId);
+ PictureProfile createPictureProfile(in PictureProfile pp, in UserHandle user);
+ void updatePictureProfile(in String id, in PictureProfile pp, in UserHandle user);
+ void removePictureProfile(in String id, in UserHandle user);
+ boolean setDefaultPictureProfile(in String id, in UserHandle user);
+ PictureProfile getPictureProfile(
+ in int type, in String name, in boolean includeParams, in UserHandle user);
+ List<PictureProfile> getPictureProfilesByPackage(
+ in String packageName, in boolean includeParams, in UserHandle user);
+ List<PictureProfile> getAvailablePictureProfiles(in boolean includeParams, in UserHandle user);
+ List<String> getPictureProfilePackageNames(in UserHandle user);
+ List<String> getPictureProfileAllowList(in UserHandle user);
+ void setPictureProfileAllowList(in List<String> packages, in UserHandle user);
+ List<PictureProfileHandle> getPictureProfileHandle(in String[] id, in UserHandle user);
- SoundProfile createSoundProfile(in SoundProfile pp, int userId);
- void updateSoundProfile(in String id, in SoundProfile pp, int userId);
- void removeSoundProfile(in String id, int userId);
- SoundProfile getSoundProfile(in int type, in String name, int userId);
- List<SoundProfile> getSoundProfilesByPackage(in String packageName, int userId);
- List<SoundProfile> getAvailableSoundProfiles(int userId);
- boolean setDefaultSoundProfile(in String id, int userId);
- List<String> getSoundProfilePackageNames(int userId);
- List<String> getSoundProfileAllowList(int userId);
- void setSoundProfileAllowList(in List<String> packages, int userId);
- List<SoundProfileHandle> getSoundProfileHandle(in String[] id, int userId);
+ SoundProfile createSoundProfile(in SoundProfile pp, in UserHandle user);
+ void updateSoundProfile(in String id, in SoundProfile pp, in UserHandle user);
+ void removeSoundProfile(in String id, in UserHandle user);
+ boolean setDefaultSoundProfile(in String id, in UserHandle user);
+ SoundProfile getSoundProfile(
+ in int type, in String name, in boolean includeParams, in UserHandle user);
+ List<SoundProfile> getSoundProfilesByPackage(
+ in String packageName, in boolean includeParams, in UserHandle user);
+ List<SoundProfile> getAvailableSoundProfiles(in boolean includeParams, in UserHandle user);
+ List<String> getSoundProfilePackageNames(in UserHandle user);
+ List<String> getSoundProfileAllowList(in UserHandle user);
+ void setSoundProfileAllowList(in List<String> packages, in UserHandle user);
+ List<SoundProfileHandle> getSoundProfileHandle(in String[] id, in UserHandle user);
void registerPictureProfileCallback(in IPictureProfileCallback cb);
void registerSoundProfileCallback(in ISoundProfileCallback cb);
void registerAmbientBacklightCallback(in IAmbientBacklightCallback cb);
- List<ParamCapability> getParamCapabilities(in List<String> names, int userId);
+ List<ParamCapability> getParamCapabilities(in List<String> names, in UserHandle user);
- boolean isSupported(int userId);
- void setAutoPictureQualityEnabled(in boolean enabled, int userId);
- boolean isAutoPictureQualityEnabled(int userId);
- void setSuperResolutionEnabled(in boolean enabled, int userId);
- boolean isSuperResolutionEnabled(int userId);
- void setAutoSoundQualityEnabled(in boolean enabled, int userId);
- boolean isAutoSoundQualityEnabled(int userId);
+ boolean isSupported(in UserHandle user);
+ void setAutoPictureQualityEnabled(in boolean enabled, in UserHandle user);
+ boolean isAutoPictureQualityEnabled(in UserHandle user);
+ void setSuperResolutionEnabled(in boolean enabled, in UserHandle user);
+ boolean isSuperResolutionEnabled(in UserHandle user);
+ void setAutoSoundQualityEnabled(in boolean enabled, in UserHandle user);
+ boolean isAutoSoundQualityEnabled(in UserHandle user);
- void setAmbientBacklightSettings(in AmbientBacklightSettings settings, int userId);
- void setAmbientBacklightEnabled(in boolean enabled, int userId);
- boolean isAmbientBacklightEnabled(int userId);
+ void setAmbientBacklightSettings(in AmbientBacklightSettings settings, in UserHandle user);
+ void setAmbientBacklightEnabled(in boolean enabled, in UserHandle user);
+ boolean isAmbientBacklightEnabled(in UserHandle user);
}
diff --git a/media/java/android/media/quality/IPictureProfileCallback.aidl b/media/java/android/media/quality/IPictureProfileCallback.aidl
index 34aa2b0..7071a16 100644
--- a/media/java/android/media/quality/IPictureProfileCallback.aidl
+++ b/media/java/android/media/quality/IPictureProfileCallback.aidl
@@ -29,5 +29,5 @@
void onPictureProfileUpdated(in String id, in PictureProfile p);
void onPictureProfileRemoved(in String id, in PictureProfile p);
void onParamCapabilitiesChanged(in String id, in List<ParamCapability> caps);
- void onError(in int err);
+ void onError(in String id, in int err);
}
diff --git a/media/java/android/media/quality/ISoundProfileCallback.aidl b/media/java/android/media/quality/ISoundProfileCallback.aidl
index 9043757..30bb106 100644
--- a/media/java/android/media/quality/ISoundProfileCallback.aidl
+++ b/media/java/android/media/quality/ISoundProfileCallback.aidl
@@ -29,5 +29,5 @@
void onSoundProfileUpdated(in String id, in SoundProfile p);
void onSoundProfileRemoved(in String id, in SoundProfile p);
void onParamCapabilitiesChanged(in String id, in List<ParamCapability> caps);
- void onError(in int err);
+ void onError(in String id, in int err);
}
diff --git a/media/java/android/media/quality/MediaQualityManager.java b/media/java/android/media/quality/MediaQualityManager.java
index efbe47b..7e87462 100644
--- a/media/java/android/media/quality/MediaQualityManager.java
+++ b/media/java/android/media/quality/MediaQualityManager.java
@@ -20,11 +20,13 @@
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.media.tv.flags.Flags;
import android.os.RemoteException;
+import android.os.UserHandle;
import androidx.annotation.RequiresPermission;
@@ -47,7 +49,7 @@
private final IMediaQualityManager mService;
private final Context mContext;
- private final int mUserId;
+ private final UserHandle mUserHandle;
private final Object mLock = new Object();
// @GuardedBy("mLock")
private final List<PictureProfileCallbackRecord> mPpCallbackRecords = new ArrayList<>();
@@ -55,6 +57,9 @@
private final List<SoundProfileCallbackRecord> mSpCallbackRecords = new ArrayList<>();
// @GuardedBy("mLock")
private final List<AmbientBacklightCallbackRecord> mAbCallbackRecords = new ArrayList<>();
+ // @GuardedBy("mLock")
+ private final List<ActiveProcessingPictureListenerRecord> mApListenerRecords =
+ new ArrayList<>();
/**
@@ -62,7 +67,7 @@
*/
public MediaQualityManager(Context context, IMediaQualityManager service) {
mContext = context;
- mUserId = context.getUserId();
+ mUserHandle = context.getUser();
mService = service;
IPictureProfileCallback ppCallback = new IPictureProfileCallback.Stub() {
@Override
@@ -102,11 +107,11 @@
}
}
@Override
- public void onError(int err) {
+ public void onError(String profileId, int err) {
synchronized (mLock) {
for (PictureProfileCallbackRecord record : mPpCallbackRecords) {
// TODO: filter callback record
- record.postError(err);
+ record.postError(profileId, err);
}
}
}
@@ -149,11 +154,11 @@
}
}
@Override
- public void onError(int err) {
+ public void onError(String profileId, int err) {
synchronized (mLock) {
for (SoundProfileCallbackRecord record : mSpCallbackRecords) {
// TODO: filter callback record
- record.postError(err);
+ record.postError(profileId, err);
}
}
}
@@ -210,18 +215,21 @@
}
}
-
/**
* Gets picture profile by given profile type and name.
*
+ * @param type the type of the profile.
+ * @param name the name of the profile.
+ * @param includeParams {@code true} to include parameters in the profile; {@code false}
+ * otherwise.
* @return the corresponding picture profile if available; {@code null} if the name doesn't
- * exist.
+ * exist.
*/
@Nullable
public PictureProfile getPictureProfile(
- @PictureProfile.ProfileType int type, @NonNull String name) {
+ @PictureProfile.ProfileType int type, @NonNull String name, boolean includeParams) {
try {
- return mService.getPictureProfile(type, name, mUserId);
+ return mService.getPictureProfile(type, name, includeParams, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -231,14 +239,18 @@
/**
* Gets profiles that available to the given package.
*
+ * @param packageName the package name of the profiles.
+ * @param includeParams {@code true} to include parameters in the profile; {@code false}
+ * otherwise.
* @hide
*/
@SystemApi
@NonNull
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
- public List<PictureProfile> getPictureProfilesByPackage(@NonNull String packageName) {
+ public List<PictureProfile> getPictureProfilesByPackage(
+ @NonNull String packageName, boolean includeParams) {
try {
- return mService.getPictureProfilesByPackage(packageName, mUserId);
+ return mService.getPictureProfilesByPackage(packageName, includeParams, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -246,11 +258,16 @@
/**
* Gets profiles that available to the caller.
+ *
+ * @param includeParams {@code true} to include parameters in the profile; {@code false}
+ * otherwise.
+ * @return the corresponding picture profile if available; {@code null} if the name doesn't
+ * exist.
*/
@NonNull
- public List<PictureProfile> getAvailablePictureProfiles() {
+ public List<PictureProfile> getAvailablePictureProfiles(boolean includeParams) {
try {
- return mService.getAvailablePictureProfiles(mUserId);
+ return mService.getAvailablePictureProfiles(includeParams, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -268,7 +285,7 @@
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public boolean setDefaultPictureProfile(@Nullable String id) {
try {
- return mService.setDefaultPictureProfile(id, mUserId);
+ return mService.setDefaultPictureProfile(id, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -277,7 +294,7 @@
/**
* Gets all package names whose picture profiles are available.
*
- * @see #getPictureProfilesByPackage(String)
+ * @see #getPictureProfilesByPackage(String, boolean)
* @hide
*/
@SystemApi
@@ -285,7 +302,7 @@
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public List<String> getPictureProfilePackageNames() {
try {
- return mService.getPictureProfilePackageNames(mUserId);
+ return mService.getPictureProfilePackageNames(mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -297,7 +314,7 @@
*/
public List<PictureProfileHandle> getPictureProfileHandle(String[] id) {
try {
- return mService.getPictureProfileHandle(id, mUserId);
+ return mService.getPictureProfileHandle(id, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -309,7 +326,7 @@
*/
public List<SoundProfileHandle> getSoundProfileHandle(String[] id) {
try {
- return mService.getSoundProfileHandle(id, mUserId);
+ return mService.getSoundProfileHandle(id, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -320,10 +337,12 @@
*
* <p>If the profile is created successfully,
* {@link PictureProfileCallback#onPictureProfileAdded(String, PictureProfile)} is invoked.
+ *
+ * @param pp the {@link PictureProfile} object to be created.
*/
public void createPictureProfile(@NonNull PictureProfile pp) {
try {
- mService.createPictureProfile(pp, mUserId);
+ mService.createPictureProfile(pp, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -332,10 +351,13 @@
/**
* Updates an existing picture profile and store it in the system.
+ *
+ * @param profileId the id of the object to be updated.
+ * @param pp the {@link PictureProfile} object to be updated.
*/
public void updatePictureProfile(@NonNull String profileId, @NonNull PictureProfile pp) {
try {
- mService.updatePictureProfile(profileId, pp, mUserId);
+ mService.updatePictureProfile(profileId, pp, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -344,10 +366,12 @@
/**
* Removes a picture profile from the system.
+ *
+ * @param profileId the id of the object to be removed.
*/
public void removePictureProfile(@NonNull String profileId) {
try {
- mService.removePictureProfile(profileId, mUserId);
+ mService.removePictureProfile(profileId, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -383,18 +407,20 @@
}
}
-
/**
* Gets sound profile by given profile type and name.
*
- * @return the corresponding sound profile if available; {@code null} if the name doesn't
- * exist.
+ * @param type the type of the profile.
+ * @param name the name of the profile.
+ * @param includeParams {@code true} to include parameters in the profile; {@code false}
+ * otherwise.
+ * @return the corresponding sound profile if available; {@code null} if the name doesn't exist.
*/
@Nullable
public SoundProfile getSoundProfile(
- @SoundProfile.ProfileType int type, @NonNull String name) {
+ @SoundProfile.ProfileType int type, @NonNull String name, boolean includeParams) {
try {
- return mService.getSoundProfile(type, name, mUserId);
+ return mService.getSoundProfile(type, name, includeParams, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -404,14 +430,18 @@
/**
* Gets profiles that available to the given package.
*
+ * @param packageName the package name of the profiles.
+ * @param includeParams {@code true} to include parameters in the profile; {@code false}
+ * otherwise.
* @hide
*/
@SystemApi
@NonNull
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
- public List<SoundProfile> getSoundProfilesByPackage(@NonNull String packageName) {
+ public List<SoundProfile> getSoundProfilesByPackage(
+ @NonNull String packageName, boolean includeParams) {
try {
- return mService.getSoundProfilesByPackage(packageName, mUserId);
+ return mService.getSoundProfilesByPackage(packageName, includeParams, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -419,11 +449,16 @@
/**
* Gets profiles that available to the caller package.
+ *
+ * @param includeParams {@code true} to include parameters in the profile; {@code false}
+ * otherwise.
+ *
+ * @return the corresponding sound profile if available; {@code null} if the none available.
*/
@NonNull
- public List<SoundProfile> getAvailableSoundProfiles() {
+ public List<SoundProfile> getAvailableSoundProfiles(boolean includeParams) {
try {
- return mService.getAvailableSoundProfiles(mUserId);
+ return mService.getAvailableSoundProfiles(includeParams, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -441,7 +476,7 @@
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public boolean setDefaultSoundProfile(@Nullable String id) {
try {
- return mService.setDefaultSoundProfile(id, mUserId);
+ return mService.setDefaultSoundProfile(id, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -450,7 +485,7 @@
/**
* Gets all package names whose sound profiles are available.
*
- * @see #getSoundProfilesByPackage(String)
+ * @see #getSoundProfilesByPackage(String, boolean)
*
* @hide
*/
@@ -459,7 +494,7 @@
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public List<String> getSoundProfilePackageNames() {
try {
- return mService.getSoundProfilePackageNames(mUserId);
+ return mService.getSoundProfilePackageNames(mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -471,10 +506,12 @@
*
* <p>If the profile is created successfully,
* {@link SoundProfileCallback#onSoundProfileAdded(String, SoundProfile)} is invoked.
+ *
+ * @param sp the {@link SoundProfile} object to be created.
*/
public void createSoundProfile(@NonNull SoundProfile sp) {
try {
- mService.createSoundProfile(sp, mUserId);
+ mService.createSoundProfile(sp, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -483,10 +520,13 @@
/**
* Updates an existing sound profile and store it in the system.
+ *
+ * @param profileId the id of the object to be updated.
+ * @param sp the {@link SoundProfile} object to be updated.
*/
public void updateSoundProfile(@NonNull String profileId, @NonNull SoundProfile sp) {
try {
- mService.updateSoundProfile(profileId, sp, mUserId);
+ mService.updateSoundProfile(profileId, sp, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -495,10 +535,12 @@
/**
* Removes a sound profile from the system.
+ *
+ * @param profileId the id of the object to be removed.
*/
public void removeSoundProfile(@NonNull String profileId) {
try {
- mService.removeSoundProfile(profileId, mUserId);
+ mService.removeSoundProfile(profileId, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -510,7 +552,7 @@
@NonNull
public List<ParamCapability> getParamCapabilities(@NonNull List<String> names) {
try {
- return mService.getParamCapabilities(names, mUserId);
+ return mService.getParamCapabilities(names, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -528,7 +570,7 @@
@NonNull
public List<String> getPictureProfileAllowList() {
try {
- return mService.getPictureProfileAllowList(mUserId);
+ return mService.getPictureProfileAllowList(mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -542,7 +584,7 @@
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public void setPictureProfileAllowList(@NonNull List<String> packageNames) {
try {
- mService.setPictureProfileAllowList(packageNames, mUserId);
+ mService.setPictureProfileAllowList(packageNames, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -560,7 +602,7 @@
@NonNull
public List<String> getSoundProfileAllowList() {
try {
- return mService.getSoundProfileAllowList(mUserId);
+ return mService.getSoundProfileAllowList(mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -574,7 +616,7 @@
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public void setSoundProfileAllowList(@NonNull List<String> packageNames) {
try {
- mService.setSoundProfileAllowList(packageNames, mUserId);
+ mService.setSoundProfileAllowList(packageNames, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -586,7 +628,7 @@
*/
public boolean isSupported() {
try {
- return mService.isSupported(mUserId);
+ return mService.isSupported(mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -604,7 +646,7 @@
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public void setAutoPictureQualityEnabled(boolean enabled) {
try {
- mService.setAutoPictureQualityEnabled(enabled, mUserId);
+ mService.setAutoPictureQualityEnabled(enabled, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -615,7 +657,7 @@
*/
public boolean isAutoPictureQualityEnabled() {
try {
- return mService.isAutoPictureQualityEnabled(mUserId);
+ return mService.isAutoPictureQualityEnabled(mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -632,7 +674,7 @@
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
public void setSuperResolutionEnabled(boolean enabled) {
try {
- mService.setSuperResolutionEnabled(enabled, mUserId);
+ mService.setSuperResolutionEnabled(enabled, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -643,7 +685,7 @@
*/
public boolean isSuperResolutionEnabled() {
try {
- return mService.isSuperResolutionEnabled(mUserId);
+ return mService.isSuperResolutionEnabled(mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -661,7 +703,7 @@
@RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
public void setAutoSoundQualityEnabled(boolean enabled) {
try {
- mService.setAutoSoundQualityEnabled(enabled, mUserId);
+ mService.setAutoSoundQualityEnabled(enabled, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -672,7 +714,7 @@
*/
public boolean isAutoSoundQualityEnabled() {
try {
- return mService.isAutoSoundQualityEnabled(mUserId);
+ return mService.isAutoSoundQualityEnabled(mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -721,7 +763,7 @@
@NonNull AmbientBacklightSettings settings) {
Preconditions.checkNotNull(settings);
try {
- mService.setAmbientBacklightSettings(settings, mUserId);
+ mService.setAmbientBacklightSettings(settings, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -732,7 +774,7 @@
*/
public boolean isAmbientBacklightEnabled() {
try {
- return mService.isAmbientBacklightEnabled(mUserId);
+ return mService.isAmbientBacklightEnabled(mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -746,7 +788,7 @@
@RequiresPermission(android.Manifest.permission.READ_COLOR_ZONES)
public void setAmbientBacklightEnabled(boolean enabled) {
try {
- mService.setAmbientBacklightEnabled(enabled, mUserId);
+ mService.setAmbientBacklightEnabled(enabled, mUserHandle);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -803,11 +845,11 @@
});
}
- public void postError(int error) {
+ public void postError(String profileId, int error) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
- mCallback.onError(error);
+ mCallback.onError(profileId, error);
}
});
}
@@ -863,11 +905,11 @@
});
}
- public void postError(int error) {
+ public void postError(String profileId, int error) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
- mCallback.onError(error);
+ mCallback.onError(profileId, error);
}
});
}
@@ -933,9 +975,11 @@
/**
* This is invoked when an issue has occurred.
*
+ * @param profileId the profile ID related to the error. {@code null} if there is no
+ * associated profile.
* @param errorCode the error code
*/
- public void onError(@PictureProfile.ErrorCode int errorCode) {
+ public void onError(@Nullable String profileId, @PictureProfile.ErrorCode int errorCode) {
}
/**
@@ -988,9 +1032,11 @@
/**
* This is invoked when an issue has occurred.
*
+ * @param profileId the profile ID related to the error. {@code null} if there is no
+ * associated profile.
* @param errorCode the error code
*/
- public void onError(@SoundProfile.ErrorCode int errorCode) {
+ public void onError(@Nullable String profileId, @SoundProfile.ErrorCode int errorCode) {
}
/**
@@ -1016,4 +1062,86 @@
public void onAmbientBacklightEvent(@NonNull AmbientBacklightEvent event) {
}
}
+
+ /**
+ * Listener used to monitor status of active pictures.
+ */
+ public interface ActiveProcessingPictureListener {
+ /**
+ * Called when active pictures are changed.
+ *
+ * @param activeProcessingPictures contents currently undergoing picture processing.
+ */
+ void onActiveProcessingPicturesChanged(
+ @NonNull List<ActiveProcessingPicture> activeProcessingPictures);
+ }
+
+ /**
+ * Adds an active picture listener for the contents owner by the caller.
+ */
+ public void addActiveProcessingPictureListener(
+ @CallbackExecutor @NonNull Executor executor,
+ @NonNull ActiveProcessingPictureListener listener) {
+ Preconditions.checkNotNull(listener);
+ Preconditions.checkNotNull(executor);
+ synchronized (mLock) {
+ mApListenerRecords.add(
+ new ActiveProcessingPictureListenerRecord(listener, executor, false));
+ }
+ }
+
+ /**
+ * Adds an active picture listener for all contents.
+ *
+ * @hide
+ */
+ @SuppressLint("PairedRegistration")
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
+ public void addGlobalActiveProcessingPictureListener(
+ @NonNull Executor executor,
+ @NonNull ActiveProcessingPictureListener listener) {
+ Preconditions.checkNotNull(listener);
+ Preconditions.checkNotNull(executor);
+ synchronized (mLock) {
+ mApListenerRecords.add(
+ new ActiveProcessingPictureListenerRecord(listener, executor, true));
+ }
+ }
+
+
+ /**
+ * Removes an active picture listener for the contents.
+ */
+ public void removeActiveProcessingPictureListener(
+ @NonNull ActiveProcessingPictureListener listener) {
+ Preconditions.checkNotNull(listener);
+ synchronized (mLock) {
+ for (Iterator<ActiveProcessingPictureListenerRecord> it = mApListenerRecords.iterator();
+ it.hasNext(); ) {
+ ActiveProcessingPictureListenerRecord record = it.next();
+ if (record.getListener() == listener) {
+ it.remove();
+ break;
+ }
+ }
+ }
+ }
+
+ private static final class ActiveProcessingPictureListenerRecord {
+ private final ActiveProcessingPictureListener mListener;
+ private final Executor mExecutor;
+ private final boolean mIsGlobal;
+
+ ActiveProcessingPictureListenerRecord(
+ ActiveProcessingPictureListener listener, Executor executor, boolean isGlobal) {
+ mListener = listener;
+ mExecutor = executor;
+ mIsGlobal = isGlobal;
+ }
+
+ public ActiveProcessingPictureListener getListener() {
+ return mListener;
+ }
+ }
}
diff --git a/media/java/android/media/quality/PictureProfileHandle.java b/media/java/android/media/quality/PictureProfileHandle.java
index 714fd36..d9d2193 100644
--- a/media/java/android/media/quality/PictureProfileHandle.java
+++ b/media/java/android/media/quality/PictureProfileHandle.java
@@ -28,11 +28,14 @@
* A picture profile represents a collection of parameters used to configure picture processing
* to enhance the quality of graphic buffers.
*
+ * @see PictureProfile.getHandle
+ *
* @hide
*/
@SystemApi
@FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
public final class PictureProfileHandle implements Parcelable {
+ /** A handle that represents no picture processing configuration. */
public static final @NonNull PictureProfileHandle NONE = new PictureProfileHandle(0);
private final long mId;
@@ -42,7 +45,16 @@
mId = id;
}
- /** @hide */
+ /**
+ * An ID that uniquely identifies the picture profile across the system.
+ *
+ * This ID can be used to construct an NDK PictureProfileHandle to be fed directly into
+ * IGraphicBufferProducer to couple a picture profile to a graphic buffer.
+ *
+ * Note: These IDs are generated randomly and are not stable across reboots.
+ *
+ * @hide
+ */
@SystemApi
@FlaggedApi(android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES)
public long getId() {
diff --git a/native/android/dynamic_instrumentation_manager.cpp b/native/android/dynamic_instrumentation_manager.cpp
index 5322136..0749731 100644
--- a/native/android/dynamic_instrumentation_manager.cpp
+++ b/native/android/dynamic_instrumentation_manager.cpp
@@ -15,7 +15,9 @@
*/
#define LOG_TAG "ADynamicInstrumentationManager"
+#include <android-base/properties.h>
#include <android/dynamic_instrumentation_manager.h>
+#include <android/os/instrumentation/BnOffsetCallback.h>
#include <android/os/instrumentation/ExecutableMethodFileOffsets.h>
#include <android/os/instrumentation/IDynamicInstrumentationManager.h>
#include <android/os/instrumentation/MethodDescriptor.h>
@@ -23,7 +25,9 @@
#include <binder/Binder.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
+#include <utils/StrongPointer.h>
+#include <future>
#include <mutex>
#include <optional>
#include <string>
@@ -31,6 +35,9 @@
namespace android::dynamicinstrumentationmanager {
+using android::os::instrumentation::BnOffsetCallback;
+using android::os::instrumentation::ExecutableMethodFileOffsets;
+
// Global instance of IDynamicInstrumentationManager, service is obtained only on first use.
static std::mutex mLock;
static sp<os::instrumentation::IDynamicInstrumentationManager> mService;
@@ -131,6 +138,30 @@
delete instance;
}
+class ResultCallback : public BnOffsetCallback {
+public:
+ ::android::binder::Status onResult(
+ const ::std::optional<ExecutableMethodFileOffsets>& offsets) override {
+ promise_.set_value(offsets);
+ return android::binder::Status::ok();
+ }
+
+ std::optional<ExecutableMethodFileOffsets> waitForResult() {
+ std::future<std::optional<ExecutableMethodFileOffsets>> futureResult =
+ promise_.get_future();
+ auto futureStatus = futureResult.wait_for(
+ std::chrono::seconds(1 * android::base::HwTimeoutMultiplier()));
+ if (futureStatus == std::future_status::ready) {
+ return futureResult.get();
+ } else {
+ return std::nullopt;
+ }
+ }
+
+private:
+ std::promise<std::optional<ExecutableMethodFileOffsets>> promise_;
+};
+
int32_t ADynamicInstrumentationManager_getExecutableMethodFileOffsets(
const ADynamicInstrumentationManager_TargetProcess* targetProcess,
const ADynamicInstrumentationManager_MethodDescriptor* methodDescriptor,
@@ -150,15 +181,15 @@
return INVALID_OPERATION;
}
- std::optional<android::os::instrumentation::ExecutableMethodFileOffsets> offsets;
+ android::sp<ResultCallback> resultCallback = android::sp<ResultCallback>::make();
binder_status_t result =
service->getExecutableMethodFileOffsets(targetProcessParcel, methodDescriptorParcel,
- &offsets)
+ resultCallback)
.exceptionCode();
if (result != OK) {
return result;
}
-
+ std::optional<ExecutableMethodFileOffsets> offsets = resultCallback->waitForResult();
if (offsets != std::nullopt) {
auto* value = new ADynamicInstrumentationManager_ExecutableMethodFileOffsets();
value->containerPath = offsets->containerPath;
@@ -170,4 +201,4 @@
}
return result;
-}
\ No newline at end of file
+}
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 1945d90..9257901 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -22,6 +22,7 @@
#include <aidl/android/hardware/power/SessionHint.h>
#include <aidl/android/hardware/power/SessionMode.h>
#include <aidl/android/hardware/power/SessionTag.h>
+#include <aidl/android/hardware/power/SupportInfo.h>
#include <aidl/android/hardware/power/WorkDuration.h>
#include <aidl/android/hardware/power/WorkDurationFixedV1.h>
#include <aidl/android/os/IHintManager.h>
@@ -148,10 +149,36 @@
std::future<bool> mChannelCreationFinished;
};
+class SupportInfoWrapper {
+public:
+ SupportInfoWrapper(hal::SupportInfo& info);
+ bool isSessionModeSupported(hal::SessionMode mode);
+ bool isSessionHintSupported(hal::SessionHint hint);
+
+private:
+ template <class T>
+ bool getEnumSupportFromBitfield(T& enumValue, int64_t& supportBitfield) {
+ // extract the bit corresponding to the enum by shifting the bitfield
+ // over that much and cutting off any extra values
+ return (supportBitfield >> static_cast<int>(enumValue)) % 2;
+ }
+ hal::SupportInfo mSupportInfo;
+};
+
+class HintManagerClient : public IHintManager::BnHintManagerClient {
+public:
+ // Currently a no-op that exists for FMQ init to call in the future
+ ndk::ScopedAStatus receiveChannelConfig(const hal::ChannelConfig&) {
+ return ndk::ScopedAStatus::ok();
+ }
+};
+
struct APerformanceHintManager {
public:
static APerformanceHintManager* getInstance();
- APerformanceHintManager(std::shared_ptr<IHintManager>& service, int64_t preferredRateNanos);
+ APerformanceHintManager(std::shared_ptr<IHintManager>& service,
+ IHintManager::HintManagerClientData&& clientData,
+ std::shared_ptr<HintManagerClient> callbackClient);
APerformanceHintManager() = delete;
~APerformanceHintManager();
@@ -169,29 +196,21 @@
FMQWrapper& getFMQWrapper();
bool canSendLoadHints(std::vector<hal::SessionHint>& hints, int64_t now) REQUIRES(sHintMutex);
void initJava(JNIEnv* _Nonnull env);
- ndk::ScopedAIBinder_Weak x;
template <class T>
static void layersFromNativeSurfaces(ANativeWindow** windows, int numWindows,
ASurfaceControl** controls, int numSurfaceControls,
std::vector<T>& out);
+ ndk::SpAIBinder& getToken();
+ SupportInfoWrapper& getSupportInfo();
private:
- // Necessary to create an empty binder object
- static void* tokenStubOnCreate(void*) {
- return nullptr;
- }
- static void tokenStubOnDestroy(void*) {}
- static binder_status_t tokenStubOnTransact(AIBinder*, transaction_code_t, const AParcel*,
- AParcel*) {
- return STATUS_OK;
- }
-
static APerformanceHintManager* create(std::shared_ptr<IHintManager> iHintManager);
std::shared_ptr<IHintManager> mHintManager;
+ std::shared_ptr<HintManagerClient> mCallbackClient;
+ IHintManager::HintManagerClientData mClientData;
+ SupportInfoWrapper mSupportInfoWrapper;
ndk::SpAIBinder mToken;
- const int64_t mPreferredRateNanos;
- std::optional<int32_t> mMaxGraphicsPipelineThreadsCount;
FMQWrapper mFMQWrapper;
double mHintBudget = kMaxLoadHintsPerInterval;
int64_t mLastBudgetReplenish = 0;
@@ -273,14 +292,27 @@
return APerformanceHintManager::getInstance()->getFMQWrapper();
}
+// ===================================== SupportInfoWrapper implementation
+
+SupportInfoWrapper::SupportInfoWrapper(hal::SupportInfo& info) : mSupportInfo(info) {}
+
+bool SupportInfoWrapper::isSessionHintSupported(hal::SessionHint hint) {
+ return getEnumSupportFromBitfield(hint, mSupportInfo.sessionHints);
+}
+
+bool SupportInfoWrapper::isSessionModeSupported(hal::SessionMode mode) {
+ return getEnumSupportFromBitfield(mode, mSupportInfo.sessionModes);
+}
+
// ===================================== APerformanceHintManager implementation
APerformanceHintManager::APerformanceHintManager(std::shared_ptr<IHintManager>& manager,
- int64_t preferredRateNanos)
- : mHintManager(std::move(manager)), mPreferredRateNanos(preferredRateNanos) {
- static AIBinder_Class* tokenBinderClass =
- AIBinder_Class_define("phm_token", tokenStubOnCreate, tokenStubOnDestroy,
- tokenStubOnTransact);
- mToken = ndk::SpAIBinder(AIBinder_new(tokenBinderClass, nullptr));
+ IHintManager::HintManagerClientData&& clientData,
+ std::shared_ptr<HintManagerClient> callbackClient)
+ : mHintManager(std::move(manager)),
+ mCallbackClient(callbackClient),
+ mClientData(clientData),
+ mSupportInfoWrapper(clientData.supportInfo),
+ mToken(callbackClient->asBinder()) {
if (mFMQWrapper.isSupported()) {
mFMQWrapper.setToken(mToken);
mFMQWrapper.startChannel(mHintManager.get());
@@ -315,16 +347,17 @@
ALOGE("%s: PerformanceHint service is not ready ", __FUNCTION__);
return nullptr;
}
- int64_t preferredRateNanos = -1L;
- ndk::ScopedAStatus ret = manager->getHintSessionPreferredRate(&preferredRateNanos);
+ std::shared_ptr<HintManagerClient> client = ndk::SharedRefBase::make<HintManagerClient>();
+ IHintManager::HintManagerClientData clientData;
+ ndk::ScopedAStatus ret = manager->registerClient(client, &clientData);
if (!ret.isOk()) {
- ALOGE("%s: PerformanceHint cannot get preferred rate. %s", __FUNCTION__, ret.getMessage());
+ ALOGE("%s: PerformanceHint is not supported. %s", __FUNCTION__, ret.getMessage());
return nullptr;
}
- if (preferredRateNanos <= 0) {
- preferredRateNanos = -1L;
+ if (clientData.preferredRateNanos <= 0) {
+ clientData.preferredRateNanos = -1L;
}
- return new APerformanceHintManager(manager, preferredRateNanos);
+ return new APerformanceHintManager(manager, std::move(clientData), client);
}
bool APerformanceHintManager::canSendLoadHints(std::vector<hal::SessionHint>& hints, int64_t now) {
@@ -389,7 +422,9 @@
ALOGE("%s: PerformanceHint cannot create session. %s", __FUNCTION__, ret.getMessage());
return nullptr;
}
- auto out = new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos,
+
+ auto out = new APerformanceHintSession(mHintManager, std::move(session),
+ mClientData.preferredRateNanos,
sessionCreationConfig->targetWorkDurationNanos, isJava,
sessionConfig.id == -1
? std::nullopt
@@ -416,24 +451,11 @@
}
int64_t APerformanceHintManager::getPreferredRateNanos() const {
- return mPreferredRateNanos;
+ return mClientData.preferredRateNanos;
}
int32_t APerformanceHintManager::getMaxGraphicsPipelineThreadsCount() {
- if (!mMaxGraphicsPipelineThreadsCount.has_value()) {
- int32_t threadsCount = -1;
- ndk::ScopedAStatus ret = mHintManager->getMaxGraphicsPipelineThreadsCount(&threadsCount);
- if (!ret.isOk()) {
- ALOGE("%s: PerformanceHint cannot get max graphics pipeline threads count. %s",
- __FUNCTION__, ret.getMessage());
- return -1;
- }
- if (threadsCount <= 0) {
- threadsCount = -1;
- }
- mMaxGraphicsPipelineThreadsCount.emplace(threadsCount);
- }
- return mMaxGraphicsPipelineThreadsCount.value();
+ return mClientData.maxGraphicsPipelineThreads;
}
FMQWrapper& APerformanceHintManager::getFMQWrapper() {
@@ -450,6 +472,14 @@
mJavaInitialized = true;
}
+ndk::SpAIBinder& APerformanceHintManager::getToken() {
+ return mToken;
+}
+
+SupportInfoWrapper& APerformanceHintManager::getSupportInfo() {
+ return mSupportInfoWrapper;
+}
+
// ===================================== APerformanceHintSession implementation
constexpr int kNumEnums = enum_size<hal::SessionHint>();
@@ -1170,7 +1200,7 @@
if (!useNewLoadHintBehavior()) {
return ENOTSUP;
}
- return session->notifyWorkloadReset(cpu, gpu, debugName);
+ return session->notifyWorkloadSpike(cpu, gpu, debugName);
}
int APerformanceHint_setNativeSurfaces(APerformanceHintSession* session,
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index c166e73..e3c10f6 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -56,9 +56,6 @@
const SessionCreationConfig& creationConfig, hal::SessionConfig* config,
std::shared_ptr<IHintSession>* _aidl_return),
(override));
- MOCK_METHOD(ScopedAStatus, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
- MOCK_METHOD(ScopedAStatus, getMaxGraphicsPipelineThreadsCount, (int32_t* _aidl_return),
- (override));
MOCK_METHOD(ScopedAStatus, setHintSessionThreads,
(const std::shared_ptr<IHintSession>& hintSession,
const ::std::vector<int32_t>& tids),
@@ -84,6 +81,11 @@
MOCK_METHOD(ScopedAStatus, getGpuHeadroomMinIntervalMillis, (int64_t* _aidl_return),
(override));
MOCK_METHOD(ScopedAStatus, passSessionManagerBinder, (const SpAIBinder& sessionManager));
+ MOCK_METHOD(ScopedAStatus, registerClient,
+ (const std::shared_ptr<::aidl::android::os::IHintManager::IHintManagerClient>&
+ clientDataIn,
+ ::aidl::android::os::IHintManager::HintManagerClientData* _aidl_return),
+ (override));
MOCK_METHOD(SpAIBinder, asBinder, (), (override));
MOCK_METHOD(bool, isRemote, (), (override));
};
@@ -125,10 +127,9 @@
APerformanceHintManager* createManager() {
APerformanceHint_setUseFMQForTesting(mUsingFMQ);
- ON_CALL(*mMockIHintManager, getHintSessionPreferredRate(_))
- .WillByDefault(DoAll(SetArgPointee<0>(123L), [] { return ScopedAStatus::ok(); }));
- ON_CALL(*mMockIHintManager, getMaxGraphicsPipelineThreadsCount(_))
- .WillByDefault(DoAll(SetArgPointee<0>(5), [] { return ScopedAStatus::ok(); }));
+ ON_CALL(*mMockIHintManager, registerClient(_, _))
+ .WillByDefault(
+ DoAll(SetArgPointee<1>(mClientData), [] { return ScopedAStatus::ok(); }));
return APerformanceHint_getManager();
}
@@ -238,6 +239,20 @@
int kMockQueueSize = 20;
bool mUsingFMQ = false;
+ IHintManager::HintManagerClientData mClientData{
+ .powerHalVersion = 6,
+ .maxGraphicsPipelineThreads = 5,
+ .preferredRateNanos = 123L,
+ .supportInfo{
+ .usesSessions = true,
+ .boosts = 0,
+ .modes = 0,
+ .sessionHints = -1,
+ .sessionModes = -1,
+ .sessionTags = -1,
+ },
+ };
+
int32_t mMaxLoadHintsPerInterval;
int64_t mLoadHintInterval;
@@ -256,12 +271,6 @@
lhs.gpuDurationNanos == rhs.gpuDurationNanos && lhs.durationNanos == rhs.durationNanos;
}
-TEST_F(PerformanceHintTest, TestGetPreferredUpdateRateNanos) {
- APerformanceHintManager* manager = createManager();
- int64_t preferredUpdateRateNanos = APerformanceHint_getPreferredUpdateRateNanos(manager);
- EXPECT_EQ(123L, preferredUpdateRateNanos);
-}
-
TEST_F(PerformanceHintTest, TestSession) {
APerformanceHintManager* manager = createManager();
APerformanceHintSession* session = createSession(manager);
diff --git a/nfc/Android.bp b/nfc/Android.bp
index 7ad8c4c..abe0ab7 100644
--- a/nfc/Android.bp
+++ b/nfc/Android.bp
@@ -37,6 +37,7 @@
java_sdk_library {
name: "framework-nfc",
libs: [
+ "androidx.annotation_annotation",
"unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
"framework-permission-s.stubs.module_lib",
"framework-permission.stubs.module_lib",
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index e97b15d..cf11ac0 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -85,6 +85,10 @@
field public static final int HCE_ACTIVATE = 1; // 0x1
field public static final int HCE_DATA_TRANSFERRED = 2; // 0x2
field public static final int HCE_DEACTIVATE = 3; // 0x3
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_A = 1; // 0x1
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_B = 2; // 0x2
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_F = 4; // 0x4
+ field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_NONE = 0; // 0x0
field public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2; // 0x2
field public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1; // 0x1
field public static final int STATUS_OK = 0; // 0x0
@@ -250,6 +254,7 @@
field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1; // 0x1
field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3; // 0x3
field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0; // 0x0
+ field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_UNKNOWN = -1; // 0xffffffff
}
}
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index fb11875..b46e343 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -150,28 +150,24 @@
/**
* Technology Type for {@link #getActiveNfceeList()}.
- * @hide
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
public static final int NFCEE_TECH_NONE = 0;
/**
* Technology Type for {@link #getActiveNfceeList()}.
- * @hide
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
public static final int NFCEE_TECH_A = 1;
/**
* Technology Type for {@link #getActiveNfceeList()}.
- * @hide
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
public static final int NFCEE_TECH_B = 1 << 1;
/**
* Technology Type for {@link #getActiveNfceeList()}.
- * @hide
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
public static final int NFCEE_TECH_F = 1 << 2;
@@ -670,12 +666,15 @@
/**
* Get the Active NFCEE (NFC Execution Environment) List
*
- * @see Reader#getName() for the list of possible NFCEE names.
- *
* @return Map< String, @NfceeTechnology Integer >
* A HashMap where keys are activated secure elements and
- * the values are bitmap of technologies supported by each secure element
- * on success keys can contain "eSE" and "UICC", otherwise empty map.
+ * the values are bitmap of technologies supported by each secure element:
+ * NFCEE_TECH_A == 0x1
+ * NFCEE_TECH_B == 0x2
+ * NFCEE_TECH_F == 0x4
+ * and keys can contain "eSE" and "SIM" with a number,
+ * in case of failure an empty map is returned.
+ * @see Reader#getName() for the list of possible NFCEE names.
*/
@NonNull
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index 8037702..e0bc15f 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -1114,6 +1114,14 @@
@FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3;
+ /**
+ * Setting the default subscription ID failed because of unknown error.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+ public static final int SET_SUBSCRIPTION_ID_STATUS_UNKNOWN = -1;
+
/** @hide */
@IntDef(prefix = "SET_SUBSCRIPTION_ID_STATUS_",
value = {
@@ -1121,6 +1129,7 @@
SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID,
SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR,
SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED,
+ SET_SUBSCRIPTION_ID_STATUS_UNKNOWN
})
@Retention(RetentionPolicy.SOURCE)
public @interface SetSubscriptionIdStatus {}
@@ -1129,9 +1138,10 @@
* Sets the system's default NFC subscription id.
*
* <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this sets the
- * default UICC NFCEE that will handle NFC offhost CE transactoions </p>
+ * default UICC NFCEE that will handle NFC offhost CE transactions </p>
*
- * @param subscriptionId the default NFC subscription Id to set.
+ * @param subscriptionId the default NFC subscription Id to set. User can get subscription id
+ * from {@link SubscriptionManager#getSubscriptionId(int)}
* @return status of the operation.
*
* @throws UnsupportedOperationException If the device does not have
@@ -1153,7 +1163,7 @@
* Returns the system's default NFC subscription id.
*
* <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this returns the
- * default UICC NFCEE that will handle NFC offhost CE transactoions </p>
+ * default UICC NFCEE that will handle NFC offhost CE transactions </p>
* <p> If the device has no UICC that can serve as NFCEE, this will return
* {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.</p>
*
diff --git a/nfc/tests/Android.bp b/nfc/tests/Android.bp
index bfa814d..b6090e8 100644
--- a/nfc/tests/Android.bp
+++ b/nfc/tests/Android.bp
@@ -25,17 +25,36 @@
android_test {
name: "NfcManagerTests",
static_libs: [
- "androidx.test.ext.junit",
+ "androidx.test.core",
"androidx.test.rules",
- "mockito-target-minus-junit4",
+ "androidx.test.runner",
+ "androidx.test.ext.junit",
+ "framework-nfc.impl",
+ "mockito-target-extended-minus-junit4",
+ "frameworks-base-testutils",
"truth",
+ "androidx.annotation_annotation",
+ "androidx.appcompat_appcompat",
+ "flag-junit",
+ "platform-test-annotations",
+ "testables",
],
libs: [
- "framework-nfc.impl",
+ "android.test.base.stubs.system",
+ "android.test.mock.stubs.system",
"android.test.runner.stubs.system",
],
+ jni_libs: [
+ // Required for ExtendedMockito
+ "libdexmakerjvmtiagent",
+ "libstaticjvmtiagent",
+ ],
srcs: ["src/**/*.java"],
platform_apis: true,
certificate: "platform",
- test_suites: ["device-tests"],
+ test_suites: [
+ "device-tests",
+ "mts-nfc",
+ ],
+ min_sdk_version: "35", // Should be 36 later.
}
diff --git a/nfc/tests/AndroidManifest.xml b/nfc/tests/AndroidManifest.xml
index 99e2c34c..9564672 100644
--- a/nfc/tests/AndroidManifest.xml
+++ b/nfc/tests/AndroidManifest.xml
@@ -17,7 +17,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.nfc">
- <application>
+ <application android:debuggable="true">
<uses-library android:name="android.test.runner" />
</application>
diff --git a/packages/CrashRecovery/framework/Android.bp b/packages/CrashRecovery/framework/Android.bp
index 43d8a62..1a3446ec 100644
--- a/packages/CrashRecovery/framework/Android.bp
+++ b/packages/CrashRecovery/framework/Android.bp
@@ -14,7 +14,11 @@
name: "framework-platformcrashrecovery",
srcs: [":framework-crashrecovery-sources"],
defaults: ["framework-non-updatable-unbundled-defaults"],
- permitted_packages: ["android.service.watchdog"],
+ permitted_packages: [
+ "android.service.watchdog",
+ "android.crashrecovery",
+ ],
+ static_libs: ["android.crashrecovery.flags-aconfig-java"],
aidl: {
include_dirs: [
"frameworks/base/core/java",
diff --git a/packages/CrashRecovery/framework/api/system-current.txt b/packages/CrashRecovery/framework/api/system-current.txt
index 3a48a4a..68429ea 100644
--- a/packages/CrashRecovery/framework/api/system-current.txt
+++ b/packages/CrashRecovery/framework/api/system-current.txt
@@ -9,7 +9,9 @@
method @NonNull public abstract java.util.List<java.lang.String> onGetRequestedPackages();
method @NonNull public abstract java.util.List<android.service.watchdog.ExplicitHealthCheckService.PackageConfig> onGetSupportedPackages();
method public abstract void onRequestHealthCheck(@NonNull String);
+ method @FlaggedApi("android.crashrecovery.flags.enable_crashrecovery") public final void setHealthCheckResultCallback(@Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<android.os.Bundle>);
field public static final String BIND_PERMISSION = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
+ field @FlaggedApi("android.crashrecovery.flags.enable_crashrecovery") public static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE = "android.service.watchdog.extra.HEALTH_CHECK_PASSED_PACKAGE";
field public static final String SERVICE_INTERFACE = "android.service.watchdog.ExplicitHealthCheckService";
}
diff --git a/packages/CrashRecovery/framework/api/test-current.txt b/packages/CrashRecovery/framework/api/test-current.txt
index 54f501f..d802177 100644
--- a/packages/CrashRecovery/framework/api/test-current.txt
+++ b/packages/CrashRecovery/framework/api/test-current.txt
@@ -1,9 +1 @@
// Signature format: 2.0
-package android.service.watchdog {
-
- public abstract class ExplicitHealthCheckService extends android.app.Service {
- method public void setCallback(@Nullable android.os.RemoteCallback);
- }
-
-}
-
diff --git a/packages/CrashRecovery/framework/java/android/service/watchdog/ExplicitHealthCheckService.java b/packages/CrashRecovery/framework/java/android/service/watchdog/ExplicitHealthCheckService.java
index 7befbfb..b03e376 100644
--- a/packages/CrashRecovery/framework/java/android/service/watchdog/ExplicitHealthCheckService.java
+++ b/packages/CrashRecovery/framework/java/android/service/watchdog/ExplicitHealthCheckService.java
@@ -18,15 +18,17 @@
import static android.os.Parcelable.Creator;
+import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.crashrecovery.flags.Flags;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -42,7 +44,9 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
/**
* A service to provide packages supporting explicit health checks and route checks to these
@@ -89,11 +93,10 @@
/**
* {@link Bundle} key for a {@link String} value.
- *
- * {@hide}
*/
+ @FlaggedApi(Flags.FLAG_ENABLE_CRASHRECOVERY)
public static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE =
- "android.service.watchdog.extra.health_check_passed_package";
+ "android.service.watchdog.extra.HEALTH_CHECK_PASSED_PACKAGE";
/**
* The Intent action that a service must respond to. Add it to the intent filter of the service
@@ -152,7 +155,8 @@
@NonNull public abstract List<String> onGetRequestedPackages();
private final Handler mHandler = Handler.createAsync(Looper.getMainLooper());
- @Nullable private RemoteCallback mCallback;
+ @Nullable private Consumer<Bundle> mHealthCheckResultCallback;
+ @Nullable private Executor mCallbackExecutor;
@Override
@NonNull
@@ -161,30 +165,49 @@
}
/**
- * Sets {@link RemoteCallback}, for testing purpose.
+ * Sets a callback to be invoked when an explicit health check passes for a package.
+ * <p>
+ * The callback will receive a {@link Bundle} containing the package name that passed the
+ * health check, identified by the key {@link #EXTRA_HEALTH_CHECK_PASSED_PACKAGE}.
+ * <p>
+ * <b>Note:</b> This API is primarily intended for testing purposes. Calling this outside of a
+ * test environment will override the default callback mechanism used to notify the system
+ * about health check results. Use with caution in production code.
*
- * @hide
+ * @param executor The executor on which the callback should be invoked. If {@code null}, the
+ * callback will be executed on the main thread.
+ * @param callback A callback that receives a {@link Bundle} containing the package name that
+ * passed the health check.
*/
- @TestApi
- public void setCallback(@Nullable RemoteCallback callback) {
- mCallback = callback;
+ @FlaggedApi(Flags.FLAG_ENABLE_CRASHRECOVERY)
+ public final void setHealthCheckResultCallback(@CallbackExecutor @Nullable Executor executor,
+ @Nullable Consumer<Bundle> callback) {
+ mCallbackExecutor = executor;
+ mHealthCheckResultCallback = callback;
}
+
+ private void executeCallback(@NonNull String packageName) {
+ if (mHealthCheckResultCallback != null) {
+ Objects.requireNonNull(packageName,
+ "Package passing explicit health check must be non-null");
+ Bundle bundle = new Bundle();
+ bundle.putString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE, packageName);
+ mHealthCheckResultCallback.accept(bundle);
+ } else {
+ Log.wtf(TAG, "System missed explicit health check result for " + packageName);
+ }
+ }
+
/**
* Implementors should call this to notify the system when explicit health check passes
* for {@code packageName};
*/
public final void notifyHealthCheckPassed(@NonNull String packageName) {
- mHandler.post(() -> {
- if (mCallback != null) {
- Objects.requireNonNull(packageName,
- "Package passing explicit health check must be non-null");
- Bundle bundle = new Bundle();
- bundle.putString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE, packageName);
- mCallback.sendResult(bundle);
- } else {
- Log.wtf(TAG, "System missed explicit health check result for " + packageName);
- }
- });
+ if (mCallbackExecutor != null) {
+ mCallbackExecutor.execute(() -> executeCallback(packageName));
+ } else {
+ mHandler.post(() -> executeCallback(packageName));
+ }
}
/**
@@ -296,9 +319,7 @@
private class ExplicitHealthCheckServiceWrapper extends IExplicitHealthCheckService.Stub {
@Override
public void setCallback(RemoteCallback callback) throws RemoteException {
- mHandler.post(() -> {
- mCallback = callback;
- });
+ mHandler.post(() -> mHealthCheckResultCallback = callback::sendResult);
}
@Override
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
index 560e751..8b8ab58 100644
--- a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
@@ -770,19 +770,19 @@
* The minimum value that can be returned by any observer.
* It represents that no mitigations were available.
*/
- public static final int LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT =
+ public static final int USER_IMPACT_THRESHOLD_NONE =
PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
/**
* The mitigation impact beyond which the user will start noticing the mitigations.
*/
- public static final int MEDIUM_USER_IMPACT_THRESHOLD =
+ public static final int USER_IMPACT_THRESHOLD_MEDIUM =
PackageHealthObserverImpact.USER_IMPACT_LEVEL_20;
/**
* The mitigation impact beyond which the user impact is severely high.
*/
- public static final int HIGH_USER_IMPACT_THRESHOLD =
+ public static final int USER_IMPACT_THRESHOLD_HIGH =
PackageHealthObserverImpact.USER_IMPACT_LEVEL_71;
/**
@@ -827,11 +827,9 @@
public interface PackageHealthObserver {
/**
* Called when health check fails for the {@code versionedPackage}.
- *
- * Note: if the returned user impact is higher than
- * {@link #DEFAULT_HIGH_USER_IMPACT_THRESHOLD}, then
- * {@link #onExecuteHealthCheckMitigation} would be called only in severe device conditions
- * like boot-loop or network failure.
+ * Note: if the returned user impact is higher than {@link #USER_IMPACT_THRESHOLD_HIGH},
+ * then {@link #onExecuteHealthCheckMitigation} would be called only in severe device
+ * conditions like boot-loop or network failure.
*
* @param versionedPackage the package that is failing. This may be null if a native
* service is crashing.
@@ -839,9 +837,9 @@
* @param mitigationCount the number of times mitigation has been called for this package
* (including this time).
*
- *
- * @return any value greater than {@link #LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT} to express
- * the impact of mitigation on the user in {@link #onExecuteHealthCheckMitigation}
+ * @return any value greater than {@link #USER_IMPACT_THRESHOLD_NONE} to express
+ * the impact of mitigation on the user in {@link #onExecuteHealthCheckMitigation}.
+ * Returning {@link #USER_IMPACT_THRESHOLD_NONE} would indicate no mitigations available.
*/
@PackageHealthObserverImpact int onHealthCheckFailed(
@Nullable VersionedPackage versionedPackage,
@@ -871,8 +869,9 @@
* @param mitigationCount the number of times mitigation has been attempted for this
* boot loop (including this time).
*
- * @return any value greater than {@link #LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT} to express
- * the impact of mitigation on the user in {@link #onExecuteBootLoopMitigation}
+ * @return any value greater than {@link #USER_IMPACT_THRESHOLD_NONE} to express
+ * the impact of mitigation on the user in {@link #onExecuteBootLoopMitigation}.
+ * Returning {@link #USER_IMPACT_THRESHOLD_NONE} would indicate no mitigations available.
*/
default @PackageHealthObserverImpact int onBootLoop(int mitigationCount) {
return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
diff --git a/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_middle.xml b/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_middle.xml
index 781373d..327f4220 100644
--- a/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_middle.xml
+++ b/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_middle.xml
@@ -19,6 +19,6 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:tools="http://schemas.android.com/tools" tools:ignore="NewApi">
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
</shape>
</inset>
\ No newline at end of file
diff --git a/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one.xml b/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one.xml
index f28c354..992fe33 100644
--- a/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one.xml
+++ b/packages/CredentialManager/res/drawable/fill_dialog_dynamic_list_item_one.xml
@@ -21,6 +21,6 @@
<shape android:shape="rectangle">
<corners android:topLeftRadius="4dp" android:topRightRadius="4dp"
android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp"/>
- <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
</shape>
</inset>
\ No newline at end of file
diff --git a/packages/CredentialManager/res/drawable/more_options_list_item.xml b/packages/CredentialManager/res/drawable/more_options_list_item.xml
index 3f9d815..991b3ff 100644
--- a/packages/CredentialManager/res/drawable/more_options_list_item.xml
+++ b/packages/CredentialManager/res/drawable/more_options_list_item.xml
@@ -24,7 +24,7 @@
<shape>
<corners android:topLeftRadius="0dp" android:topRightRadius="0dp"
android:bottomLeftRadius="4dp" android:bottomRightRadius="4dp"/>
- <solid android:color="?androidprv:attr/materialColorSurfaceContainer"/>
- <stroke android:color="?androidprv:attr/materialColorOutlineVariant" android:width="1dp"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceContainer"/>
+ <stroke android:color="@androidprv:color/materialColorOutlineVariant" android:width="1dp"/>
</shape>
</inset>
\ No newline at end of file
diff --git a/packages/CredentialManager/res/layout/credman_dropdown_bottom_sheet.xml b/packages/CredentialManager/res/layout/credman_dropdown_bottom_sheet.xml
index 914987a..6f04bd9 100644
--- a/packages/CredentialManager/res/layout/credman_dropdown_bottom_sheet.xml
+++ b/packages/CredentialManager/res/layout/credman_dropdown_bottom_sheet.xml
@@ -35,7 +35,7 @@
android:layout_gravity="center"
android:paddingStart="@dimen/autofill_view_left_padding"
android:src="@drawable/more_horiz_24px"
- android:tint="?androidprv:attr/materialColorOnSurface"
+ android:tint="@androidprv:color/materialColorOnSurface"
android:contentDescription="@string/more_options_content_description"
android:background="@null"/>
@@ -53,7 +53,7 @@
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
style="@style/autofill.TextTitle"/>
</LinearLayout>
diff --git a/packages/CredentialManager/res/layout/credman_dropdown_presentation_layout.xml b/packages/CredentialManager/res/layout/credman_dropdown_presentation_layout.xml
index 3fc6154..d00a229 100644
--- a/packages/CredentialManager/res/layout/credman_dropdown_presentation_layout.xml
+++ b/packages/CredentialManager/res/layout/credman_dropdown_presentation_layout.xml
@@ -35,7 +35,7 @@
android:layout_gravity="center"
android:layout_alignParentStart="true"
android:paddingStart="@dimen/autofill_view_left_padding"
- app:tint="?androidprv:attr/materialColorOnSurface"
+ app:tint="@androidprv:color/materialColorOnSurface"
android:background="@null"/>
<LinearLayout
@@ -53,7 +53,7 @@
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textDirection="locale"
style="@style/autofill.TextTitle"/>
@@ -61,7 +61,7 @@
android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
android:textDirection="locale"
style="@style/autofill.TextSubtitle"/>
diff --git a/packages/CredentialManager/res/values/colors.xml b/packages/CredentialManager/res/values/colors.xml
index 9d31b35..8d37d47 100644
--- a/packages/CredentialManager/res/values/colors.xml
+++ b/packages/CredentialManager/res/values/colors.xml
@@ -19,8 +19,8 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<!-- These colors are used for Remote Views. -->
- <color name="onSurface">?androidprv:attr/materialColorOnSurface</color>
- <color name="onSurfaceVariant">?androidprv:attr/materialColorOnSurfaceVariant</color>
- <color name="surfaceDim">?androidprv:attr/materialColorSurfaceDim</color>
- <color name="surfaceContainer">?androidprv:attr/materialColorSurfaceContainer</color>
+ <color name="onSurface">@androidprv:color/materialColorOnSurface</color>
+ <color name="onSurfaceVariant">@androidprv:color/materialColorOnSurfaceVariant</color>
+ <color name="surfaceDim">@androidprv:color/materialColorSurfaceDim</color>
+ <color name="surfaceContainer">@androidprv:color/materialColorSurfaceContainer</color>
</resources>
\ No newline at end of file
diff --git a/packages/CredentialManager/wear/res/values-hi/strings.xml b/packages/CredentialManager/wear/res/values-hi/strings.xml
index a061453..405d3f8 100644
--- a/packages/CredentialManager/wear/res/values-hi/strings.xml
+++ b/packages/CredentialManager/wear/res/values-hi/strings.xml
@@ -22,8 +22,8 @@
<string name="use_password_title" msgid="4655101984031246476">"क्या आपको पासवर्ड का इस्तेमाल करना है?"</string>
<string name="dialog_dismiss_button" msgid="989567669882005067">"खारिज करें"</string>
<string name="dialog_continue_button" msgid="8630290044077052145">"जारी रखें"</string>
- <string name="dialog_sign_in_options_button" msgid="448002958902615054">"साइन इन करने के विकल्प"</string>
- <string name="sign_in_options_title" msgid="6720572645638986680">"साइन इन करने के विकल्प"</string>
+ <string name="dialog_sign_in_options_button" msgid="448002958902615054">"साइन-इन करने के विकल्प"</string>
+ <string name="sign_in_options_title" msgid="6720572645638986680">"साइन-इन करने के विकल्प"</string>
<string name="provider_list_title" msgid="6803918216129492212">"साइन-इन क्रेडेंशियल मैनेज करें"</string>
<string name="choose_sign_in_title" msgid="3616025924746872202">"साइन इन करने का कोई तरीका चुनें"</string>
<string name="choose_passkey_title" msgid="8459270617632817465">"कोई पासकी चुनें"</string>
diff --git a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/BundleUtil.java b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/BundleUtil.java
index 53ef9e8..2626cc8 100644
--- a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/BundleUtil.java
+++ b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/BundleUtil.java
@@ -21,6 +21,7 @@
import static android.system.OsConstants.O_RDONLY;
import static android.system.OsConstants.PROT_READ;
+import android.annotation.SuppressLint;
import android.app.ondeviceintelligence.IResponseCallback;
import android.app.ondeviceintelligence.IStreamingResponseCallback;
import android.app.ondeviceintelligence.ITokenInfoCallback;
@@ -328,6 +329,7 @@
(value instanceof Boolean) || (value instanceof boolean[]);
}
+ @SuppressLint("NewApi")
private static void ensureValidBundle(Bundle bundle) {
if (bundle == null) {
throw new IllegalArgumentException("Request passed is expected to be non-null");
diff --git a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
index 607ec1c..0237fe7 100644
--- a/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
+++ b/packages/NeuralNetworks/service/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
@@ -16,8 +16,6 @@
package com.android.server.ondeviceintelligence;
-import static android.app.ondeviceintelligence.flags.Flags.enableOnDeviceIntelligenceModule;
-
import static android.app.ondeviceintelligence.OnDeviceIntelligenceManager.ON_DEVICE_INTELLIGENCE_IDLE_TIMEOUT_MS;
import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.DEVICE_CONFIG_UPDATE_BUNDLE_KEY;
import static android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService.MODEL_LOADED_BROADCAST_INTENT;
@@ -180,10 +178,8 @@
publishBinderService(
Context.ON_DEVICE_INTELLIGENCE_SERVICE, getOnDeviceIntelligenceManagerService(),
/* allowIsolated = */ true);
- if (enableOnDeviceIntelligenceModule()) {
- LocalManagerRegistry.addManager(OnDeviceIntelligenceManagerLocal.class,
+ LocalManagerRegistry.addManager(OnDeviceIntelligenceManagerLocal.class,
this::getRemoteInferenceServiceUid);
- }
}
@Override
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml
index 8d6f0da4..fdc5975 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml
@@ -20,7 +20,7 @@
xmlns:tools="http://schemas.android.com/tools"
tools:targetApi="28"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
<corners
android:topLeftRadius="?android:attr/dialogCornerRadius"
android:topRightRadius="0dp"
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml
index 3072772..405c452 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_right_bk.xml
@@ -20,7 +20,7 @@
xmlns:tools="http://schemas.android.com/tools"
tools:targetApi="28"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
<corners
android:topLeftRadius="0dp"
android:topRightRadius="?android:attr/dialogCornerRadius"
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml
index f1790f9..187e612 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/rounded_bk.xml
@@ -20,7 +20,7 @@
xmlns:tools="http://schemas.android.com/tools"
tools:targetApi="28"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
<corners
android:radius="?android:attr/dialogCornerRadius"
/>
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_bk.xml
index d56c843..0182b4c 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_bk.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/square_bk.xml
@@ -18,7 +18,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
<corners
android:radius="0dp"
/>
diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyValueStore.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyValueStore.kt
index 5f1f8df..472ffa9 100644
--- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyValueStore.kt
+++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyValueStore.kt
@@ -47,6 +47,37 @@
* @param value value to set, null means remove
*/
fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?)
+
+ /** Gets the boolean value of given key. */
+ fun getBoolean(key: String): Boolean? = getValue(key, Boolean::class.javaObjectType)
+
+ /** Sets boolean value for given key, null value means delete the key from data store. */
+ fun setBoolean(key: String, value: Boolean?) =
+ setValue(key, Boolean::class.javaObjectType, value)
+
+ /** Gets the float value of given key. */
+ fun getFloat(key: String): Float? = getValue(key, Float::class.javaObjectType)
+
+ /** Sets float value for given key, null value means delete the key from data store. */
+ fun setFloat(key: String, value: Float?) = setValue(key, Float::class.javaObjectType, value)
+
+ /** Gets the int value of given key. */
+ fun getInt(key: String): Int? = getValue(key, Int::class.javaObjectType)
+
+ /** Sets int value for given key, null value means delete the key from data store. */
+ fun setInt(key: String, value: Int?) = setValue(key, Int::class.javaObjectType, value)
+
+ /** Gets the long value of given key. */
+ fun getLong(key: String): Long? = getValue(key, Long::class.javaObjectType)
+
+ /** Sets long value for given key, null value means delete the key from data store. */
+ fun setLong(key: String, value: Long?) = setValue(key, Long::class.javaObjectType, value)
+
+ /** Gets the string value of given key. */
+ fun getString(key: String): String? = getValue(key, String::class.javaObjectType)
+
+ /** Sets string value for given key, null value means delete the key from data store. */
+ fun setString(key: String, value: String?) = setValue(key, String::class.javaObjectType, value)
}
/** [SharedPreferences] based [KeyValueStore]. */
diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsStore.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsStore.kt
index d6e7a89..3f1a4998 100644
--- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsStore.kt
+++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsStore.kt
@@ -50,37 +50,6 @@
contentResolver.unregisterContentObserver(contentObserver)
}
- /** Gets the boolean value of given key. */
- fun getBoolean(key: String): Boolean? = getValue(key, Boolean::class.javaObjectType)
-
- /** Sets boolean value for given key, null value means delete the key from data store. */
- fun setBoolean(key: String, value: Boolean?) =
- setValue(key, Boolean::class.javaObjectType, value)
-
- /** Gets the float value of given key. */
- fun getFloat(key: String): Float? = getValue(key, Float::class.javaObjectType)
-
- /** Sets float value for given key, null value means delete the key from data store. */
- fun setFloat(key: String, value: Float?) = setValue(key, Float::class.javaObjectType, value)
-
- /** Gets the int value of given key. */
- fun getInt(key: String): Int? = getValue(key, Int::class.javaObjectType)
-
- /** Sets int value for given key, null value means delete the key from data store. */
- fun setInt(key: String, value: Int?) = setValue(key, Int::class.javaObjectType, value)
-
- /** Gets the long value of given key. */
- fun getLong(key: String): Long? = getValue(key, Long::class.javaObjectType)
-
- /** Sets long value for given key, null value means delete the key from data store. */
- fun setLong(key: String, value: Long?) = setValue(key, Long::class.javaObjectType, value)
-
- /** Gets the string value of given key. */
- fun getString(key: String): String? = getValue(key, String::class.javaObjectType)
-
- /** Sets string value for given key, null value means delete the key from data store. */
- fun setString(key: String, value: String?) = setValue(key, String::class.javaObjectType, value)
-
/** Tag for logging. */
abstract val tag: String
}
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
index a768b5e..606710e 100644
--- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
@@ -55,9 +55,9 @@
import com.android.settingslib.metadata.ReadWritePermit
import com.android.settingslib.preference.PreferenceScreenFactory
import com.android.settingslib.preference.PreferenceScreenProvider
+import java.util.Locale
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
-import java.util.Locale
private const val TAG = "PreferenceGraphBuilder"
@@ -399,15 +399,11 @@
value = preferenceValueProto {
when (metadata) {
is BooleanValue ->
- metadata
- .storage(context)
- .getValue(metadata.key, Boolean::class.javaObjectType)
- ?.let { booleanValue = it }
+ metadata.storage(context).getBoolean(metadata.key)?.let {
+ booleanValue = it
+ }
is RangeValue -> {
- metadata
- .storage(context)
- .getValue(metadata.key, Int::class.javaObjectType)
- ?.let { intValue = it }
+ metadata.storage(context).getInt(metadata.key)?.let { intValue = it }
}
else -> {}
}
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt
index 7cfce0d..56b1693 100644
--- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt
@@ -146,7 +146,7 @@
val booleanValue = value.booleanValue
val resultCode = metadata.checkWritePermit(booleanValue)
if (resultCode != PreferenceSetterResult.OK) return resultCode
- storage.setValue(key, Boolean::class.javaObjectType, booleanValue)
+ storage.setBoolean(key, booleanValue)
return PreferenceSetterResult.OK
} else if (value.hasIntValue()) {
val intValue = value.intValue
@@ -155,7 +155,7 @@
if (metadata is RangeValue && !metadata.isValidValue(application, intValue)) {
return PreferenceSetterResult.INVALID_REQUEST
}
- storage.setValue(key, Int::class.javaObjectType, intValue)
+ storage.setInt(key, intValue)
return PreferenceSetterResult.OK
}
} catch (e: Exception) {
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt
index 6704ecc..3dd1594 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceStateProviders.kt
@@ -21,6 +21,7 @@
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.LifecycleCoroutineScope
+import com.android.settingslib.datastore.KeyValueStore
import kotlinx.coroutines.CoroutineScope
/**
@@ -157,6 +158,9 @@
*/
abstract fun <T : Any> requirePreference(key: String): T
+ /** Returns the [KeyValueStore] attached to the preference of given key *on the same screen*. */
+ abstract fun getKeyValueStore(key: String): KeyValueStore?
+
/** Notifies that preference state of given key is changed and updates preference widget UI. */
abstract fun notifyPreferenceChange(key: String)
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceTypes.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceTypes.kt
index b64f5dc..512ea3d 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceTypes.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceTypes.kt
@@ -26,8 +26,7 @@
interface TwoStatePreference : PreferenceMetadata, PersistentPreference<Boolean>, BooleanValue {
override fun shouldDisableDependents(context: Context) =
- storage(context).getValue(key, Boolean::class.javaObjectType) != true ||
- super.shouldDisableDependents(context)
+ storage(context).getBoolean(key) != true || super.shouldDisableDependents(context)
}
/** A preference that provides a two-state toggleable option. */
@@ -42,7 +41,4 @@
/** A preference that provides a two-state toggleable option that can be used as a main switch. */
open class MainSwitchPreference
@JvmOverloads
-constructor(
- override val key: String,
- @StringRes override val title: Int = 0,
-) : TwoStatePreference
\ No newline at end of file
+constructor(override val key: String, @StringRes override val title: Int = 0) : TwoStatePreference
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreAdapter.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreAdapter.kt
index 7601b9a..f0f854a 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreAdapter.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreAdapter.kt
@@ -23,38 +23,31 @@
class PreferenceDataStoreAdapter(val keyValueStore: KeyValueStore) : PreferenceDataStore() {
override fun getBoolean(key: String, defValue: Boolean): Boolean =
- keyValueStore.getValue(key, Boolean::class.javaObjectType) ?: defValue
+ keyValueStore.getBoolean(key) ?: defValue
override fun getFloat(key: String, defValue: Float): Float =
- keyValueStore.getValue(key, Float::class.javaObjectType) ?: defValue
+ keyValueStore.getFloat(key) ?: defValue
- override fun getInt(key: String, defValue: Int): Int =
- keyValueStore.getValue(key, Int::class.javaObjectType) ?: defValue
+ override fun getInt(key: String, defValue: Int): Int = keyValueStore.getInt(key) ?: defValue
- override fun getLong(key: String, defValue: Long): Long =
- keyValueStore.getValue(key, Long::class.javaObjectType) ?: defValue
+ override fun getLong(key: String, defValue: Long): Long = keyValueStore.getLong(key) ?: defValue
override fun getString(key: String, defValue: String?): String? =
- keyValueStore.getValue(key, String::class.javaObjectType) ?: defValue
+ keyValueStore.getString(key) ?: defValue
@Suppress("UNCHECKED_CAST")
override fun getStringSet(key: String, defValues: Set<String>?): Set<String>? =
(keyValueStore.getValue(key, Set::class.javaObjectType) as Set<String>?) ?: defValues
- override fun putBoolean(key: String, value: Boolean) =
- keyValueStore.setValue(key, Boolean::class.javaObjectType, value)
+ override fun putBoolean(key: String, value: Boolean) = keyValueStore.setBoolean(key, value)
- override fun putFloat(key: String, value: Float) =
- keyValueStore.setValue(key, Float::class.javaObjectType, value)
+ override fun putFloat(key: String, value: Float) = keyValueStore.setFloat(key, value)
- override fun putInt(key: String, value: Int) =
- keyValueStore.setValue(key, Int::class.javaObjectType, value)
+ override fun putInt(key: String, value: Int) = keyValueStore.setInt(key, value)
- override fun putLong(key: String, value: Long) =
- keyValueStore.setValue(key, Long::class.javaObjectType, value)
+ override fun putLong(key: String, value: Long) = keyValueStore.setLong(key, value)
- override fun putString(key: String, value: String?) =
- keyValueStore.setValue(key, String::class.javaObjectType, value)
+ override fun putString(key: String, value: String?) = keyValueStore.setString(key, value)
override fun putStringSet(key: String, values: Set<String>?) =
keyValueStore.setValue(key, Set::class.javaObjectType, values)
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 6fc9357..31bb62d 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
@@ -67,6 +67,11 @@
override fun <T : Any> requirePreference(key: String) = findPreference<T>(key)!!
+ override fun getKeyValueStore(key: String) =
+ (findPreference<Preference>(key)?.preferenceDataStore
+ as? PreferenceDataStoreAdapter)
+ ?.keyValueStore
+
override fun notifyPreferenceChange(key: String) =
notifyChange(key, CHANGE_REASON_STATE)
diff --git a/packages/SettingsLib/Spa/build.gradle.kts b/packages/SettingsLib/Spa/build.gradle.kts
index 02e1904..cf695d0 100644
--- a/packages/SettingsLib/Spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/build.gradle.kts
@@ -14,14 +14,13 @@
* limitations under the License.
*/
-import com.android.build.api.dsl.CommonExtension
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.api.AndroidBasePlugin
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
+ alias(libs.plugins.compose.compiler) apply false
alias(libs.plugins.kotlin.android) apply false
}
@@ -51,23 +50,4 @@
}
}
}
-
- afterEvaluate {
- plugins.withType<AndroidBasePlugin> {
- the(CommonExtension::class).apply {
- if (buildFeatures.compose == true) {
- composeOptions {
- kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get()
- }
- }
- }
- }
- }
-
- tasks.withType<KotlinCompile> {
- kotlinOptions {
- jvmTarget = libs.versions.jvm.get()
- freeCompilerArgs = listOf("-Xjvm-default=all")
- }
- }
}
diff --git a/packages/SettingsLib/Spa/gallery/build.gradle.kts b/packages/SettingsLib/Spa/gallery/build.gradle.kts
index a1151a5..19aa710 100644
--- a/packages/SettingsLib/Spa/gallery/build.gradle.kts
+++ b/packages/SettingsLib/Spa/gallery/build.gradle.kts
@@ -16,6 +16,7 @@
plugins {
alias(libs.plugins.android.application)
+ alias(libs.plugins.compose.compiler)
alias(libs.plugins.kotlin.android)
}
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt
index f7649b9..17f9965 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferencePageProvider.kt
@@ -20,11 +20,13 @@
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.DisabledByDefault
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.IntState
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -33,8 +35,11 @@
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.gallery.R
+import com.android.settingslib.spa.widget.preference.ListPreferenceModel
+import com.android.settingslib.spa.widget.preference.ListPreferenceOption
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
+import com.android.settingslib.spa.widget.preference.RadioPreferences
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
import com.android.settingslib.spa.widget.ui.Category
import com.android.settingslib.spa.widget.ui.SettingsIcon
@@ -103,6 +108,22 @@
override val summary = { ticks.toString() }
})
}
+ val selectedId = rememberSaveable { mutableIntStateOf(0) }
+ RadioPreferences(
+ object : ListPreferenceModel {
+ override val title: String = "RadioPreferences"
+ override val options: List<ListPreferenceOption> =
+ listOf(
+ ListPreferenceOption(id = 0, text = "option1"),
+ ListPreferenceOption(id = 1, text = "option2"),
+ ListPreferenceOption(id = 2, text = "option3"),
+ )
+ override val selectedId: IntState = selectedId
+ override val onIdSelected: (Int) -> Unit = {
+ selectedId.intValue = it
+ }
+ }
+ )
}
}
diff --git a/packages/SettingsLib/Spa/gradle/libs.versions.toml b/packages/SettingsLib/Spa/gradle/libs.versions.toml
index 74811d3..04ef96a 100644
--- a/packages/SettingsLib/Spa/gradle/libs.versions.toml
+++ b/packages/SettingsLib/Spa/gradle/libs.versions.toml
@@ -15,12 +15,11 @@
#
[versions]
-agp = "8.7.2"
-compose-compiler = "1.5.11"
+agp = "8.7.3"
dexmaker-mockito = "2.28.3"
jvm = "17"
-kotlin = "1.9.23"
-truth = "1.1.5"
+kotlin = "2.0.21"
+truth = "1.4.4"
[libraries]
dexmaker-mockito = { module = "com.linkedin.dexmaker:dexmaker-mockito", version.ref = "dexmaker-mockito" }
@@ -29,4 +28,5 @@
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }
+compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
diff --git a/packages/SettingsLib/Spa/spa/build.gradle.kts b/packages/SettingsLib/Spa/spa/build.gradle.kts
index 1f32ad6..a0bbb0c 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/spa/build.gradle.kts
@@ -16,6 +16,7 @@
plugins {
alias(libs.plugins.android.library)
+ alias(libs.plugins.compose.compiler)
alias(libs.plugins.kotlin.android)
jacoco
}
@@ -41,9 +42,6 @@
manifest.srcFile("../tests/AndroidManifest.xml")
}
}
- buildFeatures {
- compose = true
- }
buildTypes {
getByName("debug") {
enableAndroidTestCoverage = true
@@ -63,7 +61,7 @@
api("androidx.lifecycle:lifecycle-runtime-compose")
api("androidx.navigation:navigation-compose:2.9.0-alpha03")
api("com.github.PhilJay:MPAndroidChart:v3.1.0-alpha")
- api("com.google.android.material:material:1.12.0")
+ api("com.google.android.material:material:1.13.0-alpha08")
debugApi("androidx.compose.ui:ui-tooling:$jetpackComposeVersion")
implementation("com.airbnb.android:lottie-compose:6.4.0")
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/RadioPreferences.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/RadioPreferences.kt
index 8300ce8..ec94df0 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/RadioPreferences.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/RadioPreferences.kt
@@ -16,28 +16,34 @@
package com.android.settingslib.spa.widget.preference
-import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.selection.selectableGroup
+import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.IntState
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.tooling.preview.Preview
+import com.android.settingslib.spa.framework.compose.thenIf
import com.android.settingslib.spa.framework.theme.SettingsDimension
-import com.android.settingslib.spa.widget.ui.CategoryTitle
+import com.android.settingslib.spa.framework.theme.isSpaExpressiveEnabled
+import com.android.settingslib.spa.widget.ui.Category
import com.android.settingslib.spa.widget.ui.SettingsListItem
@Composable
fun RadioPreferences(model: ListPreferenceModel) {
- CategoryTitle(title = model.title)
- Spacer(modifier = Modifier.width(SettingsDimension.itemDividerHeight))
- Column(modifier = Modifier.selectableGroup()) {
+ Category(modifier = Modifier.selectableGroup(), title = model.title) {
for (option in model.options) {
Radio2(option, model.selectedId.intValue, model.enabled()) {
model.onIdSelected(it)
@@ -54,20 +60,52 @@
onIdSelected: (id: Int) -> Unit,
) {
val selected = option.id == selectedId
+ val surfaceBright = MaterialTheme.colorScheme.surfaceBright
Row(
- modifier = Modifier
- .fillMaxWidth()
- .selectable(
- selected = selected,
- enabled = enabled,
- onClick = { onIdSelected(option.id) },
- role = Role.RadioButton,
- )
- .padding(SettingsDimension.dialogItemPadding),
+ modifier =
+ Modifier.fillMaxWidth()
+ .thenIf(isSpaExpressiveEnabled) {
+ Modifier.heightIn(min = SettingsDimension.preferenceMinHeight)
+ .background(surfaceBright)
+ }
+ .selectable(
+ selected = selected,
+ enabled = enabled,
+ onClick = { onIdSelected(option.id) },
+ role = Role.RadioButton,
+ )
+ .then(
+ if (isSpaExpressiveEnabled) Modifier.padding(SettingsDimension.itemPadding)
+ else Modifier.padding(SettingsDimension.dialogItemPadding)
+ ),
verticalAlignment = Alignment.CenterVertically,
) {
RadioButton(selected = selected, onClick = null, enabled = enabled)
- Spacer(modifier = Modifier.width(SettingsDimension.itemDividerHeight))
+ Spacer(
+ modifier =
+ Modifier.width(
+ if (isSpaExpressiveEnabled) SettingsDimension.paddingExtraSmall6
+ else SettingsDimension.itemDividerHeight
+ )
+ )
SettingsListItem(text = option.text, enabled = enabled)
}
-}
\ No newline at end of file
+}
+
+@Preview
+@Composable
+private fun RadioPreferencePreview() {
+ RadioPreferences(
+ object : ListPreferenceModel {
+ override val title: String = "Title"
+ override val options: List<ListPreferenceOption> =
+ listOf(
+ ListPreferenceOption(id = 0, text = "option1"),
+ ListPreferenceOption(id = 1, text = "option2"),
+ ListPreferenceOption(id = 2, text = "option3"),
+ )
+ override val selectedId: IntState = remember { mutableIntStateOf(0) }
+ override val onIdSelected: (Int) -> Unit = {}
+ }
+ )
+}
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 96d2abb..62bc00a 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
@@ -76,7 +76,7 @@
* visually separates groups of items.
*/
@Composable
-fun Category(title: String? = null, content: @Composable ColumnScope.() -> Unit) {
+fun Category(title: String? = null, modifier: Modifier = Modifier, content: @Composable ColumnScope.() -> Unit) {
var displayTitle by remember { mutableStateOf(false) }
Column(
modifier =
@@ -90,7 +90,7 @@
if (title != null && displayTitle) CategoryTitle(title = title)
Column(
modifier =
- Modifier.onGloballyPositioned { coordinates ->
+ modifier.onGloballyPositioned { coordinates ->
displayTitle = coordinates.size.height > 0
}
.then(
@@ -162,7 +162,7 @@
@Composable
private fun CategoryPreview() {
SettingsTheme {
- Category("Appearance") {
+ Category(title = "Appearance") {
Preference(
object : PreferenceModel {
override val title = "Title"
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/RadioPreferencesTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/RadioPreferencesTest.kt
index 2f98b02..d187017 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/RadioPreferencesTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/RadioPreferencesTest.kt
@@ -43,7 +43,9 @@
RadioPreferences(remember {
object : ListPreferenceModel {
override val title = TITLE
- override val options = emptyList<ListPreferenceOption>()
+ override val options = listOf(
+ ListPreferenceOption(id = 1, text = "A")
+ )
override val selectedId = mutableIntStateOf(0)
override val onIdSelected: (Int) -> Unit = {}
}
diff --git a/packages/SettingsLib/Spa/testutils/build.gradle.kts b/packages/SettingsLib/Spa/testutils/build.gradle.kts
index cce8235..7dbd320 100644
--- a/packages/SettingsLib/Spa/testutils/build.gradle.kts
+++ b/packages/SettingsLib/Spa/testutils/build.gradle.kts
@@ -16,6 +16,7 @@
plugins {
alias(libs.plugins.android.library)
+ alias(libs.plugins.compose.compiler)
alias(libs.plugins.kotlin.android)
}
@@ -30,9 +31,6 @@
manifest.srcFile("AndroidManifest.xml")
}
}
- buildFeatures {
- compose = true
- }
}
dependencies {
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index ae04ca1..ac436ad 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -737,7 +737,7 @@
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Verander uitvoer"</string>
<string name="back_navigation_animation" msgid="8105467568421689484">"Voorspellingteruggebaaranimasies"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktiveer stelselanimasies vir voorspellingteruggebaar."</string>
- <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Hierdie instelling aktiveer stelselanimasies vir voorspellinggebaaranimasie. Dit vereis dat enableOnBackInvokedCallback per program op waar gestel word in die manifeslêer."</string>
+ <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Hierdie instelling aktiveer stelselanimasies vir voorspellinggebaaranimasie. Dit vereis dat enableOnBackInvokedCallback per app op waar gestel word in die manifeslêer."</string>
<string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
<string name="not_specified" msgid="5423502443185110328">"Nie gespesifiseer nie"</string>
<string name="neuter" msgid="2075249330106127310">"Neutrum"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 690add8..a85d0cc 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -638,7 +638,7 @@
<string name="user_setup_dialog_title" msgid="8037342066381939995">"ಈಗ ಬಳಕೆದಾರರನ್ನು ಸೆಟ್ ಮಾಡಬೇಕೆ?"</string>
<string name="user_setup_dialog_message" msgid="269931619868102841">"ಸಾಧನವನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ಮತ್ತು ಅದರ ಸ್ಥಳವನ್ನು ಹೊಂದಿಸಲು ವ್ಯಕ್ತಿಯು ಲಭ್ಯವಿದ್ದಾರೆಯೇ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
<string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ಇದೀಗ ಪ್ರೊಫೈಲ್ ಅನ್ನು ಹೊಂದಿಸುವುದೇ?"</string>
- <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ಇದೀಗ ಹೊಂದಿಸಿ"</string>
+ <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ಇದೀಗ ಸೆಟ್ ಮಾಡಿ"</string>
<string name="user_setup_button_setup_later" msgid="8712980133555493516">"ಈಗಲೇ ಬೇಡ"</string>
<string name="user_add_user_type_title" msgid="551279664052914497">"ಸೇರಿಸಿ"</string>
<string name="user_new_user_name" msgid="60979820612818840">"ಹೊಸ ಬಳಕೆದಾರರು"</string>
@@ -646,7 +646,7 @@
<string name="user_info_settings_title" msgid="6351390762733279907">"ಬಳಕೆದಾರರ ಮಾಹಿತಿ"</string>
<string name="profile_info_settings_title" msgid="105699672534365099">"ಪ್ರೊಫೈಲ್ ಮಾಹಿತಿ"</string>
<string name="user_need_lock_message" msgid="4311424336209509301">"ನೀವು ನಿರ್ಬಂಧಿತ ಪ್ರೊಫೈಲ್ ಅನ್ನು ರಚಿಸಬಹುದಾದರ ಮೊದಲು, ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಮತ್ತು ವೈಯಕ್ತಿಕ ಡೇಟಾವನ್ನು ರಕ್ಷಿಸಲು ನೀವು ಪರದೆಯ ಲಾಕ್ ಹೊಂದಿಸುವ ಅಗತ್ಯವಿದೆ."</string>
- <string name="user_set_lock_button" msgid="1427128184982594856">"ಲಾಕ್ ಹೊಂದಿಸಿ"</string>
+ <string name="user_set_lock_button" msgid="1427128184982594856">"ಲಾಕ್ ಸೆಟ್ ಮಾಡಿ"</string>
<string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>ಗೆ ಬದಲಿಸಿ"</string>
<string name="creating_new_user_dialog_message" msgid="7232880257538970375">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"ಹೊಸ ಅತಿಥಿಯನ್ನು ರಚಿಸಲಾಗುತ್ತಿದೆ…"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 216574a..429e4c9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -631,15 +631,15 @@
assistantProfile.getAllConnectedDevices().stream()
.map(deviceManager::findDevice)
.filter(Objects::nonNull)
- .map(CachedBluetoothDevice::getGroupId)
+ .map(BluetoothUtils::getGroupId)
.collect(Collectors.toSet());
Set<Integer> activeGroupIds =
leAudioProfile.getActiveDevices().stream()
.map(deviceManager::findDevice)
.filter(Objects::nonNull)
- .map(CachedBluetoothDevice::getGroupId)
+ .map(BluetoothUtils::getGroupId)
.collect(Collectors.toSet());
- int groupId = cachedDevice.getGroupId();
+ int groupId = getGroupId(cachedDevice);
return activeGroupIds.size() == 1
&& !activeGroupIds.contains(groupId)
&& connectedGroupIds.size() == 2
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 4eb0567..b58983f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -17,6 +17,7 @@
package com.android.settingslib.bluetooth;
import static com.android.settingslib.flags.Flags.enableSetPreferredTransportForLeAudioDevice;
+import static com.android.settingslib.flags.Flags.ignoreA2dpDisconnectionForAndroidAuto;
import android.annotation.CallbackExecutor;
import android.annotation.StringRes;
@@ -82,6 +83,8 @@
*/
public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
private static final String TAG = "CachedBluetoothDevice";
+ private static final ParcelUuid ANDROID_AUTO_UUID =
+ ParcelUuid.fromString("4de17a00-52cb-11e6-bdf4-0800200c9a66");
// See mConnectAttempted
private static final long MAX_UUID_DELAY_FOR_AUTO_CONNECT = 5000;
@@ -260,18 +263,26 @@
if (mHandler.hasMessages(profile.getProfileId())) {
mHandler.removeMessages(profile.getProfileId());
if (profile.getConnectionPolicy(mDevice) >
- BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
- /*
- * If we received state DISCONNECTED and previous state was
- * CONNECTING and connection policy is FORBIDDEN or UNKNOWN
- * then it's not really a failure to connect.
- *
- * Connection profile is considered as failed when connection
- * policy indicates that profile should be connected
- * but it got disconnected.
- */
- Log.w(TAG, "onProfileStateChanged(): Failed to connect profile");
- setProfileConnectedStatus(profile.getProfileId(), true);
+ BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
+ if (ignoreA2dpDisconnectionForAndroidAuto()
+ && profile instanceof A2dpProfile && isAndroidAuto()) {
+ Log.w(TAG,
+ "onProfileStateChanged(): Skip setting A2DP "
+ + "connection fail for Android Auto");
+ } else {
+ /*
+ * If we received state DISCONNECTED and previous state was
+ * CONNECTING and connection policy is FORBIDDEN or UNKNOWN
+ * then it's not really a failure to connect.
+ *
+ * Connection profile is considered as failed when connection
+ * policy indicates that profile should be connected
+ * but it got disconnected.
+ */
+ Log.w(TAG,
+ "onProfileStateChanged(): Failed to connect profile");
+ setProfileConnectedStatus(profile.getProfileId(), true);
+ }
}
}
break;
@@ -2031,4 +2042,16 @@
void setLocalBluetoothManager(LocalBluetoothManager bluetoothManager) {
mBluetoothManager = bluetoothManager;
}
+
+ private boolean isAndroidAuto() {
+ try {
+ ParcelUuid[] uuids = mDevice.getUuids();
+ if (ArrayUtils.contains(uuids, ANDROID_AUTO_UUID)) {
+ return true;
+ }
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Fail to check isAndroidAuto for " + this);
+ }
+ return false;
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
index a4c5a00d..5bcdcc0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
@@ -32,7 +32,9 @@
import android.os.Build;
import android.util.Log;
+import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.android.settingslib.R;
@@ -372,6 +374,27 @@
}
/**
+ * Gets the {@link BluetoothLeBroadcastMetadata} of a specified source added to this sink.
+ *
+ * @param sink Broadcast Sink device
+ * @param sourceId Broadcast source id
+ * @return metadata {@link BluetoothLeBroadcastMetadata} associated with the specified source.
+ */
+ public @Nullable BluetoothLeBroadcastMetadata getSourceMetadata(
+ @NonNull BluetoothDevice sink, @IntRange(from = 0x00, to = 0xFF) int sourceId) {
+ if (mService == null) {
+ Log.d(TAG, "The BluetoothLeBroadcastAssistant is null");
+ return null;
+ }
+ try {
+ return mService.getSourceMetadata(sink, sourceId);
+ } catch (IllegalArgumentException | NoSuchMethodError e) {
+ Log.w(TAG, "Error calling getSourceMetadata()", e);
+ }
+ return null;
+ }
+
+ /**
* Register Broadcast Assistant Callbacks to track its state and receivers
*
* @param executor Executor object for callback
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java
index 76aa5bf..478a5d1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InputRouteManager.java
@@ -80,8 +80,14 @@
// behavior.
@AudioDeviceType int deviceTypeToActivate = mSelectedInputDeviceType;
for (AudioDeviceInfo info : addedDevices) {
- if (InputMediaDevice.isSupportedInputDevice(info.getType())) {
- deviceTypeToActivate = info.getType();
+ @AudioDeviceType int type = info.getType();
+ // Since onAudioDevicesAdded is called not only when new device is hot
+ // plugged, but also when the switcher dialog is opened, make sure to check
+ // against existing device list and only activate if the device does not
+ // exist previously.
+ if (InputMediaDevice.isSupportedInputDevice(type)
+ && findDeviceByType(type) == null) {
+ deviceTypeToActivate = type;
}
}
@@ -140,16 +146,22 @@
}
// TODO(b/355684672): handle edge case where there are two devices with the same type. Only
- // using a single mSelectedInputDeviceType might not be enough to recognize the correct device.
- public @Nullable MediaDevice getSelectedInputDevice() {
+ // using a single type might not be enough to recognize the correct device.
+ @Nullable
+ private MediaDevice findDeviceByType(@AudioDeviceType int type) {
for (MediaDevice device : mInputMediaDevices) {
- if (((InputMediaDevice) device).getAudioDeviceInfoType() == mSelectedInputDeviceType) {
+ if (((InputMediaDevice) device).getAudioDeviceInfoType() == type) {
return device;
}
}
return null;
}
+ @Nullable
+ public MediaDevice getSelectedInputDevice() {
+ return findDeviceByType(mSelectedInputDeviceType);
+ }
+
private void applyDefaultSelectedTypeToAllPresets() {
mSelectedInputDeviceType = retrieveDefaultSelectedDeviceType();
AudioDeviceAttributes deviceAttributes =
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
index a03977c1..785bcbf 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
@@ -21,15 +21,26 @@
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+import static android.security.advancedprotection.AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY;
+
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.admin.Authority;
+import android.app.admin.DeviceAdminAuthority;
import android.app.admin.DevicePolicyManager;
+import android.app.admin.DpcAuthority;
+import android.app.admin.EnforcingAdmin;
+import android.app.admin.RoleAuthority;
+import android.app.admin.UnknownAuthority;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -37,8 +48,13 @@
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
@@ -52,6 +68,8 @@
@RunWith(RobolectricTestRunner.class)
public class RestrictedLockUtilsTest {
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@Mock
private Context mContext;
@@ -66,6 +84,7 @@
private final int mUserId = 194;
private final int mProfileId = 160;
+ private final String mPackage = "test.pkg";
private final ComponentName mAdmin1 = new ComponentName("admin1", "admin1class");
private final ComponentName mAdmin2 = new ComponentName("admin2", "admin2class");
@@ -85,6 +104,7 @@
RestrictedLockUtilsInternal.sProxy = mProxy;
}
+ @RequiresFlagsDisabled(android.security.Flags.FLAG_AAPM_API)
@Test
public void checkIfRestrictionEnforced_deviceOwner()
throws PackageManager.NameNotFoundException {
@@ -109,6 +129,7 @@
assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
}
+ @RequiresFlagsDisabled(android.security.Flags.FLAG_AAPM_API)
@Test
public void checkIfRestrictionEnforced_profileOwner()
throws PackageManager.NameNotFoundException {
@@ -133,6 +154,125 @@
assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
}
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+ @Test
+ public void checkIfRestrictionEnforced_getEnforcingAdminExists() {
+ UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
+ UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
+ final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+ final EnforcingAdmin enforcingAdmin = new EnforcingAdmin(mPackage,
+ UnknownAuthority.UNKNOWN_AUTHORITY, UserHandle.of(mUserId), mAdmin1);
+
+ when(mUserManager.getUserRestrictionSources(userRestriction,
+ UserHandle.of(mUserId)))
+ .thenReturn(Collections.singletonList(enforcingUser));
+ when(mDevicePolicyManager.getEnforcingAdmin(mUserId, userRestriction))
+ .thenReturn(enforcingAdmin);
+
+ EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+ mContext, userRestriction, mUserId);
+
+ assertThat(enforcedAdmin).isNotNull();
+ assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
+ assertThat(enforcedAdmin.component).isEqualTo(enforcingAdmin.getComponentName());
+ assertThat(enforcedAdmin.user).isEqualTo(enforcingAdmin.getUserHandle());
+ }
+
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+ @Test
+ public void checkIfRestrictionEnforced_getEnforcingAdminReturnsNull_deviceOwner()
+ throws PackageManager.NameNotFoundException {
+ UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
+ UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
+ final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+
+ when(mUserManager.getUserRestrictionSources(userRestriction,
+ UserHandle.of(mUserId)))
+ .thenReturn(Collections.singletonList(enforcingUser));
+ when(mDevicePolicyManager.getEnforcingAdmin(mUserId, userRestriction))
+ .thenReturn(null);
+ when(mContext.createPackageContextAsUser(any(), eq(0),
+ eq(UserHandle.of(mUserId))))
+ .thenReturn(mContext);
+
+ setUpDeviceOwner(mAdmin1, mUserId);
+
+ EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
+ .checkIfRestrictionEnforced(mContext, userRestriction, mUserId);
+
+ assertThat(enforcedAdmin).isNotNull();
+ assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
+ assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
+ }
+
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+ @Test
+ public void checkIfRestrictionEnforced_getEnforcingAdminReturnsNull_profileOwner()
+ throws PackageManager.NameNotFoundException {
+ UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
+ UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
+ final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+
+ when(mUserManager.getUserRestrictionSources(userRestriction,
+ UserHandle.of(mUserId)))
+ .thenReturn(Collections.singletonList(enforcingUser));
+ when(mDevicePolicyManager.getEnforcingAdmin(mUserId, userRestriction))
+ .thenReturn(null);
+ when(mContext.createPackageContextAsUser(any(), eq(0),
+ eq(UserHandle.of(mUserId))))
+ .thenReturn(mContext);
+
+ setUpProfileOwner(mAdmin1);
+
+ EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
+ .checkIfRestrictionEnforced(mContext, userRestriction, mUserId);
+
+ assertThat(enforcedAdmin).isNotNull();
+ assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
+ assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
+ }
+
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+ @Test
+ public void isPolicyEnforcedByAdvancedProtection_notEnforced_returnsFalse() {
+ final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+ final Authority[] allNonAdvancedProtectionAuthorities = new Authority[] {
+ UnknownAuthority.UNKNOWN_AUTHORITY,
+ DeviceAdminAuthority.DEVICE_ADMIN_AUTHORITY,
+ DpcAuthority.DPC_AUTHORITY,
+ new RoleAuthority(Collections.singleton("some-role"))
+ };
+
+ for (Authority authority : allNonAdvancedProtectionAuthorities) {
+ final EnforcingAdmin enforcingAdmin = new EnforcingAdmin(mPackage, authority,
+ UserHandle.of(mUserId), mAdmin1);
+
+ when(mDevicePolicyManager.getEnforcingAdmin(mUserId, userRestriction))
+ .thenReturn(enforcingAdmin);
+
+ assertWithMessage(authority + " is not an advanced protection authority")
+ .that(RestrictedLockUtilsInternal.isPolicyEnforcedByAdvancedProtection(
+ mContext, userRestriction, mUserId))
+ .isFalse();
+ }
+ }
+
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+ @Test
+ public void isPolicyEnforcedByAdvancedProtection_enforced_returnsTrue() {
+ final Authority advancedProtectionAuthority = new UnknownAuthority(
+ ADVANCED_PROTECTION_SYSTEM_ENTITY);
+ final EnforcingAdmin advancedProtectionEnforcingAdmin = new EnforcingAdmin(mPackage,
+ advancedProtectionAuthority, UserHandle.of(mUserId), mAdmin1);
+ final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+
+ when(mDevicePolicyManager.getEnforcingAdmin(mUserId, userRestriction))
+ .thenReturn(advancedProtectionEnforcingAdmin);
+
+ assertThat(RestrictedLockUtilsInternal.isPolicyEnforcedByAdvancedProtection(mContext,
+ userRestriction, mUserId)).isTrue();
+ }
+
@Test
public void checkIfDevicePolicyServiceDisabled_noEnforceAdminForManagedProfile() {
when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(null);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java
index 7ad54e1..dbbbd5b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedPreferenceHelperTest.java
@@ -16,7 +16,10 @@
package com.android.settingslib;
+import static android.security.advancedprotection.AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY;
+
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -26,10 +29,23 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.admin.Authority;
+import android.app.admin.DeviceAdminAuthority;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyResourcesManager;
+import android.app.admin.DpcAuthority;
+import android.app.admin.EnforcingAdmin;
+import android.app.admin.RoleAuthority;
+import android.app.admin.UnknownAuthority;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.view.View;
import android.widget.TextView;
@@ -37,14 +53,19 @@
import androidx.preference.PreferenceViewHolder;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+import java.util.Collections;
+
@RunWith(RobolectricTestRunner.class)
public class RestrictedPreferenceHelperTest {
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@Mock
private Context mContext;
@@ -57,6 +78,11 @@
@Mock
private RestrictedTopLevelPreference mRestrictedTopLevelPreference;
+ private final String mPackage = "test.pkg";
+ private final ComponentName mAdmin = new ComponentName("admin", "adminclass");
+ private final Authority mAdvancedProtectionAuthority = new UnknownAuthority(
+ ADVANCED_PROTECTION_SYSTEM_ENTITY);
+
private PreferenceViewHolder mViewHolder;
private RestrictedPreferenceHelper mHelper;
@@ -71,6 +97,7 @@
mHelper = new RestrictedPreferenceHelper(mContext, mPreference, null);
}
+ @RequiresFlagsDisabled(android.security.Flags.FLAG_AAPM_API)
@Test
public void bindPreference_disabled_shouldDisplayDisabledSummary() {
final TextView summaryView = mock(TextView.class, RETURNS_DEEP_STUBS);
@@ -101,6 +128,57 @@
verify(summaryView, never()).setVisibility(View.GONE);
}
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+ @Test
+ public void bindPreference_disabled_byAdvancedProtection_shouldDisplayDisabledSummary() {
+ final TextView summaryView = mock(TextView.class, RETURNS_DEEP_STUBS);
+ final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+ final RestrictedLockUtils.EnforcedAdmin enforcedAdmin = new RestrictedLockUtils
+ .EnforcedAdmin(/* component */ null, userRestriction, UserHandle.of(
+ UserHandle.myUserId()));
+ final EnforcingAdmin advancedProtectionEnforcingAdmin = new EnforcingAdmin(mPackage,
+ mAdvancedProtectionAuthority, UserHandle.of(UserHandle.myUserId()), mAdmin);
+
+ when(mViewHolder.itemView.findViewById(android.R.id.summary))
+ .thenReturn(summaryView);
+ when(mDevicePolicyManager.getEnforcingAdmin(UserHandle.myUserId(), userRestriction))
+ .thenReturn(advancedProtectionEnforcingAdmin);
+ when(mContext.getString(
+ com.android.settingslib.widget.restricted.R.string.disabled_by_advanced_protection))
+ .thenReturn("advanced_protection");
+
+ mHelper.useAdminDisabledSummary(true);
+ mHelper.setDisabledByAdmin(enforcedAdmin);
+ mHelper.onBindViewHolder(mViewHolder);
+
+ verify(summaryView).setText("advanced_protection");
+ verify(summaryView, never()).setVisibility(View.GONE);
+ }
+
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+ @Test
+ public void bindPreference_disabled_byAdmin_shouldDisplayDisabledSummary() {
+ final TextView summaryView = mock(TextView.class, RETURNS_DEEP_STUBS);
+ final EnforcingAdmin nonAdvancedProtectionEnforcingAdmin = new EnforcingAdmin(mPackage,
+ UnknownAuthority.UNKNOWN_AUTHORITY, UserHandle.of(UserHandle.myUserId()), mAdmin);
+ final String userRestriction = UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY;
+
+ when(mViewHolder.itemView.findViewById(android.R.id.summary))
+ .thenReturn(summaryView);
+ when(mDevicePolicyManager.getEnforcingAdmin(UserHandle.myUserId(), userRestriction))
+ .thenReturn(nonAdvancedProtectionEnforcingAdmin);
+ when(mContext.getString(R.string.disabled_by_admin_summary_text))
+ .thenReturn("test");
+ when(mDevicePolicyResourcesManager.getString(any(), any())).thenReturn("test");
+
+ mHelper.useAdminDisabledSummary(true);
+ mHelper.setDisabledByAdmin(new RestrictedLockUtils.EnforcedAdmin());
+ mHelper.onBindViewHolder(mViewHolder);
+
+ verify(summaryView).setText("test");
+ verify(summaryView, never()).setVisibility(View.GONE);
+ }
+
@Test
public void bindPreference_notDisabled_shouldNotHideSummary() {
final TextView summaryView = mock(TextView.class, RETURNS_DEEP_STUBS);
@@ -157,4 +235,74 @@
assertThat(mHelper.isDisabledByAdmin()).isTrue();
}
+
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+ @Test
+ public void setDisabledByAdmin_previousAndCurrentAdminsAreTheSame_returnsFalse() {
+ RestrictedLockUtils.EnforcedAdmin enforcedAdmin =
+ new RestrictedLockUtils.EnforcedAdmin(/* component */ null,
+ /* enforcedRestriction */ "some_restriction", /* userHandle */ null);
+
+ mHelper.setDisabledByAdmin(enforcedAdmin);
+
+ assertThat(mHelper.setDisabledByAdmin(enforcedAdmin)).isFalse();
+ }
+
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+ @Test
+ public void setDisabledByAdmin_previousAndCurrentAdminsAreDifferent_returnsTrue() {
+ RestrictedLockUtils.EnforcedAdmin enforcedAdmin1 =
+ new RestrictedLockUtils.EnforcedAdmin(/* component */ null,
+ /* enforcedRestriction */ "some_restriction", /* userHandle */ null);
+ RestrictedLockUtils.EnforcedAdmin enforcedAdmin2 =
+ new RestrictedLockUtils.EnforcedAdmin(new ComponentName("pkg", "cls"),
+ /* enforcedRestriction */ "some_restriction", /* userHandle */ null);
+
+ mHelper.setDisabledByAdmin(enforcedAdmin1);
+
+ assertThat(mHelper.setDisabledByAdmin(enforcedAdmin2)).isTrue();
+ }
+
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+ @Test
+ public void isRestrictionEnforcedByAdvancedProtection_notEnforced_returnsFalse() {
+ final Authority[] allNonAdvancedProtectionAuthorities = new Authority[] {
+ UnknownAuthority.UNKNOWN_AUTHORITY,
+ DeviceAdminAuthority.DEVICE_ADMIN_AUTHORITY,
+ DpcAuthority.DPC_AUTHORITY,
+ new RoleAuthority(Collections.singleton("some-role"))
+ };
+ final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+
+ for (Authority authority : allNonAdvancedProtectionAuthorities) {
+ final EnforcingAdmin enforcingAdmin = new EnforcingAdmin(mPackage, authority,
+ UserHandle.of(UserHandle.myUserId()), mAdmin);
+
+ when(mDevicePolicyManager.getEnforcingAdmin(UserHandle.myUserId(), userRestriction))
+ .thenReturn(enforcingAdmin);
+
+ mHelper.setDisabledByAdmin(new RestrictedLockUtils.EnforcedAdmin(/* component */ null,
+ userRestriction, UserHandle.of(UserHandle.myUserId())));
+
+ assertWithMessage(authority + " is not an advanced protection authority")
+ .that(mHelper.isRestrictionEnforcedByAdvancedProtection())
+ .isFalse();
+ }
+ }
+
+ @RequiresFlagsEnabled(android.security.Flags.FLAG_AAPM_API)
+ @Test
+ public void isRestrictionEnforcedByAdvancedProtection_enforced_returnsTrue() {
+ final EnforcingAdmin advancedProtectionEnforcingAdmin = new EnforcingAdmin(mPackage,
+ mAdvancedProtectionAuthority, UserHandle.of(UserHandle.myUserId()), mAdmin);
+ final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+
+ when(mDevicePolicyManager.getEnforcingAdmin(UserHandle.myUserId(), userRestriction))
+ .thenReturn(advancedProtectionEnforcingAdmin);
+
+ mHelper.setDisabledByAdmin(new RestrictedLockUtils.EnforcedAdmin(/* component */ null,
+ userRestriction, UserHandle.of(UserHandle.myUserId())));
+
+ assertThat(mHelper.isRestrictionEnforcedByAdvancedProtection()).isTrue();
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java
index d808a25..9c34946 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InputRouteManagerTest.java
@@ -361,6 +361,26 @@
}
@Test
+ public void onAudioDevicesAdded_doNotActivatePreexistingDevice() {
+ final AudioManager audioManager = mock(AudioManager.class);
+ InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager);
+
+ final AudioDeviceInfo info = mockWiredHeadsetInfo();
+ InputMediaDevice device = createInputMediaDeviceFromDeviceInfo(info);
+ inputRouteManager.mInputMediaDevices.add(device);
+
+ // Trigger onAudioDevicesAdded with a device that already exists in the device list.
+ AudioDeviceInfo[] devices = {info};
+ inputRouteManager.mAudioDeviceCallback.onAudioDevicesAdded(devices);
+
+ // The device should not be activated.
+ for (@MediaRecorder.Source int preset : PRESETS) {
+ verify(audioManager, never())
+ .setPreferredDeviceForCapturePreset(preset, getWiredHeadsetDeviceAttributes());
+ }
+ }
+
+ @Test
public void onAudioDevicesRemoved_shouldApplyDefaultSelectedDeviceToAllPresets() {
final AudioManager audioManager = mock(AudioManager.class);
InputRouteManager inputRouteManager = new InputRouteManager(mContext, audioManager);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/EventLogTags.logtags b/packages/SettingsProvider/src/com/android/providers/settings/EventLogTags.logtags
index 7eff16b..0367fe0 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/EventLogTags.logtags
+++ b/packages/SettingsProvider/src/com/android/providers/settings/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.providers.settings;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index e12c7a2..326bff4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -201,6 +201,16 @@
"could_not_read_from_cursor";
private static final String ERROR_FAILED_TO_WRITE_ENTITY =
"failed_to_write_entity";
+ private static final String ERROR_COULD_NOT_READ_ENTITY =
+ "could_not_read_entity";
+ private static final String ERROR_SKIPPED_BY_SYSTEM = "skipped_by_system";
+ private static final String ERROR_SKIPPED_BY_BLOCKLIST =
+ "skipped_by_dynamic_blocklist";
+ private static final String ERROR_SKIPPED_PRESERVED = "skipped_preserved";
+ private static final String ERROR_SKIPPED_DUE_TO_LARGE_SCREEN =
+ "skipped_due_to_large_screen";
+ private static final String ERROR_DID_NOT_PASS_VALIDATION = "did_not_pass_validation";
+
// Name of the temporary file we use during full backup/restore. This is
// stored in the full-backup tarfile as well, so should not be changed.
@@ -373,7 +383,7 @@
restoreSettings(data, Settings.System.CONTENT_URI, movedToGlobal,
movedToSecure, /* movedToSystem= */ null,
R.array.restore_blocked_system_settings, dynamicBlockList,
- preservedSystemSettings);
+ preservedSystemSettings, KEY_SYSTEM);
mSettingsHelper.applyAudioSettings();
break;
@@ -381,13 +391,13 @@
restoreSettings(data, Settings.Secure.CONTENT_URI, movedToGlobal,
/* movedToSecure= */ null, movedToSystem,
R.array.restore_blocked_secure_settings, dynamicBlockList,
- preservedSecureSettings);
+ preservedSecureSettings, KEY_SECURE);
break;
case KEY_GLOBAL :
restoreSettings(data, Settings.Global.CONTENT_URI, /* movedToGlobal= */ null,
movedToSecure, movedToSystem, R.array.restore_blocked_global_settings,
- dynamicBlockList, preservedGlobalSettings);
+ dynamicBlockList, preservedGlobalSettings, KEY_GLOBAL);
break;
case KEY_WIFI_SUPPLICANT :
@@ -506,7 +516,7 @@
restoreSettings(buffer, nBytes, Settings.System.CONTENT_URI, movedToGlobal,
movedToSecure, /* movedToSystem= */ null,
R.array.restore_blocked_system_settings, Collections.emptySet(),
- Collections.emptySet());
+ Collections.emptySet(), KEY_SYSTEM);
// secure settings
nBytes = in.readInt();
@@ -516,7 +526,7 @@
restoreSettings(buffer, nBytes, Settings.Secure.CONTENT_URI, movedToGlobal,
/* movedToSecure= */ null, movedToSystem,
R.array.restore_blocked_secure_settings, Collections.emptySet(),
- Collections.emptySet());
+ Collections.emptySet(), KEY_SECURE);
// Global only if sufficiently new
if (version >= FULL_BACKUP_ADDED_GLOBAL) {
@@ -527,7 +537,7 @@
restoreSettings(buffer, nBytes, Settings.Global.CONTENT_URI,
/* movedToGlobal= */ null, movedToSecure, movedToSystem,
R.array.restore_blocked_global_settings, Collections.emptySet(),
- Collections.emptySet());
+ Collections.emptySet(), KEY_GLOBAL);
}
// locale
@@ -808,7 +818,8 @@
return baos.toByteArray();
}
- private void restoreSettings(
+ @VisibleForTesting
+ void restoreSettings(
BackupDataInput data,
Uri contentUri,
Set<String> movedToGlobal,
@@ -816,12 +827,17 @@
Set<String> movedToSystem,
int blockedSettingsArrayId,
Set<String> dynamicBlockList,
- Set<String> settingsToPreserve) {
+ Set<String> settingsToPreserve,
+ String settingsKey) {
byte[] settings = new byte[data.getDataSize()];
try {
data.readEntityData(settings, 0, settings.length);
} catch (IOException ioe) {
Log.e(TAG, "Couldn't read entity data");
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger.logItemsRestoreFailed(
+ settingsKey, /* count= */ 1, ERROR_COULD_NOT_READ_ENTITY);
+ }
return;
}
restoreSettings(
@@ -833,7 +849,8 @@
movedToSystem,
blockedSettingsArrayId,
dynamicBlockList,
- settingsToPreserve);
+ settingsToPreserve,
+ settingsKey);
}
private void restoreSettings(
@@ -845,7 +862,8 @@
Set<String> movedToSystem,
int blockedSettingsArrayId,
Set<String> dynamicBlockList,
- Set<String> settingsToPreserve) {
+ Set<String> settingsToPreserve,
+ String settingsKey) {
restoreSettings(
settings,
0,
@@ -856,7 +874,8 @@
movedToSystem,
blockedSettingsArrayId,
dynamicBlockList,
- settingsToPreserve);
+ settingsToPreserve,
+ settingsKey);
}
@VisibleForTesting
@@ -870,12 +889,13 @@
Set<String> movedToSystem,
int blockedSettingsArrayId,
Set<String> dynamicBlockList,
- Set<String> settingsToPreserve) {
+ Set<String> settingsToPreserve,
+ String settingsKey) {
if (DEBUG) {
Log.i(TAG, "restoreSettings: " + contentUri);
}
- SettingsBackupWhitelist whitelist = getBackupWhitelist(contentUri);
+ SettingsBackupAllowlist allowlist = getBackupAllowlist(contentUri);
// Restore only the white list data.
final ArrayMap<String, String> cachedEntries = new ArrayMap<>();
@@ -885,7 +905,8 @@
Set<String> blockedSettings = getBlockedSettings(blockedSettingsArrayId);
- for (String key : whitelist.mSettingsWhitelist) {
+ int restoredSettingsCount = 0;
+ for (String key : allowlist.mSettingsAllowlist) {
boolean isBlockedBySystem = blockedSettings != null && blockedSettings.contains(key);
if (isBlockedBySystem || isBlockedByDynamicList(dynamicBlockList, contentUri, key)) {
Log.i(
@@ -895,6 +916,12 @@
+ " removed from restore by "
+ (isBlockedBySystem ? "system" : "dynamic")
+ " block list");
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger.logItemsRestoreFailed(
+ settingsKey,
+ /* count= */ 1,
+ isBlockedBySystem ? ERROR_SKIPPED_BY_SYSTEM : ERROR_SKIPPED_BY_BLOCKLIST);
+ }
continue;
}
@@ -905,12 +932,20 @@
if (isSettingPreserved && !Settings.Secure.NAVIGATION_MODE.equals(key)) {
Log.i(TAG, "Skipping restore for setting " + key + " as it is marked as "
+ "preserved");
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger.logItemsRestoreFailed(
+ settingsKey, /* count= */ 1, ERROR_SKIPPED_PRESERVED);
+ }
continue;
}
if (LargeScreenSettings.doNotRestoreIfLargeScreenSetting(key, getBaseContext())) {
Log.i(TAG, "Skipping restore for setting " + key + " as the target device "
+ "is a large screen (i.e tablet or foldable in unfolded state)");
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger.logItemsRestoreFailed(
+ settingsKey, /* count= */ 1, ERROR_SKIPPED_DUE_TO_LARGE_SCREEN);
+ }
continue;
}
@@ -947,19 +982,34 @@
}
// only restore the settings that have valid values
- if (!isValidSettingValue(key, value, whitelist.mSettingsValidators)) {
+ if (!isValidSettingValue(key, value, allowlist.mSettingsValidators)) {
Log.w(TAG, "Attempted restore of " + key + " setting, but its value didn't pass"
+ " validation, value: " + value);
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger.logItemsRestoreFailed(
+ settingsKey, /* count= */ 1, ERROR_DID_NOT_PASS_VALIDATION);
+ }
continue;
}
final Uri destination;
+ // If the destination changes, we need to update the key used as datatype for metrics.
+ String finalSettingsKey = settingsKey;
if (movedToGlobal != null && movedToGlobal.contains(key)) {
destination = Settings.Global.CONTENT_URI;
+ if (areAgentMetricsEnabled) {
+ finalSettingsKey = KEY_GLOBAL;
+ }
} else if (movedToSecure != null && movedToSecure.contains(key)) {
destination = Settings.Secure.CONTENT_URI;
+ if (areAgentMetricsEnabled) {
+ finalSettingsKey = KEY_SECURE;
+ }
} else if (movedToSystem != null && movedToSystem.contains(key)) {
destination = Settings.System.CONTENT_URI;
+ if (areAgentMetricsEnabled) {
+ finalSettingsKey = KEY_SYSTEM;
+ }
} else {
destination = contentUri;
}
@@ -977,6 +1027,10 @@
if (isSettingPreserved) {
Log.i(TAG, "Skipping restore for setting navigation_mode "
+ "as it is marked as preserved");
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger.logItemsRestoreFailed(
+ finalSettingsKey, /* count= */ 1, ERROR_SKIPPED_PRESERVED);
+ }
continue;
}
}
@@ -996,12 +1050,16 @@
Log.d(TAG, "Restored font scale from: " + toRestore + " to " + value);
}
-
+ // TODO(b/379861078): Log metrics inside this method.
settingsHelper.restoreValue(this, cr, contentValues, destination, key, value,
mRestoredFromSdkInt);
Log.d(TAG, "Restored setting: " + destination + " : " + key + "=" + value);
+ if (areAgentMetricsEnabled) {
+ mBackupRestoreEventLogger.logItemsRestored(finalSettingsKey, /* count= */ 1);
+ }
}
+
}
@@ -1031,29 +1089,29 @@
}
@VisibleForTesting
- SettingsBackupWhitelist getBackupWhitelist(Uri contentUri) {
+ SettingsBackupAllowlist getBackupAllowlist(Uri contentUri) {
// Figure out the white list and redirects to the global table. We restore anything
// in either the backup allowlist or the legacy-restore allowlist for this table.
- String[] whitelist;
+ String[] allowlist;
Map<String, Validator> validators = null;
if (contentUri.equals(Settings.Secure.CONTENT_URI)) {
- whitelist = ArrayUtils.concat(String.class, SecureSettings.SETTINGS_TO_BACKUP,
+ allowlist = ArrayUtils.concat(String.class, SecureSettings.SETTINGS_TO_BACKUP,
Settings.Secure.LEGACY_RESTORE_SETTINGS,
DeviceSpecificSettings.DEVICE_SPECIFIC_SETTINGS_TO_BACKUP);
validators = SecureSettingsValidators.VALIDATORS;
} else if (contentUri.equals(Settings.System.CONTENT_URI)) {
- whitelist = ArrayUtils.concat(String.class, SystemSettings.SETTINGS_TO_BACKUP,
+ allowlist = ArrayUtils.concat(String.class, SystemSettings.SETTINGS_TO_BACKUP,
Settings.System.LEGACY_RESTORE_SETTINGS);
validators = SystemSettingsValidators.VALIDATORS;
} else if (contentUri.equals(Settings.Global.CONTENT_URI)) {
- whitelist = ArrayUtils.concat(String.class, getGlobalSettingsToBackup(),
+ allowlist = ArrayUtils.concat(String.class, getGlobalSettingsToBackup(),
Settings.Global.LEGACY_RESTORE_SETTINGS);
validators = GlobalSettingsValidators.VALIDATORS;
} else {
throw new IllegalArgumentException("Unknown URI: " + contentUri);
}
- return new SettingsBackupWhitelist(whitelist, validators);
+ return new SettingsBackupAllowlist(allowlist, validators);
}
private String[] getGlobalSettingsToBackup() {
@@ -1449,7 +1507,8 @@
null,
blockedSettingsArrayId,
dynamicBlocklist,
- preservedSettings);
+ preservedSettings,
+ KEY_DEVICE_SPECIFIC_CONFIG);
updateWindowManagerIfNeeded(originalDensity);
@@ -1647,14 +1706,14 @@
* Store the allowlist of settings to be backed up and validators for them.
*/
@VisibleForTesting
- static class SettingsBackupWhitelist {
- final String[] mSettingsWhitelist;
+ static class SettingsBackupAllowlist {
+ final String[] mSettingsAllowlist;
final Map<String, Validator> mSettingsValidators;
- SettingsBackupWhitelist(String[] settingsWhitelist,
+ SettingsBackupAllowlist(String[] settingsAllowlist,
Map<String, Validator> settingsValidators) {
- mSettingsWhitelist = settingsWhitelist;
+ mSettingsAllowlist = settingsAllowlist;
mSettingsValidators = settingsValidators;
}
}
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
index 4642864..350c149 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
@@ -30,6 +30,7 @@
import android.app.backup.BackupAnnotations.BackupDestination;
import android.app.backup.BackupAnnotations.OperationType;
+import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupRestoreEventLogger;
import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
@@ -57,6 +58,7 @@
import com.android.window.flags.Flags;
+import java.util.List;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -95,6 +97,15 @@
private static final Map<String, Validator> TEST_VALUES_VALIDATORS = new HashMap<>();
private static final String TEST_KEY = "test_key";
private static final String TEST_VALUE = "test_value";
+ private static final String ERROR_COULD_NOT_READ_ENTITY = "could_not_read_entity";
+ private static final String ERROR_SKIPPED_BY_SYSTEM = "skipped_by_system";
+ private static final String ERROR_SKIPPED_BY_BLOCKLIST =
+ "skipped_by_dynamic_blocklist";
+ private static final String ERROR_SKIPPED_PRESERVED = "skipped_preserved";
+ private static final String ERROR_DID_NOT_PASS_VALIDATION = "did_not_pass_validation";
+ private static final String KEY_SYSTEM = "system";
+ private static final String KEY_SECURE = "secure";
+ private static final String KEY_GLOBAL = "global";
static {
DEVICE_SPECIFIC_TEST_VALUES.put(Settings.Secure.DISPLAY_DENSITY_FORCED,
@@ -113,6 +124,7 @@
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
+ @Mock private BackupDataInput mBackupDataInput;
@Mock private BackupDataOutput mBackupDataOutput;
private TestFriendlySettingsBackupAgent mAgentUnderTest;
@@ -232,19 +244,32 @@
@Test
public void testOnRestore_preservedSettingsAreNotRestored() {
- SettingsBackupAgent.SettingsBackupWhitelist whitelist =
- new SettingsBackupAgent.SettingsBackupWhitelist(
+ SettingsBackupAgent.SettingsBackupAllowlist allowlist =
+ new SettingsBackupAgent.SettingsBackupAllowlist(
new String[] { OVERRIDDEN_TEST_SETTING, PRESERVED_TEST_SETTING },
TEST_VALUES_VALIDATORS);
- mAgentUnderTest.setSettingsWhitelist(whitelist);
+ mAgentUnderTest.setSettingsAllowlist(allowlist);
mAgentUnderTest.setBlockedSettings();
TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
mAgentUnderTest.mSettingsHelper = settingsHelper;
byte[] backupData = generateBackupData(TEST_VALUES);
- mAgentUnderTest.restoreSettings(backupData, /* pos */ 0, backupData.length, TEST_URI,
- null, null, null, /* blockedSettingsArrayId */ 0, Collections.emptySet(),
- new HashSet<>(Collections.singletonList(SettingsBackupAgent.getQualifiedKeyForSetting(PRESERVED_TEST_SETTING, TEST_URI))));
+ mAgentUnderTest.restoreSettings(
+ backupData,
+ /* pos */ 0,
+ backupData.length,
+ TEST_URI,
+ null,
+ null,
+ null,
+ /* blockedSettingsArrayId */ 0,
+ Collections.emptySet(),
+ new HashSet<>(Collections
+ .singletonList(
+ SettingsBackupAgent
+ .getQualifiedKeyForSetting(
+ PRESERVED_TEST_SETTING, TEST_URI))),
+ TEST_KEY);
assertTrue(settingsHelper.mWrittenValues.containsKey(OVERRIDDEN_TEST_SETTING));
assertFalse(settingsHelper.mWrittenValues.containsKey(PRESERVED_TEST_SETTING));
@@ -395,6 +420,382 @@
assertNull(getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest));
}
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreEnabled_agentMetricsAreLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ SettingsBackupAgent.SettingsBackupAllowlist allowlist =
+ new SettingsBackupAgent.SettingsBackupAllowlist(
+ new String[] {OVERRIDDEN_TEST_SETTING},
+ TEST_VALUES_VALIDATORS);
+ mAgentUnderTest.setSettingsAllowlist(allowlist);
+ mAgentUnderTest.setBlockedSettings();
+ TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
+ mAgentUnderTest.mSettingsHelper = settingsHelper;
+
+ byte[] backupData = generateBackupData(TEST_VALUES);
+ mAgentUnderTest
+ .restoreSettings(
+ backupData,
+ /* pos= */ 0,
+ backupData.length,
+ TEST_URI,
+ /* movedToGlobal= */ null,
+ /* movedToSecure= */ null,
+ /* movedToSystem= */ null,
+ /* blockedSettingsArrayId= */ 0,
+ /* dynamicBlockList= */ Collections.emptySet(),
+ /* settingsToPreserve= */ Collections.emptySet(),
+ TEST_KEY);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getSuccessCount(), 1);
+ }
+
+ @Test
+ @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreDisabled_agentMetricsAreNotLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ SettingsBackupAgent.SettingsBackupAllowlist allowlist =
+ new SettingsBackupAgent.SettingsBackupAllowlist(
+ new String[] {OVERRIDDEN_TEST_SETTING},
+ TEST_VALUES_VALIDATORS);
+ mAgentUnderTest.setSettingsAllowlist(allowlist);
+ mAgentUnderTest.setBlockedSettings();
+ TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
+ mAgentUnderTest.mSettingsHelper = settingsHelper;
+
+ byte[] backupData = generateBackupData(TEST_VALUES);
+ mAgentUnderTest
+ .restoreSettings(
+ backupData,
+ /* pos= */ 0,
+ backupData.length,
+ TEST_URI,
+ /* movedToGlobal= */ null,
+ /* movedToSecure= */ null,
+ /* movedToSystem= */ null,
+ /* blockedSettingsArrayId= */ 0,
+ /* dynamicBlockList= */ Collections.emptySet(),
+ /* settingsToPreserve= */ Collections.emptySet(),
+ TEST_KEY);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest);
+ assertNull(loggingResult);
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreEnabled_readEntityDataFails_failureIsLogged()
+ throws IOException {
+ when(mBackupDataInput.readEntityData(any(byte[].class), anyInt(), anyInt()))
+ .thenThrow(new IOException());
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+
+ mAgentUnderTest.restoreSettings(
+ mBackupDataInput,
+ TEST_URI,
+ /* movedToGlobal= */ null,
+ /* movedToSecure= */ null,
+ /* movedToSystem= */ null,
+ /* blockedSettingsArrayId= */ 0,
+ /* dynamicBlockList= */ Collections.emptySet(),
+ /* settingsToPreserve= */ Collections.emptySet(),
+ TEST_KEY);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getFailCount(), 1);
+ assertTrue(loggingResult.getErrors().containsKey(ERROR_COULD_NOT_READ_ENTITY));
+ }
+
+ @Test
+ @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreDisabled_readEntityDataFails_failureIsNotLogged()
+ throws IOException {
+ when(mBackupDataInput.readEntityData(any(byte[].class), anyInt(), anyInt()))
+ .thenThrow(new IOException());
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+
+ mAgentUnderTest.restoreSettings(
+ mBackupDataInput,
+ TEST_URI,
+ /* movedToGlobal= */ null,
+ /* movedToSecure= */ null,
+ /* movedToSystem= */ null,
+ /* blockedSettingsArrayId= */ 0,
+ /* dynamicBlockList= */ Collections.emptySet(),
+ /* settingsToPreserve= */ Collections.emptySet(),
+ TEST_KEY);
+
+ assertNull(getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest));
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreEnabled_settingIsSkippedBySystem_failureIsLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ String[] settingBlockedBySystem = new String[] {OVERRIDDEN_TEST_SETTING};
+ SettingsBackupAgent.SettingsBackupAllowlist allowlist =
+ new SettingsBackupAgent.SettingsBackupAllowlist(
+ settingBlockedBySystem,
+ TEST_VALUES_VALIDATORS);
+ mAgentUnderTest.setSettingsAllowlist(allowlist);
+ mAgentUnderTest.setBlockedSettings(settingBlockedBySystem);
+ TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
+ mAgentUnderTest.mSettingsHelper = settingsHelper;
+
+ byte[] backupData = generateBackupData(TEST_VALUES);
+ mAgentUnderTest
+ .restoreSettings(
+ backupData,
+ /* pos= */ 0,
+ backupData.length,
+ TEST_URI,
+ /* movedToGlobal= */ null,
+ /* movedToSecure= */ null,
+ /* movedToSystem= */ null,
+ /* blockedSettingsArrayId= */ 0,
+ /* dynamicBlockList= */ Collections.emptySet(),
+ /* settingsToPreserve= */ Collections.emptySet(),
+ TEST_KEY);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getFailCount(), 1);
+ assertTrue(loggingResult.getErrors().containsKey(ERROR_SKIPPED_BY_SYSTEM));
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreEnabled_settingIsSkippedByBlockList_failureIsLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ SettingsBackupAgent.SettingsBackupAllowlist allowlist =
+ new SettingsBackupAgent.SettingsBackupAllowlist(
+ new String[] {OVERRIDDEN_TEST_SETTING},
+ TEST_VALUES_VALIDATORS);
+ mAgentUnderTest.setSettingsAllowlist(allowlist);
+ mAgentUnderTest.setBlockedSettings();
+ TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
+ mAgentUnderTest.mSettingsHelper = settingsHelper;
+ Set<String> dynamicBlockList =
+ Set.of(Uri.withAppendedPath(TEST_URI, OVERRIDDEN_TEST_SETTING).toString());
+
+ byte[] backupData = generateBackupData(TEST_VALUES);
+ mAgentUnderTest
+ .restoreSettings(
+ backupData,
+ /* pos= */ 0,
+ backupData.length,
+ TEST_URI,
+ /* movedToGlobal= */ null,
+ /* movedToSecure= */ null,
+ /* movedToSystem= */ null,
+ /* blockedSettingsArrayId= */ 0,
+ dynamicBlockList,
+ /* settingsToPreserve= */ Collections.emptySet(),
+ TEST_KEY);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getFailCount(), 1);
+ assertTrue(loggingResult.getErrors().containsKey(ERROR_SKIPPED_BY_BLOCKLIST));
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreEnabled_settingIsPreserved_failureIsLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ SettingsBackupAgent.SettingsBackupAllowlist allowlist =
+ new SettingsBackupAgent.SettingsBackupAllowlist(
+ new String[] {OVERRIDDEN_TEST_SETTING},
+ TEST_VALUES_VALIDATORS);
+ mAgentUnderTest.setSettingsAllowlist(allowlist);
+ mAgentUnderTest.setBlockedSettings();
+ TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
+ mAgentUnderTest.mSettingsHelper = settingsHelper;
+ Set<String> preservedSettings =
+ Set.of(Uri.withAppendedPath(TEST_URI, OVERRIDDEN_TEST_SETTING).toString());
+
+ byte[] backupData = generateBackupData(TEST_VALUES);
+ mAgentUnderTest
+ .restoreSettings(
+ backupData,
+ /* pos= */ 0,
+ backupData.length,
+ TEST_URI,
+ /* movedToGlobal= */ null,
+ /* movedToSecure= */ null,
+ /* movedToSystem= */ null,
+ /* blockedSettingsArrayId= */ 0,
+ /* dynamicBlockList = */ Collections.emptySet(),
+ preservedSettings,
+ TEST_KEY);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getFailCount(), 1);
+ assertTrue(loggingResult.getErrors().containsKey(ERROR_SKIPPED_PRESERVED));
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreEnabled_settingIsNotValid_failureIsLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ SettingsBackupAgent.SettingsBackupAllowlist allowlist =
+ new SettingsBackupAgent.SettingsBackupAllowlist(
+ new String[] {OVERRIDDEN_TEST_SETTING},
+ /* settingsValidators= */ null);
+ mAgentUnderTest.setSettingsAllowlist(allowlist);
+ mAgentUnderTest.setBlockedSettings();
+ TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
+ mAgentUnderTest.mSettingsHelper = settingsHelper;
+
+ byte[] backupData = generateBackupData(TEST_VALUES);
+ mAgentUnderTest
+ .restoreSettings(
+ backupData,
+ /* pos= */ 0,
+ backupData.length,
+ TEST_URI,
+ /* movedToGlobal= */ null,
+ /* movedToSecure= */ null,
+ /* movedToSystem= */ null,
+ /* blockedSettingsArrayId= */ 0,
+ /* dynamicBlockList = */ Collections.emptySet(),
+ /* settingsToPreserve= */ Collections.emptySet(),
+ TEST_KEY);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getFailCount(), 1);
+ assertTrue(loggingResult.getErrors().containsKey(ERROR_DID_NOT_PASS_VALIDATION));
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreEnabled_settingIsMarkedAsMovedToGlobal_agentMetricsAreLoggedWithGlobalKey() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ SettingsBackupAgent.SettingsBackupAllowlist allowlist =
+ new SettingsBackupAgent.SettingsBackupAllowlist(
+ new String[] {OVERRIDDEN_TEST_SETTING},
+ TEST_VALUES_VALIDATORS);
+ mAgentUnderTest.setSettingsAllowlist(allowlist);
+ mAgentUnderTest.setBlockedSettings();
+ TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
+ mAgentUnderTest.mSettingsHelper = settingsHelper;
+
+ byte[] backupData = generateBackupData(TEST_VALUES);
+ mAgentUnderTest
+ .restoreSettings(
+ backupData,
+ /* pos= */ 0,
+ backupData.length,
+ TEST_URI,
+ /* movedToGlobal= */ Set.of(OVERRIDDEN_TEST_SETTING),
+ /* movedToSecure= */ null,
+ /* movedToSystem= */ null,
+ /* blockedSettingsArrayId= */ 0,
+ /* dynamicBlockList= */ Collections.emptySet(),
+ /* settingsToPreserve= */ Collections.emptySet(),
+ TEST_KEY);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(KEY_GLOBAL, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getSuccessCount(), 1);
+ assertNull(getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest));
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreEnabled_settingIsMarkedAsMovedToSecure_agentMetricsAreLoggedWithSecureKey() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ SettingsBackupAgent.SettingsBackupAllowlist allowlist =
+ new SettingsBackupAgent.SettingsBackupAllowlist(
+ new String[] {OVERRIDDEN_TEST_SETTING},
+ TEST_VALUES_VALIDATORS);
+ mAgentUnderTest.setSettingsAllowlist(allowlist);
+ mAgentUnderTest.setBlockedSettings();
+ TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
+ mAgentUnderTest.mSettingsHelper = settingsHelper;
+
+ byte[] backupData = generateBackupData(TEST_VALUES);
+ mAgentUnderTest
+ .restoreSettings(
+ backupData,
+ /* pos= */ 0,
+ backupData.length,
+ TEST_URI,
+ /* movedToGlobal= */ null,
+ /* movedToSecure= */ Set.of(OVERRIDDEN_TEST_SETTING),
+ /* movedToSystem= */ null,
+ /* blockedSettingsArrayId= */ 0,
+ /* dynamicBlockList= */ Collections.emptySet(),
+ /* settingsToPreserve= */ Collections.emptySet(),
+ TEST_KEY);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(KEY_SECURE, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getSuccessCount(), 1);
+ assertNull(getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest));
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreEnabled_settingIsMarkedAsMovedToSystem_agentMetricsAreLoggedWithSystemKey() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ SettingsBackupAgent.SettingsBackupAllowlist allowlist =
+ new SettingsBackupAgent.SettingsBackupAllowlist(
+ new String[] {OVERRIDDEN_TEST_SETTING},
+ TEST_VALUES_VALIDATORS);
+ mAgentUnderTest.setSettingsAllowlist(allowlist);
+ mAgentUnderTest.setBlockedSettings();
+ TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
+ mAgentUnderTest.mSettingsHelper = settingsHelper;
+
+ byte[] backupData = generateBackupData(TEST_VALUES);
+ mAgentUnderTest
+ .restoreSettings(
+ backupData,
+ /* pos= */ 0,
+ backupData.length,
+ TEST_URI,
+ /* movedToGlobal= */ null,
+ /* movedToSecure= */ null,
+ /* movedToSystem= */ Set.of(OVERRIDDEN_TEST_SETTING),
+ /* blockedSettingsArrayId= */ 0,
+ /* dynamicBlockList= */ Collections.emptySet(),
+ /* settingsToPreserve= */ Collections.emptySet(),
+ TEST_KEY);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(KEY_SYSTEM, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getSuccessCount(), 1);
+ assertNull(getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest));
+ }
+
private byte[] generateBackupData(Map<String, String> keyValueData) {
int totalBytes = 0;
for (String key : keyValueData.keySet()) {
@@ -426,7 +827,8 @@
null,
R.array.restore_blocked_global_settings,
/* dynamicBlockList= */ Collections.emptySet(),
- /* settingsToPreserve= */ Collections.emptySet());
+ /* settingsToPreserve= */ Collections.emptySet(),
+ TEST_KEY);
}
private byte[] generateUncorruptedHeader() throws IOException {
@@ -488,7 +890,7 @@
private static class TestFriendlySettingsBackupAgent extends SettingsBackupAgent {
private Boolean mForcedDeviceInfoRestoreAcceptability = null;
private String[] mBlockedSettings = null;
- private SettingsBackupWhitelist mSettingsWhitelist = null;
+ private SettingsBackupAllowlist mSettingsAllowlist = null;
void setForcedDeviceInfoRestoreAcceptability(boolean value) {
mForcedDeviceInfoRestoreAcceptability = value;
@@ -498,8 +900,8 @@
mBlockedSettings = blockedSettings;
}
- void setSettingsWhitelist(SettingsBackupWhitelist settingsWhitelist) {
- mSettingsWhitelist = settingsWhitelist;
+ void setSettingsAllowlist(SettingsBackupAllowlist settingsAllowlist) {
+ mSettingsAllowlist = settingsAllowlist;
}
@Override
@@ -517,12 +919,12 @@
}
@Override
- SettingsBackupWhitelist getBackupWhitelist(Uri contentUri) {
- if (mSettingsWhitelist == null) {
- return super.getBackupWhitelist(contentUri);
+ SettingsBackupAllowlist getBackupAllowlist(Uri contentUri) {
+ if (mSettingsAllowlist == null) {
+ return super.getBackupAllowlist(contentUri);
}
- return mSettingsWhitelist;
+ return mSettingsAllowlist;
}
void setNumberOfSettingsPerKey(String key, int numberOfSettings) {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index baf829a..65f4877 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -740,9 +740,6 @@
<uses-permission android:name="android.permission.USE_CUSTOM_VIRTUAL_MACHINE" />
<uses-permission android:name="android.permission.DEBUG_VIRTUAL_MACHINE" />
- <!-- Permission required to access bugreport and screenshot files created by wear. -->
- <uses-permission android:name="com.google.wear.permission.ACCESS_BUG_REPORT_FILES" />
-
<!-- Permission required to run GtsAssistantTestCases -->
<uses-permission android:name="android.permission.MANAGE_VOICE_KEYPHRASES" />
@@ -992,6 +989,10 @@
<uses-permission android:name="android.permission.health.READ_SKIN_TEMPERATURE"
android:featureFlag="android.permission.flags.replace_body_sensor_permission_enabled"/>
+ <!-- Permission for TestClassifier tests to get access to classifier by type -->
+ <uses-permission android:name="android.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE"
+ android:featureFlag="android.permission.flags.text_classifier_choice_api_enabled"/>
+
<application
android:label="@string/app_label"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
diff --git a/packages/Shell/res/values/defaults.xml b/packages/Shell/res/values/defaults.xml
new file mode 100644
index 0000000..b693cc8
--- /dev/null
+++ b/packages/Shell/res/values/defaults.xml
@@ -0,0 +1,5 @@
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Default for Wear bugreport warning activity-->
+ <!-- DO NOT TRANSLATE -->
+ <string name="system_ui_wear_bugreport_warning_activity" />
+</resources>
\ No newline at end of file
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 9736831..0694b61 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -1365,7 +1365,11 @@
*/
private Intent buildWearWarningIntent() {
Intent intent = new Intent();
- intent.setClassName(mContext, getPackageName() + ".WearBugreportWarningActivity");
+ String systemUIPackage = mContext.getResources().getString(
+ com.android.internal.R.string.config_systemUi);
+ String wearBugreportWarningActivity = getResources()
+ .getString(R.string.system_ui_wear_bugreport_warning_activity);
+ intent.setClassName(systemUIPackage, wearBugreportWarningActivity);
if (mContext.getPackageManager().resolveActivity(intent, /* flags */ 0) == null) {
Log.e(TAG, "Cannot find wear bugreport warning activity");
return buildWarningIntent(mContext, /* sendIntent */ null);
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 5519b51..11cb070 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -385,6 +385,9 @@
is ready -->
<uses-permission android:name="android.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW" />
+ <!-- To be able to decipher default applications for certain roles in shortcut helper -->
+ <uses-permission android:name="android.permission.MANAGE_DEFAULT_APPLICATIONS" />
+
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ne/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ne/strings.xml
index 10e36b8..9506a7e 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-ne/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-ne/strings.xml
@@ -11,7 +11,7 @@
<string name="recent_apps_label" msgid="6583276995616385847">"हालै चलाइएका एप"</string>
<string name="lockscreen_label" msgid="648347953557887087">"लक स्क्रिन"</string>
<string name="quick_settings_label" msgid="2999117381487601865">"द्रुत सेटिङहरू"</string>
- <string name="notifications_label" msgid="6829741046963013567">"सूचनाहरू"</string>
+ <string name="notifications_label" msgid="6829741046963013567">"नोटिफिकेसनहरू"</string>
<string name="screenshot_label" msgid="863978141223970162">"स्क्रिनसट"</string>
<string name="screenshot_utterance" msgid="1430760563401895074">"स्क्रिनसट लिनुहोस्"</string>
<string name="volume_up_label" msgid="8592766918780362870">"भोल्युम बढाउनुहोस्"</string>
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index c1f7868..ee22915 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1230,13 +1230,6 @@
}
flag {
- name: "communal_hub_on_mobile"
- namespace: "systemui"
- description: "Brings the glanceable hub experience to mobile phones"
- bug: "375689917"
-}
-
-flag {
name: "glanceable_hub_v2"
namespace: "systemui"
description: "Gates the refreshed glanceable hub experience that also brings the glanceable hub to mobile phones"
diff --git a/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java b/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java
index 0317d5f0..d0404ec 100644
--- a/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java
+++ b/packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java
@@ -18,8 +18,11 @@
import android.annotation.Nullable;
import android.graphics.Canvas;
+import android.graphics.Outline;
+import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.os.Build;
import android.util.Log;
import android.view.Surface;
@@ -44,6 +47,9 @@
public class ViewUIComponent implements UIComponent {
private static final String TAG = "ViewUIComponent";
private static final boolean DEBUG = Build.IS_USERDEBUG || Log.isLoggable(TAG, Log.DEBUG);
+ private final Path mClippingPath = new Path();
+ private final Outline mClippingOutline = new Outline();
+
private final OnDrawListener mOnDrawListener = this::postDraw;
private final View mView;
@@ -182,6 +188,17 @@
canvas.scale(
(float) renderBounds.width() / realBounds.width(),
(float) renderBounds.height() / realBounds.height());
+
+ if (mView.getClipToOutline()) {
+ mView.getOutlineProvider().getOutline(mView, mClippingOutline);
+ mClippingPath.reset();
+ RectF rect = new RectF(0, 0, mView.getWidth(), mView.getHeight());
+ final float cornerRadius = mClippingOutline.getRadius();
+ mClippingPath.addRoundRect(rect, cornerRadius, cornerRadius, Path.Direction.CW);
+ mClippingPath.close();
+ canvas.clipPath(mClippingPath);
+ }
+
canvas.saveLayerAlpha(null, (int) (255 * mView.getAlpha()));
mView.draw(canvas);
canvas.restore();
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewTransitionAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewTransitionAnimatorController.kt
index 558c1eba..65cd3c7 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewTransitionAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewTransitionAnimatorController.kt
@@ -397,6 +397,10 @@
ghostedView.visibility = View.VISIBLE
ghostedView.invalidate()
}
+
+ if (isEphemeral) {
+ onDispose()
+ }
}
companion object {
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/ShadeDisplayAwareDetector.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/ShadeDisplayAwareDetector.kt
index 2f83d82..92b6fd4 100644
--- a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/ShadeDisplayAwareDetector.kt
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/ShadeDisplayAwareDetector.kt
@@ -25,6 +25,7 @@
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.intellij.psi.PsiParameter
import org.jetbrains.uast.UClass
import org.jetbrains.uast.getContainingUFile
@@ -40,14 +41,8 @@
if (!isInRelevantShadePackage(node)) continue
if (IGNORED_PACKAGES.contains(node.qualifiedName)) continue
- // Check the any context-dependent parameter to see if it has @ShadeDisplayAware
- // annotation
for (parameter in constructor.parameterList.parameters) {
- val shouldReport =
- CONTEXT_DEPENDENT_SHADE_CLASSES.contains(
- parameter.type.canonicalText
- ) && !parameter.hasAnnotation(SHADE_DISPLAY_AWARE_ANNOTATION)
- if (shouldReport) {
+ if (parameter.shouldReport()) {
context.report(
issue = ISSUE,
scope = parameter.declarationScope,
@@ -62,20 +57,35 @@
companion object {
private const val INJECT_ANNOTATION = "javax.inject.Inject"
+ private const val APPLICATION_ANNOTATION =
+ "com.android.systemui.dagger.qualifiers.Application"
+ private const val GLOBAL_CONFIG_ANNOTATION = "com.android.systemui.common.ui.GlobalConfig"
private const val SHADE_DISPLAY_AWARE_ANNOTATION =
"com.android.systemui.shade.ShadeDisplayAware"
+ private const val CONTEXT = "android.content.Context"
+ private const val WINDOW_MANAGER = "android.view.WindowManager"
+ private const val LAYOUT_INFLATER = "android.view.LayoutInflater"
+ private const val RESOURCES = "android.content.res.Resources"
+ private const val CONFIG_STATE = "com.android.systemui.common.ui.ConfigurationState"
+ private const val CONFIG_CONTROLLER =
+ "com.android.systemui.statusbar.policy.ConfigurationController"
+ private const val CONFIG_INTERACTOR =
+ "com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor"
+
private val CONTEXT_DEPENDENT_SHADE_CLASSES =
setOf(
- "android.content.Context",
- "android.view.WindowManager",
- "android.view.LayoutInflater",
- "android.content.res.Resources",
- "com.android.systemui.common.ui.ConfigurationState",
- "com.android.systemui.statusbar.policy.ConfigurationController",
- "com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor",
+ CONTEXT,
+ WINDOW_MANAGER,
+ LAYOUT_INFLATER,
+ RESOURCES,
+ CONFIG_STATE,
+ CONFIG_CONTROLLER,
+ CONFIG_INTERACTOR,
)
+ private val CONFIG_CLASSES = setOf(CONFIG_STATE, CONFIG_CONTROLLER, CONFIG_INTERACTOR)
+
private val SHADE_WINDOW_PACKAGES =
listOf(
"com.android.systemui.biometrics",
@@ -93,6 +103,22 @@
"com.android.systemui.qs.customize.TileAdapter",
)
+ private fun PsiParameter.shouldReport(): Boolean {
+ val className = type.canonicalText
+
+ // check if the parameter is a context-dependent class relevant to shade
+ if (className !in CONTEXT_DEPENDENT_SHADE_CLASSES) return false
+ // check if it has @ShadeDisplayAware
+ if (hasAnnotation(SHADE_DISPLAY_AWARE_ANNOTATION)) return false
+ // check if its a @Application-annotated Context
+ if (className == CONTEXT && hasAnnotation(APPLICATION_ANNOTATION)) return false
+ // check if its a @GlobalConfig-annotated ConfigurationState, ConfigurationController
+ // or ConfigurationInteractor
+ if (className in CONFIG_CLASSES && hasAnnotation(GLOBAL_CONFIG_ANNOTATION)) return false
+
+ return true
+ }
+
private fun isInRelevantShadePackage(node: UClass): Boolean {
val packageName = node.getContainingUFile()?.packageName
if (packageName.isNullOrBlank()) return false
@@ -102,15 +128,15 @@
}
private fun reportMsg(className: String) =
- """UI elements of the shade window
- |should use ShadeDisplayAware-annotated $className, as the shade might move between windows, and only
- |@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so
- |might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).
- |If the usage of $className is not related to display specific configuration or UI, then there is
- |technically no need to use the annotation, and you can annotate the class with
- |@SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")
- |"""
- .trimMargin()
+ "UI elements of the shade window should use " +
+ "ShadeDisplayAware-annotated $className, as the shade might move between windows, " +
+ "and only @ShadeDisplayAware resources are updated with the new configuration " +
+ "correctly. Failures to do so might result in wrong dimensions for shade window " +
+ "classes (e.g. using the wrong density or theme). If the usage of $className is " +
+ "not related to display specific configuration or UI, then there is technically " +
+ "no need to use the annotation, and you can annotate the class with " +
+ "@SuppressLint(\"ShadeDisplayAwareContextChecker\")/" +
+ "@Suppress(\"ShadeDisplayAwareContextChecker\")".trimMargin()
@JvmField
val ISSUE: Issue =
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/ShadeDisplayAwareDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/ShadeDisplayAwareDetectorTest.kt
index 58ad363..79f1907 100644
--- a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/ShadeDisplayAwareDetectorTest.kt
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/ShadeDisplayAwareDetectorTest.kt
@@ -63,6 +63,26 @@
)
.indented()
+ private val applicationStub: TestFile =
+ kotlin(
+ """
+ package com.android.systemui.dagger.qualifiers
+
+ @Retention(AnnotationRetention.RUNTIME) annotation class Application
+ """
+ )
+ .indented()
+
+ private val globalConfigStub: TestFile =
+ kotlin(
+ """
+ package com.android.systemui.common.ui
+
+ @Retention(AnnotationRetention.RUNTIME) annotation class GlobalConfig
+ """
+ )
+ .indented()
+
private val configStateStub: TestFile =
kotlin(
"""
@@ -98,6 +118,8 @@
injectStub,
qsContext,
shadeDisplayAwareStub,
+ applicationStub,
+ globalConfigStub,
configStateStub,
configControllerStub,
configInteractorStub,
@@ -259,6 +281,60 @@
}
@Test
+ fun injectedConstructor_inRelevantPackage_withApplicationAnnotatedContext() {
+ lint()
+ .files(
+ TestFiles.kotlin(
+ """
+ package com.android.systemui.shade.example
+
+ import javax.inject.Inject
+ import android.content.Context
+ import com.android.systemui.dagger.qualifiers.Application
+
+ class ExampleClass
+ @Inject
+ constructor(@Application private val context: Context)
+ """
+ .trimIndent()
+ ),
+ *androidStubs,
+ *otherStubs,
+ )
+ .issues(ShadeDisplayAwareDetector.ISSUE)
+ .testModes(TestMode.DEFAULT)
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun injectedConstructor_inRelevantPackage_withGlobalConfigAnnotatedConfigurationClass() {
+ lint()
+ .files(
+ TestFiles.kotlin(
+ """
+ package com.android.systemui.shade.example
+
+ import javax.inject.Inject
+ import com.android.systemui.common.ui.ConfigurationState
+ import com.android.systemui.common.ui.GlobalConfig
+
+ class ExampleClass
+ @Inject
+ constructor(@GlobalConfig private val configState: ConfigurationState)
+ """
+ .trimIndent()
+ ),
+ *androidStubs,
+ *otherStubs,
+ )
+ .issues(ShadeDisplayAwareDetector.ISSUE)
+ .testModes(TestMode.DEFAULT)
+ .run()
+ .expectClean()
+ }
+
+ @Test
fun injectedConstructor_notInRelevantPackage_withRelevantParameter_withoutAnnotation() {
lint()
.files(
@@ -363,13 +439,13 @@
}
private fun errorMsgString(lineNumber: Int, className: String) =
- """
- src/com/android/systemui/shade/example/ExampleClass.kt:$lineNumber: Error: UI elements of the shade window
- should use ShadeDisplayAware-annotated $className, as the shade might move between windows, and only
- @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so
- might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).
- If the usage of $className is not related to display specific configuration or UI, then there is
- technically no need to use the annotation, and you can annotate the class with
- @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")
- """
+ "src/com/android/systemui/shade/example/ExampleClass.kt:$lineNumber: Error: UI elements of " +
+ "the shade window should use ShadeDisplayAware-annotated $className, as the shade " +
+ "might move between windows, and only @ShadeDisplayAware resources are updated with " +
+ "the new configuration correctly. Failures to do so might result in wrong dimensions " +
+ "for shade window classes (e.g. using the wrong density or theme). If the usage of " +
+ "$className is not related to display specific configuration or UI, then there is " +
+ "technically no need to use the annotation, and you can annotate the class with " +
+ "@SuppressLint(\"ShadeDisplayAwareContextChecker\")" +
+ "/@Suppress(\"ShadeDisplayAwareContextChecker\")"
}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
index 58b8836..9fe85b7 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
@@ -111,22 +111,24 @@
draggable: NestedDraggable,
orientation: Orientation,
overscrollEffect: OverscrollEffect? = null,
+ enabled: Boolean = true,
): Modifier {
return this.thenIf(overscrollEffect != null) { Modifier.overscroll(overscrollEffect) }
- .then(NestedDraggableElement(draggable, orientation, overscrollEffect))
+ .then(NestedDraggableElement(draggable, orientation, overscrollEffect, enabled))
}
private data class NestedDraggableElement(
private val draggable: NestedDraggable,
private val orientation: Orientation,
private val overscrollEffect: OverscrollEffect?,
+ private val enabled: Boolean,
) : ModifierNodeElement<NestedDraggableNode>() {
override fun create(): NestedDraggableNode {
- return NestedDraggableNode(draggable, orientation, overscrollEffect)
+ return NestedDraggableNode(draggable, orientation, overscrollEffect, enabled)
}
override fun update(node: NestedDraggableNode) {
- node.update(draggable, orientation, overscrollEffect)
+ node.update(draggable, orientation, overscrollEffect, enabled)
}
}
@@ -134,6 +136,7 @@
private var draggable: NestedDraggable,
override var orientation: Orientation,
private var overscrollEffect: OverscrollEffect?,
+ private var enabled: Boolean,
) :
DelegatingNode(),
PointerInputModifierNode,
@@ -179,14 +182,22 @@
draggable: NestedDraggable,
orientation: Orientation,
overscrollEffect: OverscrollEffect?,
+ enabled: Boolean,
) {
this.draggable = draggable
this.orientation = orientation
this.overscrollEffect = overscrollEffect
+ this.enabled = enabled
trackDownPositionDelegate?.resetPointerInputHandler()
detectDragsDelegate?.resetPointerInputHandler()
nestedScrollController?.ensureOnDragStoppedIsCalled()
+
+ if (!enabled && trackDownPositionDelegate != null) {
+ check(detectDragsDelegate != null)
+ trackDownPositionDelegate = null
+ detectDragsDelegate = null
+ }
}
override fun onPointerEvent(
@@ -194,6 +205,8 @@
pass: PointerEventPass,
bounds: IntSize,
) {
+ if (!enabled) return
+
if (trackDownPositionDelegate == null) {
check(detectDragsDelegate == null)
trackDownPositionDelegate = SuspendingPointerInputModifierNode { trackDownPosition() }
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/theme/Color.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/Color.kt
index a499447..fe3faaf 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/theme/Color.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/Color.kt
@@ -37,4 +37,4 @@
@ColorInt val color = ta.getColor(0, 0)
ta.recycle()
return Color(color)
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
index f8561b8..fd3902f 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
@@ -344,6 +344,45 @@
assertThat(draggable.onDragStoppedCalled).isTrue()
}
+ @Test
+ fun enabled() {
+ val draggable = TestDraggable()
+ var enabled by mutableStateOf(false)
+ val touchSlop =
+ rule.setContentWithTouchSlop {
+ Box(
+ Modifier.fillMaxSize()
+ .nestedDraggable(draggable, orientation, enabled = enabled)
+ )
+ }
+
+ assertThat(draggable.onDragStartedCalled).isFalse()
+
+ rule.onRoot().performTouchInput {
+ down(center)
+ moveBy(touchSlop.toOffset())
+ }
+
+ assertThat(draggable.onDragStartedCalled).isFalse()
+ assertThat(draggable.onDragStoppedCalled).isFalse()
+
+ enabled = true
+ rule.onRoot().performTouchInput {
+ // Release previously up finger.
+ up()
+
+ down(center)
+ moveBy(touchSlop.toOffset())
+ }
+
+ assertThat(draggable.onDragStartedCalled).isTrue()
+ assertThat(draggable.onDragStoppedCalled).isFalse()
+
+ enabled = false
+ rule.waitForIdle()
+ assertThat(draggable.onDragStoppedCalled).isTrue()
+ }
+
private fun ComposeContentTestRule.setContentWithTouchSlop(
content: @Composable () -> Unit
): Float {
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 737853b..96989a2 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
@@ -16,8 +16,8 @@
package com.android.compose.theme
+import android.annotation.ColorRes
import android.content.Context
-import androidx.annotation.AttrRes
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@@ -70,118 +70,118 @@
val colorValues = mutableListOf<ColorValue>()
fun onLaunch(colorScheme: ColorScheme, context: Context) {
- fun addValue(name: String, materialValue: Color, @AttrRes attr: Int) {
- colorValues.add(ColorValue(name, materialValue, colorAttr(context, attr)))
+ fun addValue(name: String, materialValue: Color, @ColorRes color: Int) {
+ colorValues.add(ColorValue(name, materialValue, Color(context.getColor(color))))
}
- addValue("primary", colorScheme.primary, R.attr.materialColorPrimary)
- addValue("onPrimary", colorScheme.onPrimary, R.attr.materialColorOnPrimary)
+ addValue("primary", colorScheme.primary, R.color.materialColorPrimary)
+ addValue("onPrimary", colorScheme.onPrimary, R.color.materialColorOnPrimary)
addValue(
"primaryContainer",
colorScheme.primaryContainer,
- R.attr.materialColorPrimaryContainer,
+ R.color.materialColorPrimaryContainer,
)
addValue(
"onPrimaryContainer",
colorScheme.onPrimaryContainer,
- R.attr.materialColorOnPrimaryContainer,
+ R.color.materialColorOnPrimaryContainer,
)
addValue(
"inversePrimary",
colorScheme.inversePrimary,
- R.attr.materialColorInversePrimary,
+ R.color.materialColorInversePrimary,
)
- addValue("secondary", colorScheme.secondary, R.attr.materialColorSecondary)
- addValue("onSecondary", colorScheme.onSecondary, R.attr.materialColorOnSecondary)
+ addValue("secondary", colorScheme.secondary, R.color.materialColorSecondary)
+ addValue("onSecondary", colorScheme.onSecondary, R.color.materialColorOnSecondary)
addValue(
"secondaryContainer",
colorScheme.secondaryContainer,
- R.attr.materialColorSecondaryContainer,
+ R.color.materialColorSecondaryContainer,
)
addValue(
"onSecondaryContainer",
colorScheme.onSecondaryContainer,
- R.attr.materialColorOnSecondaryContainer,
+ R.color.materialColorOnSecondaryContainer,
)
- addValue("tertiary", colorScheme.tertiary, R.attr.materialColorTertiary)
- addValue("onTertiary", colorScheme.onTertiary, R.attr.materialColorOnTertiary)
+ addValue("tertiary", colorScheme.tertiary, R.color.materialColorTertiary)
+ addValue("onTertiary", colorScheme.onTertiary, R.color.materialColorOnTertiary)
addValue(
"tertiaryContainer",
colorScheme.tertiaryContainer,
- R.attr.materialColorTertiaryContainer,
+ R.color.materialColorTertiaryContainer,
)
addValue(
"onTertiaryContainer",
colorScheme.onTertiaryContainer,
- R.attr.materialColorOnTertiaryContainer,
+ R.color.materialColorOnTertiaryContainer,
)
- addValue("onBackground", colorScheme.onBackground, R.attr.materialColorOnBackground)
- addValue("surface", colorScheme.surface, R.attr.materialColorSurface)
- addValue("onSurface", colorScheme.onSurface, R.attr.materialColorOnSurface)
+ addValue("onBackground", colorScheme.onBackground, R.color.materialColorOnBackground)
+ addValue("surface", colorScheme.surface, R.color.materialColorSurface)
+ addValue("onSurface", colorScheme.onSurface, R.color.materialColorOnSurface)
addValue(
"surfaceVariant",
colorScheme.surfaceVariant,
- R.attr.materialColorSurfaceVariant,
+ R.color.materialColorSurfaceVariant,
)
addValue(
"onSurfaceVariant",
colorScheme.onSurfaceVariant,
- R.attr.materialColorOnSurfaceVariant,
+ R.color.materialColorOnSurfaceVariant,
)
addValue(
"inverseSurface",
colorScheme.inverseSurface,
- R.attr.materialColorInverseSurface,
+ R.color.materialColorInverseSurface,
)
addValue(
"inverseOnSurface",
colorScheme.inverseOnSurface,
- R.attr.materialColorInverseOnSurface,
+ R.color.materialColorInverseOnSurface,
)
- addValue("error", colorScheme.error, R.attr.materialColorError)
- addValue("onError", colorScheme.onError, R.attr.materialColorOnError)
+ addValue("error", colorScheme.error, R.color.materialColorError)
+ addValue("onError", colorScheme.onError, R.color.materialColorOnError)
addValue(
"errorContainer",
colorScheme.errorContainer,
- R.attr.materialColorErrorContainer,
+ R.color.materialColorErrorContainer,
)
addValue(
"onErrorContainer",
colorScheme.onErrorContainer,
- R.attr.materialColorOnErrorContainer,
+ R.color.materialColorOnErrorContainer,
)
- addValue("outline", colorScheme.outline, R.attr.materialColorOutline)
+ addValue("outline", colorScheme.outline, R.color.materialColorOutline)
addValue(
"outlineVariant",
colorScheme.outlineVariant,
- R.attr.materialColorOutlineVariant,
+ R.color.materialColorOutlineVariant,
)
- addValue("surfaceBright", colorScheme.surfaceBright, R.attr.materialColorSurfaceBright)
- addValue("surfaceDim", colorScheme.surfaceDim, R.attr.materialColorSurfaceDim)
+ addValue("surfaceBright", colorScheme.surfaceBright, R.color.materialColorSurfaceBright)
+ addValue("surfaceDim", colorScheme.surfaceDim, R.color.materialColorSurfaceDim)
addValue(
"surfaceContainer",
colorScheme.surfaceContainer,
- R.attr.materialColorSurfaceContainer,
+ R.color.materialColorSurfaceContainer,
)
addValue(
"surfaceContainerHigh",
colorScheme.surfaceContainerHigh,
- R.attr.materialColorSurfaceContainerHigh,
+ R.color.materialColorSurfaceContainerHigh,
)
addValue(
"surfaceContainerHighest",
colorScheme.surfaceContainerHighest,
- R.attr.materialColorSurfaceContainerHighest,
+ R.color.materialColorSurfaceContainerHighest,
)
addValue(
"surfaceContainerLow",
colorScheme.surfaceContainerLow,
- R.attr.materialColorSurfaceContainerLow,
+ R.color.materialColorSurfaceContainerLow,
)
addValue(
"surfaceContainerLowest",
colorScheme.surfaceContainerLowest,
- R.attr.materialColorSurfaceContainerLowest,
+ R.color.materialColorSurfaceContainerLowest,
)
}
@@ -200,9 +200,9 @@
"MaterialTheme.colorScheme.${colorValue.name} matches attribute color"
)
.that(colorValue.materialValue)
- .isEqualTo(colorValue.attrValue)
+ .isEqualTo(colorValue.colorValue)
}
}
- private data class ColorValue(val name: String, val materialValue: Color, val attrValue: Color)
+ private data class ColorValue(val name: String, val materialValue: Color, val colorValue: Color)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Color.kt b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Color.kt
index 64b9f2d..81ae6b3 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Color.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/Color.kt
@@ -19,6 +19,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.colorResource
import com.android.compose.theme.colorAttr
/** Resolves [com.android.systemui.common.shared.model.Color] into [Color] */
@@ -28,5 +29,6 @@
return when (this) {
is com.android.systemui.common.shared.model.Color.Attribute -> colorAttr(attribute)
is com.android.systemui.common.shared.model.Color.Loaded -> Color(color)
+ is com.android.systemui.common.shared.model.Color.Resource -> colorResource(colorRes)
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index 4705d8d..beaf963 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -44,7 +44,6 @@
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.observableTransitionState
import com.android.compose.animation.scene.transitions
-import com.android.systemui.Flags.communalHubOnMobile
import com.android.systemui.communal.shared.model.CommunalBackgroundType
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.CommunalTransitionKeys
@@ -188,7 +187,7 @@
scene(
CommunalScenes.Blank,
userActions =
- if (communalHubOnMobile()) emptyMap()
+ if (viewModel.v2FlagEnabled()) emptyMap()
else mapOf(Swipe.Start(fromSource = Edge.End) to CommunalScenes.Communal),
) {
// This scene shows nothing only allowing for transitions to the communal scene.
@@ -198,7 +197,8 @@
scene(
CommunalScenes.Communal,
userActions =
- if (communalHubOnMobile()) emptyMap() else mapOf(Swipe.End to CommunalScenes.Blank),
+ if (viewModel.v2FlagEnabled()) emptyMap()
+ else mapOf(Swipe.End to CommunalScenes.Blank),
) {
CommunalScene(
backgroundType = backgroundType,
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 778d7e7..a17a1d4 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
@@ -23,11 +23,17 @@
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.Measurable
+import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntRect
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.zIndex
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.communal.smartspace.SmartspaceInteractionHandler
import com.android.systemui.communal.ui.compose.section.AmbientStatusBarSection
import com.android.systemui.communal.ui.compose.section.CommunalPopupSection
+import com.android.systemui.communal.ui.compose.section.CommunalToDreamButtonSection
import com.android.systemui.communal.ui.view.layout.sections.CommunalAppWidgetSection
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.keyguard.ui.composable.blueprint.BlueprintAlignmentLines
@@ -48,6 +54,7 @@
private val ambientStatusBarSection: AmbientStatusBarSection,
private val communalPopupSection: CommunalPopupSection,
private val widgetSection: CommunalAppWidgetSection,
+ private val communalToDreamButtonSection: CommunalToDreamButtonSection,
) {
@Composable
@@ -59,7 +66,7 @@
Box(modifier = Modifier.fillMaxSize()) {
with(communalPopupSection) { Popup() }
with(ambientStatusBarSection) {
- AmbientStatusBar(modifier = Modifier.fillMaxWidth())
+ AmbientStatusBar(modifier = Modifier.fillMaxWidth().zIndex(1f))
}
CommunalHub(
viewModel = viewModel,
@@ -81,11 +88,13 @@
Modifier.element(Communal.Elements.IndicationArea).fillMaxWidth()
)
}
+ with(communalToDreamButtonSection) { Button() }
},
) { measurables, constraints ->
val communalGridMeasurable = measurables[0]
val lockIconMeasurable = measurables[1]
val bottomAreaMeasurable = measurables[2]
+ val screensaverButtonMeasurable: Measurable? = measurables.getOrNull(3)
val noMinConstraints = constraints.copy(minWidth = 0, minHeight = 0)
@@ -100,6 +109,15 @@
val bottomAreaPlaceable = bottomAreaMeasurable.measure(noMinConstraints)
+ val screensaverButtonSizeInt = screensaverButtonSize.roundToPx()
+ val screensaverButtonPlaceable =
+ screensaverButtonMeasurable?.measure(
+ Constraints.fixed(
+ width = screensaverButtonSizeInt,
+ height = screensaverButtonSizeInt,
+ )
+ )
+
val communalGridPlaceable =
communalGridMeasurable.measure(
noMinConstraints.copy(maxHeight = lockIconBounds.top)
@@ -108,12 +126,22 @@
layout(constraints.maxWidth, constraints.maxHeight) {
communalGridPlaceable.place(x = 0, y = 0)
lockIconPlaceable.place(x = lockIconBounds.left, y = lockIconBounds.top)
- bottomAreaPlaceable.place(
- x = 0,
- y = constraints.maxHeight - bottomAreaPlaceable.height,
+
+ val bottomAreaTop = constraints.maxHeight - bottomAreaPlaceable.height
+ bottomAreaPlaceable.place(x = 0, y = bottomAreaTop)
+ screensaverButtonPlaceable?.place(
+ x =
+ constraints.maxWidth -
+ screensaverButtonSizeInt -
+ Dimensions.ItemSpacing.roundToPx(),
+ y = lockIconBounds.top,
)
}
}
}
}
+
+ companion object {
+ val screensaverButtonSize: Dp = 64.dp
+ }
}
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 573e5ca..a55b6d7 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
@@ -187,6 +187,7 @@
import com.android.systemui.communal.ui.viewmodel.ResizeInfo
import com.android.systemui.communal.ui.viewmodel.ResizeableItemFrameViewModel
import com.android.systemui.communal.util.DensityUtils.Companion.adjustedDp
+import com.android.systemui.communal.util.ResizeUtils.resizeOngoingItems
import com.android.systemui.communal.widgets.SmartspaceAppWidgetHostView
import com.android.systemui.communal.widgets.WidgetConfigurator
import com.android.systemui.lifecycle.rememberViewModel
@@ -217,6 +218,7 @@
var removeButtonCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
var toolbarSize: IntSize? by remember { mutableStateOf(null) }
var gridCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
+ var contentOffset: Offset by remember { mutableStateOf(Offset.Zero) }
val gridState =
rememberLazyGridState(viewModel.savedFirstScrollIndex, viewModel.savedFirstScrollOffset)
@@ -239,9 +241,7 @@
initialValue = !viewModel.isEditMode
)
- val contentPadding = gridContentPadding(viewModel.isEditMode, toolbarSize)
- val contentOffset = beforeContentPadding(contentPadding).toOffset()
-
+ val minContentPadding = gridContentPadding(viewModel.isEditMode, toolbarSize)
ObserveScrollEffect(gridState, viewModel)
val context = LocalContext.current
@@ -367,7 +367,7 @@
) {
AccessibilityContainer(viewModel) {
if (!viewModel.isEditMode && isEmptyState) {
- EmptyStateCta(contentPadding = contentPadding, viewModel = viewModel)
+ EmptyStateCta(contentPadding = minContentPadding, viewModel = viewModel)
} else {
val slideOffsetInPx =
with(LocalDensity.current) { Dimensions.SlideOffsetY.toPx().toInt() }
@@ -396,10 +396,11 @@
CommunalHubLazyGrid(
communalContent = communalContent,
viewModel = viewModel,
- contentPadding = contentPadding,
+ minContentPadding = minContentPadding,
contentOffset = contentOffset,
screenWidth = screenWidth,
setGridCoordinates = { gridCoordinates = it },
+ setContentOffset = { contentOffset = it },
updateDragPositionForRemove = { boundingBox ->
val gridOffset = gridCoordinates?.positionInWindow()
val removeButtonCenter =
@@ -741,8 +742,9 @@
@Composable
private fun HorizontalGridWrapper(
- contentPadding: PaddingValues,
+ minContentPadding: PaddingValues,
gridState: LazyGridState,
+ setContentOffset: (offset: Offset) -> Unit,
modifier: Modifier = Modifier,
content: LazyGridScope.(sizeInfo: SizeInfo?) -> Unit,
) {
@@ -751,17 +753,26 @@
cellAspectRatio = 1.5f,
modifier = modifier,
state = gridState,
- minContentPadding = contentPadding,
+ minContentPadding = minContentPadding,
minHorizontalArrangement = Dimensions.ItemSpacing,
minVerticalArrangement = Dimensions.ItemSpacing,
+ setContentOffset = setContentOffset,
content = content,
)
} else {
+ val layoutDirection = LocalLayoutDirection.current
+ val density = LocalDensity.current
+
+ val minStartPadding = minContentPadding.calculateStartPadding(layoutDirection)
+ val minTopPadding = minContentPadding.calculateTopPadding()
+
+ with(density) { setContentOffset(Offset(minStartPadding.toPx(), minTopPadding.toPx())) }
+
LazyHorizontalGrid(
modifier = modifier,
state = gridState,
rows = GridCells.Fixed(CommunalContentSize.FixedSize.FULL.span),
- contentPadding = contentPadding,
+ contentPadding = minContentPadding,
horizontalArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing),
verticalArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing),
) {
@@ -775,13 +786,14 @@
private fun BoxScope.CommunalHubLazyGrid(
communalContent: List<CommunalContentModel>,
viewModel: BaseCommunalViewModel,
- contentPadding: PaddingValues,
+ minContentPadding: PaddingValues,
selectedKey: State<String?>,
screenWidth: Int,
contentOffset: Offset,
gridState: LazyGridState,
contentListState: ContentListState,
setGridCoordinates: (coordinates: LayoutCoordinates) -> Unit,
+ setContentOffset: (offset: Offset) -> Unit,
updateDragPositionForRemove: (boundingBox: IntRect) -> Boolean,
widgetConfigurator: WidgetConfigurator?,
interactionHandler: RemoteViews.InteractionHandler?,
@@ -832,10 +844,19 @@
HorizontalGridWrapper(
modifier = gridModifier,
gridState = gridState,
- contentPadding = contentPadding,
+ minContentPadding = minContentPadding,
+ setContentOffset = setContentOffset,
) { sizeInfo ->
+ /** Override spans based on the responsive grid size */
+ val finalizedList =
+ if (sizeInfo != null) {
+ resizeOngoingItems(list, sizeInfo.gridSize.height)
+ } else {
+ list
+ }
+
itemsIndexed(
- items = list,
+ items = finalizedList,
key = { _, item -> item.key },
contentType = { _, item -> item.key },
span = { _, item -> GridItemSpan(item.getSpanOrMax(sizeInfo?.gridSize?.height)) },
@@ -883,7 +904,7 @@
key = item.key,
currentSpan = GridItemSpan(currentItemSpan),
gridState = gridState,
- gridContentPadding = contentPadding,
+ gridContentPadding = sizeInfo?.contentPadding ?: minContentPadding,
verticalArrangement =
Arrangement.spacedBy(
sizeInfo?.verticalArrangement ?: Dimensions.ItemSpacing
@@ -1193,6 +1214,7 @@
is CommunalContentModel.Smartspace -> SmartspaceContent(interactionHandler, model, modifier)
is CommunalContentModel.Tutorial -> TutorialContent(modifier)
is CommunalContentModel.Umo -> Umo(viewModel, sceneScope, modifier)
+ is CommunalContentModel.Spacer -> Box(Modifier.fillMaxSize())
}
}
@@ -1723,24 +1745,22 @@
val windowMetrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
val screenHeight = with(density) { windowMetrics.bounds.height().toDp() }
val toolbarHeight = with(density) { Dimensions.ToolbarPaddingTop + toolbarSize.height.toDp() }
- val verticalPadding =
- ((screenHeight - toolbarHeight - hubDimensions.GridHeight + hubDimensions.GridTopSpacing) /
- 2)
- .coerceAtLeast(Dimensions.Spacing)
- return PaddingValues(
- start = Dimensions.ToolbarPaddingHorizontal,
- end = Dimensions.ToolbarPaddingHorizontal,
- top = verticalPadding + toolbarHeight,
- bottom = verticalPadding,
- )
-}
-
-@Composable
-private fun beforeContentPadding(paddingValues: PaddingValues): ContentPaddingInPx {
- return with(LocalDensity.current) {
- ContentPaddingInPx(
- start = paddingValues.calculateStartPadding(LocalLayoutDirection.current).toPx(),
- top = paddingValues.calculateTopPadding().toPx(),
+ return if (communalResponsiveGrid()) {
+ PaddingValues(
+ start = Dimensions.ToolbarPaddingHorizontal,
+ end = Dimensions.ToolbarPaddingHorizontal,
+ top = hubDimensions.GridTopSpacing,
+ )
+ } else {
+ val verticalPadding =
+ ((screenHeight - toolbarHeight - hubDimensions.GridHeight +
+ hubDimensions.GridTopSpacing) / 2)
+ .coerceAtLeast(Dimensions.Spacing)
+ PaddingValues(
+ start = Dimensions.ToolbarPaddingHorizontal,
+ end = Dimensions.ToolbarPaddingHorizontal,
+ top = verticalPadding + toolbarHeight,
+ bottom = verticalPadding,
)
}
}
@@ -1760,10 +1780,6 @@
private fun keyAtIndexIfEditable(list: List<CommunalContentModel>, index: Int): String? =
if (index in list.indices && list[index].isWidgetContent()) list[index].key else null
-data class ContentPaddingInPx(val start: Float, val top: Float) {
- fun toOffset(): Offset = Offset(start, top)
-}
-
class Dimensions(val context: Context, val config: Configuration) {
val GridTopSpacing: Dp
get() {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt
index 7a50080..ef5e90b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt
@@ -94,7 +94,7 @@
private val scope: CoroutineScope,
private val updateDragPositionForRemove: (draggingBoundingBox: IntRect) -> Boolean,
) {
- var draggingItemKey by mutableStateOf<String?>(null)
+ var draggingItemKey by mutableStateOf<Any?>(null)
private set
var isDraggingToRemove by mutableStateOf(false)
@@ -138,7 +138,7 @@
// before content padding from the initial pointer position
.firstItemAtOffset(normalizedOffset - contentOffset)
?.apply {
- draggingItemKey = key as String
+ draggingItemKey = key
draggingItemInitialOffset = this.offset.toOffset()
return true
}
@@ -284,9 +284,7 @@
contentOffset,
)
) {
- // draggingItemKey is guaranteed to be non-null here because it is set in
- // onDragStart()
- viewModel.onReorderWidgetStart(dragDropState.draggingItemKey!!)
+ viewModel.onReorderWidgetStart()
}
},
onDragEnd = {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt
index 3642127..21b3474 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt
@@ -35,7 +35,9 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
@@ -54,6 +56,7 @@
cellAspectRatio: Float,
modifier: Modifier = Modifier,
state: LazyGridState = rememberLazyGridState(),
+ setContentOffset: (offset: Offset) -> Unit = {},
minContentPadding: PaddingValues = PaddingValues(0.dp),
minHorizontalArrangement: Dp = 0.dp,
minVerticalArrangement: Dp = 0.dp,
@@ -70,6 +73,7 @@
BoxWithConstraints(modifier) {
val gridSize = rememberGridSize(maxWidth = maxWidth, maxHeight = maxHeight)
val layoutDirection = LocalLayoutDirection.current
+ val density = LocalDensity.current
val minStartPadding = minContentPadding.calculateStartPadding(layoutDirection)
val minEndPadding = minContentPadding.calculateEndPadding(layoutDirection)
@@ -124,14 +128,19 @@
val extraWidth = maxWidth - usedWidth
val extraHeight = maxHeight - usedHeight
+ val finalStartPadding = minStartPadding + extraWidth / 2
+ val finalTopPadding = minTopPadding + extraHeight / 2
+
val finalContentPadding =
PaddingValues(
- start = minStartPadding + extraWidth / 2,
+ start = finalStartPadding,
end = minEndPadding + extraWidth / 2,
- top = minTopPadding + extraHeight / 2,
+ top = finalTopPadding,
bottom = minBottomPadding + extraHeight / 2,
)
+ with(density) { setContentOffset(Offset(finalStartPadding.toPx(), finalTopPadding.toPx())) }
+
LazyHorizontalGrid(
rows = GridCells.Fixed(gridSize.height),
modifier = Modifier.fillMaxSize(),
@@ -179,12 +188,13 @@
* @property verticalArrangement The space between rows in the grid.
* @property gridSize The size of the grid, in cell units.
* @property availableHeight The maximum height an item in the grid may occupy.
+ * @property contentPadding The padding around the content of the grid.
*/
data class SizeInfo(
val cellSize: DpSize,
val verticalArrangement: Dp,
val gridSize: IntSize,
- private val contentPadding: PaddingValues,
+ val contentPadding: PaddingValues,
private val maxHeight: Dp,
) {
val availableHeight: Dp
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalToDreamButtonSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalToDreamButtonSection.kt
new file mode 100644
index 0000000..9421596
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalToDreamButtonSection.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.communal.ui.compose.section
+
+import androidx.compose.material3.IconButtonDefaults
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.res.stringResource
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.compose.PlatformIconButton
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
+import com.android.systemui.communal.ui.viewmodel.CommunalToDreamButtonViewModel
+import com.android.systemui.lifecycle.rememberViewModel
+import com.android.systemui.res.R
+import javax.inject.Inject
+
+class CommunalToDreamButtonSection
+@Inject
+constructor(
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
+ private val viewModelFactory: CommunalToDreamButtonViewModel.Factory,
+) {
+ @Composable
+ fun Button() {
+ if (!communalSettingsInteractor.isV2FlagEnabled()) {
+ return
+ }
+
+ val viewModel =
+ rememberViewModel("CommunalToDreamButtonSection") { viewModelFactory.create() }
+ val shouldShowDreamButtonOnHub by
+ viewModel.shouldShowDreamButtonOnHub.collectAsStateWithLifecycle(false)
+
+ if (!shouldShowDreamButtonOnHub) {
+ return
+ }
+
+ PlatformIconButton(
+ onClick = { viewModel.onShowDreamButtonTap() },
+ iconResource = R.drawable.ic_screensaver_auto,
+ contentDescription =
+ stringResource(R.string.accessibility_glanceable_hub_to_dream_button),
+ colors =
+ IconButtonDefaults.filledIconButtonColors(
+ contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
+ containerColor = MaterialTheme.colorScheme.primaryContainer,
+ ),
+ )
+ }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt
index da78eed..1cee4d6 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt
@@ -77,7 +77,7 @@
resources.getDimensionPixelSize(
R.dimen.keyguard_status_view_bottom_margin
)
- }
+ },
)
) {
if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) {
@@ -87,6 +87,7 @@
val paddingBelowClockStart =
dimensionResource(R.dimen.below_clock_padding_start)
val paddingBelowClockEnd = dimensionResource(R.dimen.below_clock_padding_end)
+ val paddingCardHorizontal = paddingBelowClockEnd
if (keyguardSmartspaceViewModel.isDateWeatherDecoupled) {
Row(
@@ -96,16 +97,14 @@
// All items will be constrained to be as tall as the shortest
// item.
.height(IntrinsicSize.Min)
- .padding(
- start = paddingBelowClockStart,
- ),
+ .padding(start = paddingBelowClockStart),
) {
Date(
modifier =
Modifier.burnInAware(
viewModel = aodBurnInViewModel,
params = burnInParams,
- ),
+ )
)
Spacer(modifier = Modifier.width(4.dp))
Weather(
@@ -113,7 +112,7 @@
Modifier.burnInAware(
viewModel = aodBurnInViewModel,
params = burnInParams,
- ),
+ )
)
}
}
@@ -121,14 +120,8 @@
Card(
modifier =
Modifier.fillMaxWidth()
- .padding(
- start = paddingBelowClockStart,
- end = paddingBelowClockEnd,
- )
- .burnInAware(
- viewModel = aodBurnInViewModel,
- params = burnInParams,
- ),
+ .padding(start = paddingCardHorizontal, end = paddingCardHorizontal)
+ .burnInAware(viewModel = aodBurnInViewModel, params = burnInParams)
)
}
}
@@ -136,9 +129,7 @@
}
@Composable
- private fun Card(
- modifier: Modifier = Modifier,
- ) {
+ private fun Card(modifier: Modifier = Modifier) {
AndroidView(
factory = { context ->
FrameLayout(context).apply {
@@ -161,9 +152,7 @@
}
@Composable
- private fun Weather(
- modifier: Modifier = Modifier,
- ) {
+ private fun Weather(modifier: Modifier = Modifier) {
val isVisible by keyguardSmartspaceViewModel.isWeatherVisible.collectAsStateWithLifecycle()
if (!isVisible) {
return
@@ -188,9 +177,7 @@
}
@Composable
- private fun Date(
- modifier: Modifier = Modifier,
- ) {
+ private fun Date(modifier: Modifier = Modifier) {
val isVisible by keyguardSmartspaceViewModel.isDateVisible.collectAsStateWithLifecycle()
if (!isVisible) {
return
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
index 4f1acdc..6591a75 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreen.kt
@@ -27,6 +27,7 @@
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
@@ -95,7 +96,9 @@
recentTiles: List<PeopleTileViewModel>,
onTileClicked: (PeopleTileViewModel) -> Unit,
) {
- Column(Modifier.sysuiResTag("top_level_with_conversations")) {
+ Column(
+ Modifier.fillMaxSize().safeContentPadding().sysuiResTag("top_level_with_conversations")
+ ) {
Column(
Modifier.fillMaxWidth().padding(PeopleSpacePadding),
horizontalAlignment = Alignment.CenterHorizontally,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
index d483f88..9f582bc 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/people/ui/compose/PeopleScreenEmpty.kt
@@ -27,6 +27,7 @@
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
@@ -47,7 +48,7 @@
@Composable
internal fun PeopleScreenEmpty(onGotItClicked: () -> Unit) {
Column(
- Modifier.fillMaxSize().padding(PeopleSpacePadding),
+ Modifier.fillMaxSize().safeContentPadding().padding(PeopleSpacePadding),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
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 2d32fd7..f7ce215 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
@@ -261,7 +261,7 @@
/** A button with an icon. */
@Composable
-private fun IconButton(model: FooterActionsButtonViewModel, modifier: Modifier = Modifier) {
+fun IconButton(model: FooterActionsButtonViewModel, modifier: Modifier = Modifier) {
Expandable(
color = colorAttr(model.backgroundColor),
shape = CircleShape,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
index 3fce890..b1a1945 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
@@ -26,8 +26,10 @@
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredHeightIn
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
@@ -50,6 +52,8 @@
import com.android.systemui.qs.panels.ui.compose.EditMode
import com.android.systemui.qs.panels.ui.compose.TileDetails
import com.android.systemui.qs.panels.ui.compose.TileGrid
+import com.android.systemui.qs.panels.ui.compose.toolbar.Toolbar
+import com.android.systemui.qs.ui.composable.QuickSettingsShade.Dimensions.GridMaxHeight
import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel
import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeOverlayActionsViewModel
import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeOverlayContentViewModel
@@ -122,7 +126,9 @@
// A sealed interface to represent the possible states of the `ShadeBody`
sealed interface ShadeBodyState {
data object Editing : ShadeBodyState
+
data object TileDetails : ShadeBodyState
+
data object Default : ShadeBodyState
}
@@ -149,9 +155,8 @@
ShadeBodyState.Editing -> {
EditMode(
viewModel = viewModel.editModeViewModel,
- modifier = Modifier
- .fillMaxWidth()
- .padding(QuickSettingsShade.Dimensions.Padding),
+ modifier =
+ Modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding),
)
}
ShadeBodyState.TileDetails -> {
@@ -182,22 +187,23 @@
.padding(
start = QuickSettingsShade.Dimensions.Padding,
end = QuickSettingsShade.Dimensions.Padding,
- top = QuickSettingsShade.Dimensions.Padding,
+ bottom = QuickSettingsShade.Dimensions.Padding / 2,
),
) {
+ Toolbar(viewModel.toolbarViewModelFactory)
BrightnessSliderContainer(
viewModel = viewModel.brightnessSliderViewModel,
modifier =
Modifier.fillMaxWidth().height(QuickSettingsShade.Dimensions.BrightnessSliderHeight),
)
- Box {
+ Box(
+ modifier =
+ Modifier.requiredHeightIn(max = GridMaxHeight)
+ .verticalNestedScrollToScene()
+ .verticalScroll(rememberScrollState())
+ ) {
GridAnchor()
- TileGrid(
- viewModel = viewModel.tileGridViewModel,
- modifier =
- Modifier.fillMaxWidth()
- .heightIn(max = QuickSettingsShade.Dimensions.GridMaxHeight),
- )
+ TileGrid(viewModel = viewModel.tileGridViewModel, modifier = Modifier.fillMaxWidth())
}
}
}
@@ -207,6 +213,6 @@
object Dimensions {
val Padding = 16.dp
val BrightnessSliderHeight = 64.dp
- val GridMaxHeight = 800.dp
+ val GridMaxHeight = 420.dp
}
}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
index f1da01f..4410e15 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
@@ -771,7 +771,7 @@
private fun expectedOffset(currentOffset: Dp, density: Density): Dp {
return with(density) {
- OffsetOverscrollEffect.computeOffset(this, currentOffset.toPx()).toDp()
+ OffsetOverscrollEffect.computeOffset(density, currentOffset.toPx()).toDp()
}
}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/effect/OffsetOverscrollEffectTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/effect/OffsetOverscrollEffectTest.kt
index d267cc5..da8fe30 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/effect/OffsetOverscrollEffectTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/effect/OffsetOverscrollEffectTest.kt
@@ -36,6 +36,7 @@
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
+import kotlin.properties.Delegates
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -44,165 +45,131 @@
class OffsetOverscrollEffectTest {
@get:Rule val rule = createComposeRule()
- private fun expectedOffset(currentOffset: Dp, density: Density): Dp {
- return with(density) {
- OffsetOverscrollEffect.computeOffset(this, currentOffset.toPx()).toDp()
+ private val BOX_TAG = "box"
+
+ private data class LayoutInfo(val layoutSize: Dp, val touchSlop: Float, val density: Density) {
+ fun expectedOffset(currentOffset: Dp): Dp {
+ return with(density) {
+ OffsetOverscrollEffect.computeOffset(this, currentOffset.toPx()).toDp()
+ }
}
}
+ private fun setupOverscrollableBox(
+ scrollableOrientation: Orientation,
+ overscrollEffectOrientation: Orientation = scrollableOrientation,
+ ): LayoutInfo {
+ val layoutSize: Dp = 200.dp
+ var touchSlop: Float by Delegates.notNull()
+ // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
+ // detected as a drag event.
+ lateinit var density: Density
+ rule.setContent {
+ density = LocalDensity.current
+ touchSlop = LocalViewConfiguration.current.touchSlop
+ val overscrollEffect = rememberOffsetOverscrollEffect(overscrollEffectOrientation)
+
+ Box(
+ Modifier.overscroll(overscrollEffect)
+ // A scrollable that does not consume the scroll gesture.
+ .scrollable(
+ state = rememberScrollableState { 0f },
+ orientation = scrollableOrientation,
+ overscrollEffect = overscrollEffect,
+ )
+ .size(layoutSize)
+ .testTag(BOX_TAG)
+ )
+ }
+ return LayoutInfo(layoutSize, touchSlop, density)
+ }
+
@Test
fun applyVerticalOffset_duringVerticalOverscroll() {
- // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
- // detected as a drag event.
- var touchSlop = 0f
- lateinit var density: Density
- val layoutSize = 200.dp
+ val info = setupOverscrollableBox(scrollableOrientation = Orientation.Vertical)
- rule.setContent {
- density = LocalDensity.current
- touchSlop = LocalViewConfiguration.current.touchSlop
- val overscrollEffect = rememberOffsetOverscrollEffect(Orientation.Vertical)
-
- Box(
- Modifier.overscroll(overscrollEffect)
- // A scrollable that does not consume the scroll gesture.
- .scrollable(
- state = rememberScrollableState { 0f },
- orientation = Orientation.Vertical,
- overscrollEffect = overscrollEffect,
- )
- .size(layoutSize)
- .testTag("box")
- )
- }
-
- val onBox = rule.onNodeWithTag("box")
-
- onBox.assertTopPositionInRootIsEqualTo(0.dp)
+ rule.onNodeWithTag(BOX_TAG).assertTopPositionInRootIsEqualTo(0.dp)
rule.onRoot().performTouchInput {
down(center)
- moveBy(Offset(0f, touchSlop + layoutSize.toPx()), delayMillis = 1_000)
+ moveBy(Offset(0f, info.touchSlop + info.layoutSize.toPx()), delayMillis = 1_000)
}
- onBox.assertTopPositionInRootIsEqualTo(expectedOffset(layoutSize, density))
+ rule
+ .onNodeWithTag(BOX_TAG)
+ .assertTopPositionInRootIsEqualTo(info.expectedOffset(info.layoutSize))
}
@Test
fun applyNoOffset_duringHorizontalOverscroll() {
- // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
- // detected as a drag event.
- var touchSlop = 0f
- val layoutSize = 200.dp
-
- rule.setContent {
- touchSlop = LocalViewConfiguration.current.touchSlop
- val overscrollEffect = rememberOffsetOverscrollEffect(Orientation.Vertical)
-
- Box(
- Modifier.overscroll(overscrollEffect)
- // A scrollable that does not consume the scroll gesture.
- .scrollable(
- state = rememberScrollableState { 0f },
- orientation = Orientation.Horizontal,
- overscrollEffect = overscrollEffect,
- )
- .size(layoutSize)
- .testTag("box")
+ val info =
+ setupOverscrollableBox(
+ scrollableOrientation = Orientation.Vertical,
+ overscrollEffectOrientation = Orientation.Horizontal,
)
- }
- val onBox = rule.onNodeWithTag("box")
-
- onBox.assertTopPositionInRootIsEqualTo(0.dp)
+ rule.onNodeWithTag(BOX_TAG).assertTopPositionInRootIsEqualTo(0.dp)
rule.onRoot().performTouchInput {
down(center)
- moveBy(Offset(touchSlop + layoutSize.toPx(), 0f), delayMillis = 1_000)
+ moveBy(Offset(info.touchSlop + info.layoutSize.toPx(), 0f), delayMillis = 1_000)
}
- onBox.assertTopPositionInRootIsEqualTo(0.dp)
+ rule.onNodeWithTag(BOX_TAG).assertTopPositionInRootIsEqualTo(0.dp)
}
@Test
fun backToZero_afterOverscroll() {
- // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
- // detected as a drag event.
- var touchSlop = 0f
- lateinit var density: Density
- val layoutSize = 200.dp
-
- rule.setContent {
- density = LocalDensity.current
- touchSlop = LocalViewConfiguration.current.touchSlop
- val overscrollEffect = rememberOffsetOverscrollEffect(Orientation.Vertical)
-
- Box(
- Modifier.overscroll(overscrollEffect)
- // A scrollable that does not consume the scroll gesture.
- .scrollable(
- state = rememberScrollableState { 0f },
- orientation = Orientation.Vertical,
- overscrollEffect = overscrollEffect,
- )
- .size(layoutSize)
- .testTag("box")
- )
- }
-
- val onBox = rule.onNodeWithTag("box")
+ val info = setupOverscrollableBox(scrollableOrientation = Orientation.Vertical)
rule.onRoot().performTouchInput {
down(center)
- moveBy(Offset(0f, touchSlop + layoutSize.toPx()), delayMillis = 1_000)
+ moveBy(Offset(0f, info.touchSlop + info.layoutSize.toPx()), delayMillis = 1_000)
}
- onBox.assertTopPositionInRootIsEqualTo(expectedOffset(layoutSize, density))
+ rule
+ .onNodeWithTag(BOX_TAG)
+ .assertTopPositionInRootIsEqualTo(info.expectedOffset(info.layoutSize))
rule.onRoot().performTouchInput { up() }
- onBox.assertTopPositionInRootIsEqualTo(0.dp)
+ rule.onNodeWithTag(BOX_TAG).assertTopPositionInRootIsEqualTo(0.dp)
}
@Test
fun offsetOverscroll_followTheTouchPointer() {
- // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
- // detected as a drag event.
- var touchSlop = 0f
- lateinit var density: Density
- val layoutSize = 200.dp
+ val info = setupOverscrollableBox(scrollableOrientation = Orientation.Vertical)
- rule.setContent {
- density = LocalDensity.current
- touchSlop = LocalViewConfiguration.current.touchSlop
- val overscrollEffect = rememberOffsetOverscrollEffect(Orientation.Vertical)
-
- Box(
- Modifier.overscroll(overscrollEffect)
- // A scrollable that does not consume the scroll gesture.
- .scrollable(
- state = rememberScrollableState { 0f },
- orientation = Orientation.Vertical,
- overscrollEffect = overscrollEffect,
- )
- .size(layoutSize)
- .testTag("box")
- )
- }
-
- val onBox = rule.onNodeWithTag("box")
-
+ // First gesture, drag down.
rule.onRoot().performTouchInput {
down(center)
// A full screen scroll.
- moveBy(Offset(0f, touchSlop + layoutSize.toPx()), delayMillis = 1_000)
+ moveBy(Offset(0f, info.touchSlop + info.layoutSize.toPx()), delayMillis = 1_000)
}
- onBox.assertTopPositionInRootIsEqualTo(expectedOffset(layoutSize, density))
+ rule
+ .onNodeWithTag(BOX_TAG)
+ .assertTopPositionInRootIsEqualTo(info.expectedOffset(info.layoutSize))
rule.onRoot().performTouchInput {
// Reduced by half.
- moveBy(Offset(0f, -layoutSize.toPx() / 2), delayMillis = 1_000)
+ moveBy(Offset(0f, -info.layoutSize.toPx() / 2), delayMillis = 1_000)
}
- onBox.assertTopPositionInRootIsEqualTo(expectedOffset(layoutSize / 2, density))
+ rule
+ .onNodeWithTag(BOX_TAG)
+ .assertTopPositionInRootIsEqualTo(info.expectedOffset(info.layoutSize / 2))
+
+ rule.onRoot().performTouchInput { up() }
+ // Animate back to 0.
+ rule.onNodeWithTag(BOX_TAG).assertTopPositionInRootIsEqualTo(0.dp)
+
+ // Second gesture, drag up.
+ rule.onRoot().performTouchInput {
+ down(center)
+ // A full screen scroll.
+ moveBy(Offset(0f, -info.touchSlop - info.layoutSize.toPx()), delayMillis = 1_000)
+ }
+ rule
+ .onNodeWithTag(BOX_TAG)
+ .assertTopPositionInRootIsEqualTo(info.expectedOffset(-info.layoutSize))
}
}
diff --git a/packages/SystemUI/lint-baseline.xml b/packages/SystemUI/lint-baseline.xml
index 00b0c44..09abc37 100644
--- a/packages/SystemUI/lint-baseline.xml
+++ b/packages/SystemUI/lint-baseline.xml
@@ -26857,8 +26857,8 @@
<issue
id="Overdraw"
- message="Possible overdraw: Root element paints background `?androidprv:attr/materialColorOnSurfaceVariant` with a theme that also paints a background (inferred theme is `@style/Theme.SystemUI`)"
- errorLine1=" android:background="?androidprv:attr/materialColorOnSurfaceVariant" />"
+ message="Possible overdraw: Root element paints background `@androidprv:color/materialColorOnSurfaceVariant` with a theme that also paints a background (inferred theme is `@style/Theme.SystemUI`)"
+ errorLine1=" android:background="@androidprv:color/materialColorOnSurfaceVariant" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="frameworks/base/packages/SystemUI/res/layout/notification_children_divider.xml"
@@ -26868,8 +26868,8 @@
<issue
id="Overdraw"
- message="Possible overdraw: Root element paints background `?androidprv:attr/materialColorSurfaceContainerHigh` with a theme that also paints a background (inferred theme is `@style/Theme.SystemUI`)"
- errorLine1=" android:background="?androidprv:attr/materialColorSurfaceContainerHigh""
+ message="Possible overdraw: Root element paints background `@androidprv:color/materialColorSurfaceContainerHigh` with a theme that also paints a background (inferred theme is `@style/Theme.SystemUI`)"
+ errorLine1=" android:background="@androidprv:color/materialColorSurfaceContainerHigh""
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="frameworks/base/packages/SystemUI/res/layout/notification_snooze.xml"
@@ -33644,7 +33644,7 @@
<issue
id="ShadeDisplayAwareContextChecker"
- message="UI elements of the shade window
should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only
@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so
might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).
If the usage of Resources is not related to display specific configuration or UI, then there is
technically no need to use the annotation, and you can annotate the class with
@SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
errorLine1=" @Main resources: Resources,"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -33655,7 +33655,7 @@
<issue
id="ShadeDisplayAwareContextChecker"
- message="UI elements of the shade window
should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only
@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so
might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).
If the usage of Context is not related to display specific configuration or UI, then there is
technically no need to use the annotation, and you can annotate the class with
@SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
errorLine1="constructor(context: Context, val shadeViewController: ShadeViewController) {"
errorLine2=" ~~~~~~~~~~~~~~~~">
<location
@@ -33699,7 +33699,7 @@
<issue
id="ShadeDisplayAwareContextChecker"
- message="UI elements of the shade window
should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only
@ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so
might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme).
If the usage of Resources is not related to display specific configuration or UI, then there is
technically no need to use the annotation, and you can annotate the class with
@SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
errorLine1=" @Main private val resources: Resources,"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -33763,5 +33763,201 @@
column="5"/>
</issue>
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" public AuthController(Context context,"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java"
+ line="716"
+ column="35"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated WindowManager, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of WindowManager is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" @NonNull WindowManager windowManager,"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java"
+ line="721"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" private val sysuiContext: Context,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt"
+ line="72"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated ConfigurationController, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of ConfigurationController is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" private val configurationController: ConfigurationController,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt"
+ line="74"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" Context context,"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationBroadcastReceiver.java"
+ line="46"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" @Main Resources resources,"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationDialogFactory.java"
+ line="52"
+ column="29"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" public BiometricNotificationService(@NonNull Context context,"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/BiometricNotificationService.java"
+ line="148"
+ column="58"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" c: Context,"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt"
+ line="61"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" @Main private val resources: Resources,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/EmergencyServicesRepository.kt"
+ line="39"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" @Main private val resources: Resources,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt"
+ line="37"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" @Main private val resources: Resources,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/FaceHelpMessageDeferral.kt"
+ line="42"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" @NonNull final Context context,"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java"
+ line="186"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1="class IconBuilder @Inject constructor(private val context: Context) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt"
+ line="27"
+ column="39"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated WindowManager, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of WindowManager is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" private val windowManager: WindowManager,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModel.kt"
+ line="40"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" @Main resources: Resources,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt"
+ line="53"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Resources, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Resources is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" @Main private val resources: Resources,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddable.kt"
+ line="51"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated Context, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of Context is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" private val context: Context,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractor.kt"
+ line="51"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="ShadeDisplayAwareContextChecker"
+ message="UI elements of the shade window should use ShadeDisplayAware-annotated WindowManager, as the shade might move between windows, and only @ShadeDisplayAware resources are updated with the new configuration correctly. Failures to do so might result in wrong dimensions for shade window classes (e.g. using the wrong density or theme). If the usage of WindowManager is not related to display specific configuration or UI, then there is technically no need to use the annotation, and you can annotate the class with @SuppressLint("ShadeDisplayAwareContextChecker")/@Suppress("ShadeDisplayAwareContextChecker")"
+ errorLine1=" windowManager: WindowManager,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/SideFpsSensorInteractor.kt"
+ line="53"
+ column="5"/>
</issues>
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
index 84d062a..831012c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
@@ -30,7 +30,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.airbnb.lottie.model.KeyPath
-import com.android.settingslib.Utils
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider
import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
@@ -77,20 +76,14 @@
private val contextDisplayInfo = DisplayInfo()
- private val indicatorColor =
- Utils.getColorAttrDefaultColor(
- context,
- com.android.internal.R.attr.materialColorPrimaryFixed,
+ private val indicatorColor = context.getColor(
+ com.android.internal.R.color.materialColorPrimaryFixed,
)
- private val outerRimColor =
- Utils.getColorAttrDefaultColor(
- context,
- com.android.internal.R.attr.materialColorPrimaryFixedDim,
+ private val outerRimColor = context.getColor(
+ com.android.internal.R.color.materialColorPrimaryFixedDim,
)
- private val chevronFill =
- Utils.getColorAttrDefaultColor(
- context,
- com.android.internal.R.attr.materialColorOnPrimaryFixed,
+ private val chevronFill = context.getColor(
+ com.android.internal.R.color.materialColorOnPrimaryFixed,
)
private val color_blue400 =
context.getColor(com.android.settingslib.color.R.color.settingslib_color_blue400)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModelTest.kt
new file mode 100644
index 0000000..8820685
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModelTest.kt
@@ -0,0 +1,104 @@
+/*
+ * 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.communal.ui.viewmodel
+
+import android.platform.test.annotations.EnableFlags
+import android.service.dream.dreamManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.lifecycle.activateIn
+import com.android.systemui.statusbar.policy.batteryController
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+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.whenever
+
+@SmallTest
+@EnableFlags(FLAG_GLANCEABLE_HUB_V2)
+@RunWith(AndroidJUnit4::class)
+class CommunalToDreamButtonViewModelTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val underTest: CommunalToDreamButtonViewModel by lazy {
+ kosmos.communalToDreamButtonViewModel
+ }
+
+ @Before
+ fun setUp() {
+ kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)
+ underTest.activateIn(testScope)
+ }
+
+ @Test
+ fun shouldShowDreamButtonOnHub_trueWhenCanDream() =
+ with(kosmos) {
+ runTest {
+ whenever(dreamManager.canStartDreaming(any())).thenReturn(true)
+ whenever(batteryController.isPluggedIn()).thenReturn(true)
+
+ val shouldShowButton by collectLastValue(underTest.shouldShowDreamButtonOnHub)
+ assertThat(shouldShowButton).isTrue()
+ }
+ }
+
+ @Test
+ fun shouldShowDreamButtonOnHub_falseWhenCannotDream() =
+ with(kosmos) {
+ runTest {
+ whenever(dreamManager.canStartDreaming(any())).thenReturn(false)
+ whenever(batteryController.isPluggedIn()).thenReturn(true)
+
+ val shouldShowButton by collectLastValue(underTest.shouldShowDreamButtonOnHub)
+ assertThat(shouldShowButton).isFalse()
+ }
+ }
+
+ @Test
+ fun shouldShowDreamButtonOnHub_falseWhenNotPluggedIn() =
+ with(kosmos) {
+ runTest {
+ whenever(dreamManager.canStartDreaming(any())).thenReturn(true)
+ whenever(batteryController.isPluggedIn()).thenReturn(false)
+
+ val shouldShowButton by collectLastValue(underTest.shouldShowDreamButtonOnHub)
+ assertThat(shouldShowButton).isFalse()
+ }
+ }
+
+ @Test
+ fun onShowDreamButtonTap_startsDream() =
+ with(kosmos) {
+ runTest {
+ underTest.onShowDreamButtonTap()
+ runCurrent()
+
+ verify(dreamManager).startDream()
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/util/ResizeUtilsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/util/ResizeUtilsTest.kt
new file mode 100644
index 0000000..b0f4803
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/util/ResizeUtilsTest.kt
@@ -0,0 +1,222 @@
+/*
+ * 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.communal.util
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.domain.model.CommunalContentModel
+import com.android.systemui.communal.shared.model.CommunalContentSize
+import com.android.systemui.communal.util.ResizeUtils.resizeOngoingItems
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ResizeUtilsTest : SysuiTestCase() {
+ private val mockWidget =
+ mock<CommunalContentModel.WidgetContent.Widget> {
+ on { size } doReturn CommunalContentSize.Responsive(1)
+ }
+
+ @Test
+ fun noOngoingContent() {
+ val list = listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 2)
+
+ assertThat(resized).containsExactly(mockWidget)
+ }
+
+ @Test
+ fun singleOngoingContent_singleRowGrid() {
+ val list = createOngoingListWithSize(1) + listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 1)
+
+ assertThat(resized.map { it.size })
+ .containsExactly(CommunalContentSize.Responsive(1), mockWidget.size)
+ .inOrder()
+ }
+
+ @Test
+ fun singleOngoingContent_twoRowGrid() {
+ val list = createOngoingListWithSize(1) + listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 2)
+
+ assertThat(resized.map { it.size })
+ .containsExactly(CommunalContentSize.Responsive(2), mockWidget.size)
+ .inOrder()
+ }
+
+ @Test
+ fun singleOngoingContent_threeRowGrid() {
+ val list = createOngoingListWithSize(1) + listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 3)
+
+ assertThat(resized.map { it.size })
+ .containsExactly(
+ CommunalContentSize.Responsive(2),
+ CommunalContentSize.Responsive(1),
+ mockWidget.size,
+ )
+ .inOrder()
+ // A spacer should be added as the second element to avoid mixing widget content
+ // with ongoing content.
+ assertThat(resized[1]).isInstanceOf(CommunalContentModel.Spacer::class.java)
+ }
+
+ @Test
+ fun twoOngoingContent_singleRowGrid() {
+ val list = createOngoingListWithSize(2) + listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 1)
+
+ assertThat(resized.map { it.size })
+ .containsExactly(
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ mockWidget.size,
+ )
+ .inOrder()
+ }
+
+ @Test
+ fun twoOngoingContent_twoRowGrid() {
+ val list = createOngoingListWithSize(2) + listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 2)
+
+ assertThat(resized.map { it.size })
+ .containsExactly(
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ mockWidget.size,
+ )
+ .inOrder()
+ }
+
+ @Test
+ fun twoOngoingContent_threeRowGrid() {
+ val list = createOngoingListWithSize(2) + listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 3)
+
+ assertThat(resized.map { it.size })
+ .containsExactly(
+ CommunalContentSize.Responsive(2),
+ CommunalContentSize.Responsive(1),
+ mockWidget.size,
+ )
+ .inOrder()
+ }
+
+ @Test
+ fun threeOngoingContent_singleRowGrid() {
+ val list = createOngoingListWithSize(3) + listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 1)
+
+ assertThat(resized.map { it.size })
+ .containsExactly(
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ mockWidget.size,
+ )
+ .inOrder()
+ }
+
+ @Test
+ fun threeOngoingContent_twoRowGrid() {
+ val list = createOngoingListWithSize(3) + listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 2)
+
+ assertThat(resized.map { it.size })
+ .containsExactly(
+ CommunalContentSize.Responsive(2),
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ mockWidget.size,
+ )
+ .inOrder()
+ }
+
+ @Test
+ fun threeOngoingContent_threeRowGrid() {
+ val list = createOngoingListWithSize(3) + listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 3)
+
+ assertThat(resized.map { it.size })
+ .containsExactly(
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ mockWidget.size,
+ )
+ .inOrder()
+ }
+
+ @Test
+ fun fourOngoingContent_singleRowGrid() {
+ val list = createOngoingListWithSize(4) + listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 1)
+
+ assertThat(resized.map { it.size })
+ .containsExactly(
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ mockWidget.size,
+ )
+ .inOrder()
+ }
+
+ @Test
+ fun fourOngoingContent_twoRowGrid() {
+ val list = createOngoingListWithSize(4) + listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 2)
+
+ assertThat(resized.map { it.size })
+ .containsExactly(
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(1),
+ mockWidget.size,
+ )
+ .inOrder()
+ }
+
+ @Test
+ fun fourOngoingContent_threeRowGrid() {
+ val list = createOngoingListWithSize(4) + listOf(mockWidget)
+ val resized = resizeOngoingItems(list = list, numRows = 3)
+
+ assertThat(resized.map { it.size })
+ .containsExactly(
+ CommunalContentSize.Responsive(2),
+ CommunalContentSize.Responsive(1),
+ CommunalContentSize.Responsive(2),
+ CommunalContentSize.Responsive(1),
+ mockWidget.size,
+ )
+ .inOrder()
+ }
+
+ private fun createOngoingListWithSize(size: Int): List<CommunalContentModel.Ongoing> {
+ return List(size) { CommunalContentModel.Umo(createdTimestampMillis = 100) }
+ }
+}
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 18cc8bf..5bbd3ff 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
@@ -172,16 +172,16 @@
}
@Test
- fun selectedKey_onReorderWidgets_isSet() =
+ fun selectedKey_onReorderWidgets_isCleared() =
testScope.runTest {
val selectedKey by collectLastValue(underTest.selectedKey)
- underTest.setSelectedKey(null)
- assertThat(selectedKey).isNull()
-
val key = CommunalContentModel.KEY.widget(123)
- underTest.onReorderWidgetStart(key)
+ underTest.setSelectedKey(key)
assertThat(selectedKey).isEqualTo(key)
+
+ underTest.onReorderWidgetStart()
+ assertThat(selectedKey).isNull()
}
@Test
@@ -234,7 +234,7 @@
@Test
fun reorderWidget_uiEventLogging_start() {
- underTest.onReorderWidgetStart(CommunalContentModel.KEY.widget(123))
+ underTest.onReorderWidgetStart()
verify(uiEventLogger).log(CommunalUiEvent.COMMUNAL_HUB_REORDER_WIDGET_START)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayRegistrantTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayRegistrantTest.kt
index 790df03..1e937b4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayRegistrantTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayRegistrantTest.kt
@@ -29,8 +29,11 @@
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
+import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled
import com.android.systemui.log.core.FakeLogBuffer
import com.android.systemui.shared.condition.Monitor
+import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.withArgCaptor
import kotlin.test.Test
import org.junit.Before
@@ -48,6 +51,8 @@
@TestableLooper.RunWithLooper
@RunWith(AndroidJUnit4::class)
class DreamOverlayRegistrantTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+
private val context = mock<Context>()
private val packageManager = mock<PackageManager>()
@@ -73,6 +78,7 @@
monitor,
packageManager,
dreamManager,
+ kosmos.communalSettingsInteractor,
logBuffer,
)
@@ -117,7 +123,7 @@
/** Verify overlay registered when enabled in manifest. */
@Test
- @DisableFlags(Flags.FLAG_COMMUNAL_HUB_ON_MOBILE)
+ @DisableFlags(Flags.FLAG_GLANCEABLE_HUB_V2)
fun testRegisteredWhenEnabledWithManifest() {
serviceInfo.enabled = true
start()
@@ -127,8 +133,10 @@
/** Verify overlay registered for mobile hub with flag. */
@Test
- @EnableFlags(Flags.FLAG_COMMUNAL_HUB_ON_MOBILE)
+ @EnableFlags(Flags.FLAG_GLANCEABLE_HUB_V2)
fun testRegisteredForMobileHub() {
+ kosmos.setCommunalV2ConfigEnabled(true)
+
start()
verify(dreamManager).registerDreamOverlayService(componentName)
@@ -139,7 +147,7 @@
* enabled.
*/
@Test
- @DisableFlags(Flags.FLAG_COMMUNAL_HUB_ON_MOBILE)
+ @DisableFlags(Flags.FLAG_GLANCEABLE_HUB_V2)
fun testDisabledForMobileWithoutMobileHub() {
start()
@@ -154,8 +162,9 @@
/** Ensure service unregistered when component is disabled at runtime. */
@Test
- @EnableFlags(Flags.FLAG_COMMUNAL_HUB_ON_MOBILE)
+ @EnableFlags(Flags.FLAG_GLANCEABLE_HUB_V2)
fun testUnregisteredWhenComponentDisabled() {
+ kosmos.setCommunalV2ConfigEnabled(true)
start()
verify(dreamManager).registerDreamOverlayService(componentName)
clearInvocations(dreamManager)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
index f924ccb..b07097d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -43,7 +43,7 @@
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
-import com.android.systemui.Flags.FLAG_COMMUNAL_HUB_ON_MOBILE
+import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2
import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
import com.android.systemui.SysuiTestCase
import com.android.systemui.ambient.touch.TouchHandler
@@ -55,7 +55,9 @@
import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
+import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled
import com.android.systemui.communal.shared.log.CommunalUiEvent
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.complication.ComplicationHostViewController
@@ -262,6 +264,7 @@
mKeyguardUpdateMonitor,
mScrimManager,
mCommunalInteractor,
+ kosmos.communalSettingsInteractor,
kosmos.sceneInteractor,
mSystemDialogsCloser,
mUiEventLogger,
@@ -1283,7 +1286,7 @@
environmentComponents.verifyNoMoreInteractions()
}
- @DisableFlags(FLAG_COMMUNAL_HUB_ON_MOBILE)
+ @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
@Test
fun testAmbientTouchHandlersRegistration_registerHideComplicationAndCommunal() {
val client = client
@@ -1303,9 +1306,11 @@
.containsExactly(mHideComplicationTouchHandler, mCommunalTouchHandler)
}
- @EnableFlags(FLAG_COMMUNAL_HUB_ON_MOBILE)
+ @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
@Test
fun testAmbientTouchHandlersRegistration_v2_registerOnlyHideComplication() {
+ kosmos.setCommunalV2ConfigEnabled(true)
+
val client = client
// Inform the overlay service of dream starting.
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
index 76434ee..1de38ee 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
@@ -16,10 +16,8 @@
package com.android.systemui.inputdevice.tutorial.ui.viewmodel
-import androidx.lifecycle.Lifecycle.Event
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
import androidx.lifecycle.SavedStateHandle
+import androidx.lifecycle.testing.TestLifecycleOwner
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -55,7 +53,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.mock
import org.mockito.kotlin.mock
@OptIn(ExperimentalCoroutinesApi::class)
@@ -71,9 +68,6 @@
private var tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD
private val viewModel by lazy { createViewModel(tutorialScope) }
- // createUnsafe so its methods don't have to be called on Main thread
- private val lifecycle = LifecycleRegistry.createUnsafe(mock(LifecycleOwner::class.java))
-
@get:Rule val mainDispatcherRule = MainDispatcherRule(kosmos.testDispatcher)
private fun createViewModel(
@@ -88,7 +82,6 @@
mock<InputDeviceTutorialLogger>(),
SavedStateHandle(mapOf(INTENT_TUTORIAL_SCOPE_KEY to scope)),
)
- lifecycle.addObserver(viewModel)
return viewModel
}
@@ -279,7 +272,7 @@
collectValues(viewModel.screen) // just to initialize viewModel
peripheralsState(touchpadConnected = true)
- lifecycle.handleLifecycleEvent(Event.ON_START)
+ viewModel.onStart(TestLifecycleOwner())
assertGesturesDisabled()
}
@@ -291,8 +284,8 @@
collectValues(viewModel.screen)
peripheralsState(touchpadConnected = true)
- lifecycle.handleLifecycleEvent(Event.ON_START)
- lifecycle.handleLifecycleEvent(Event.ON_STOP)
+ viewModel.onStart(TestLifecycleOwner())
+ viewModel.onStop(TestLifecycleOwner())
assertGesturesNotDisabled()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureDataAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureDataAdapterTest.kt
new file mode 100644
index 0000000..f78c692
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureDataAdapterTest.kt
@@ -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.systemui.keyboard.shortcut.data.repository
+
+import android.app.role.RoleManager
+import android.app.role.roleManager
+import android.content.Context
+import android.content.Intent
+import android.content.mockedContext
+import android.content.packageManager
+import android.content.pm.ActivityInfo
+import android.content.pm.PackageManager
+import android.hardware.input.AppLaunchData
+import android.hardware.input.AppLaunchData.RoleData
+import android.hardware.input.InputGestureData
+import android.hardware.input.InputGestureData.createKeyTrigger
+import android.view.KeyEvent.KEYCODE_A
+import android.view.KeyEvent.META_ALT_ON
+import android.view.KeyEvent.META_CTRL_ON
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.app.ResolverActivity
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.keyboard.shortcut.data.model.InternalGroupsSource
+import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup
+import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutInfo
+import com.android.systemui.keyboard.shortcut.inputGestureDataAdapter
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.res.R
+import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.settings.userTracker
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class InputGestureDataAdapterTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos().also { kosmos ->
+ kosmos.userTracker = FakeUserTracker(onCreateCurrentUserContext = { kosmos.mockedContext })
+ }
+ private val adapter = kosmos.inputGestureDataAdapter
+ private val roleManager = kosmos.roleManager
+ private val packageManager: PackageManager = kosmos.packageManager
+ private val mockUserContext: Context = kosmos.mockedContext
+ private val intent: Intent = mock()
+ private val fakeResolverActivityInfo =
+ ActivityInfo().apply { name = ResolverActivity::class.qualifiedName }
+ private val fakeActivityInfo: ActivityInfo =
+ ActivityInfo().apply {
+ name = FAKE_ACTIVITY_NAME
+ icon = 0x1
+ nonLocalizedLabel = TEST_SHORTCUT_LABEL
+ }
+ private val mockSelectorIntent: Intent = mock()
+
+ @Before
+ fun setup() {
+ whenever(mockUserContext.packageManager).thenReturn(packageManager)
+ whenever(mockUserContext.getSystemService(RoleManager::class.java)).thenReturn(roleManager)
+ whenever(roleManager.isRoleAvailable(TEST_ROLE)).thenReturn(true)
+ whenever(roleManager.getDefaultApplication(TEST_ROLE)).thenReturn(TEST_ROLE_PACKAGE)
+ whenever(packageManager.getActivityInfo(any(), anyInt())).thenReturn(mock())
+ whenever(packageManager.getLaunchIntentForPackage(TEST_ROLE_PACKAGE)).thenReturn(intent)
+ whenever(intent.selector).thenReturn(mockSelectorIntent)
+ whenever(mockSelectorIntent.categories).thenReturn(setOf(TEST_ACTIVITY_CATEGORY))
+ }
+
+ @Test
+ fun shortcutLabel_whenDefaultAppForCategoryIsNotSet_loadsLabelFromFirstAppMatchingIntent() =
+ kosmos.runTest {
+ setApiToRetrieveResolverActivity()
+
+ val inputGestureData = buildInputGestureDataForAppLaunchShortcut()
+ val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData))
+ val label =
+ internalGroups.firstOrNull()?.groups?.firstOrNull()?.items?.firstOrNull()?.label
+
+ assertThat(label).isEqualTo(expectedShortcutLabelForFirstAppMatchingIntent)
+ }
+
+ @Test
+ fun shortcutLabel_whenDefaultAppForCategoryIsSet_loadsLabelOfDefaultApp() {
+ kosmos.runTest {
+ setApiToRetrieveSpecificActivity()
+
+ val inputGestureData = buildInputGestureDataForAppLaunchShortcut()
+ val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData))
+ val label =
+ internalGroups.firstOrNull()?.groups?.firstOrNull()?.items?.firstOrNull()?.label
+
+ assertThat(label).isEqualTo(TEST_SHORTCUT_LABEL)
+ }
+ }
+
+ @Test
+ fun shortcutIcon_whenDefaultAppForCategoryIsSet_loadsIconOfDefaultApp() {
+ kosmos.runTest {
+ setApiToRetrieveSpecificActivity()
+
+ val inputGestureData = buildInputGestureDataForAppLaunchShortcut()
+ val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData))
+ val icon =
+ internalGroups.firstOrNull()?.groups?.firstOrNull()?.items?.firstOrNull()?.icon
+
+ assertThat(icon).isNotNull()
+ }
+ }
+
+ @Test
+ fun internalGroupSource_isCorrectlyConvertedWithSimpleInputGestureData() =
+ kosmos.runTest {
+ setApiToRetrieveResolverActivity()
+
+ val inputGestureData = buildInputGestureDataForAppLaunchShortcut()
+ val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData))
+
+ assertThat(internalGroups).containsExactly(
+ InternalGroupsSource(
+ type = ShortcutCategoryType.AppCategories,
+ groups = listOf(
+ InternalKeyboardShortcutGroup(
+ label = APPLICATION_SHORTCUT_GROUP_LABEL,
+ items = listOf(
+ InternalKeyboardShortcutInfo(
+ label = expectedShortcutLabelForFirstAppMatchingIntent,
+ keycode = KEYCODE_A,
+ modifiers = META_CTRL_ON or META_ALT_ON,
+ isCustomShortcut = true
+ )
+ )
+ )
+ )
+ )
+ )
+ }
+
+ private fun setApiToRetrieveResolverActivity() {
+ whenever(intent.resolveActivityInfo(eq(packageManager), anyInt()))
+ .thenReturn(fakeResolverActivityInfo)
+ }
+
+ private fun setApiToRetrieveSpecificActivity() {
+ whenever(intent.resolveActivityInfo(eq(packageManager), anyInt()))
+ .thenReturn(fakeActivityInfo)
+ }
+
+
+ private fun buildInputGestureDataForAppLaunchShortcut(
+ keyCode: Int = KEYCODE_A,
+ modifiers: Int = META_CTRL_ON or META_ALT_ON,
+ appLaunchData: AppLaunchData = RoleData(TEST_ROLE)
+ ): InputGestureData {
+ return InputGestureData.Builder()
+ .setTrigger(createKeyTrigger(keyCode, modifiers))
+ .setAppLaunchData(appLaunchData)
+ .build()
+ }
+
+ private val expectedShortcutLabelForFirstAppMatchingIntent =
+ context.getString(R.string.keyboard_shortcut_group_applications_browser)
+
+ private companion object {
+ private const val TEST_ROLE = "Test Browser Role"
+ private const val TEST_ROLE_PACKAGE = "test.browser.package"
+ private const val APPLICATION_SHORTCUT_GROUP_LABEL = "Applications"
+ private const val FAKE_ACTIVITY_NAME = "Fake activity"
+ private const val TEST_SHORTCUT_LABEL = "Test shortcut label"
+ private const val TEST_ACTIVITY_CATEGORY = Intent.CATEGORY_APP_BROWSER
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
index 75190e9..7dc7016 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
@@ -40,7 +40,6 @@
import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
-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.keyboard.shortcut.shared.model.ShortcutCommand
@@ -543,37 +542,20 @@
simpleShortcutCategory(
MultiTasking,
"Split screen",
- "Switch from split screen to full screen",
+ "Switch to full screen",
),
simpleShortcutCategory(
MultiTasking,
"Split screen",
- "Use split screen with current app on the left",
+ "Use split screen with app on the left",
),
simpleShortcutCategory(
MultiTasking,
"Split screen",
- "Switch to app on left or above while using split screen",
- ),
- simpleShortcutCategory(
- MultiTasking,
- "Split screen",
- "Use split screen with current app on the right",
- ),
- simpleShortcutCategory(
- MultiTasking,
- "Split screen",
- "Switch to app on right or below while using split screen",
+ "Use split screen with app on the right",
),
simpleShortcutCategory(System, "System controls", "Show shortcuts"),
simpleShortcutCategory(System, "System controls", "View recent apps"),
- simpleShortcutCategory(AppCategories, "Applications", "Calculator"),
- simpleShortcutCategory(AppCategories, "Applications", "Calendar"),
- simpleShortcutCategory(AppCategories, "Applications", "Browser"),
- simpleShortcutCategory(AppCategories, "Applications", "Contacts"),
- simpleShortcutCategory(AppCategories, "Applications", "Email"),
- simpleShortcutCategory(AppCategories, "Applications", "Maps"),
- simpleShortcutCategory(AppCategories, "Applications", "SMS"),
)
val customInputGestureTypeHome = simpleInputGestureData(keyGestureType = KEY_GESTURE_TYPE_HOME)
@@ -602,40 +584,13 @@
keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_LEFT
),
simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT
- ),
- simpleInputGestureData(
keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION_RIGHT
),
simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT
- ),
- simpleInputGestureData(
keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER
),
simpleInputGestureData(keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS),
simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS
- ),
- simpleInputGestureData(
- keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING
- ),
- simpleInputGestureData(
keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER
),
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfigTest.kt
index 77c615c..789b10b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfigTest.kt
@@ -25,7 +25,8 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.communalSceneRepository
import com.android.systemui.communal.domain.interactor.communalInteractor
-import com.android.systemui.communal.domain.interactor.setCommunalEnabled
+import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
+import com.android.systemui.communal.domain.interactor.setCommunalV2Enabled
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.andSceneContainer
@@ -38,7 +39,6 @@
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
-import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -48,7 +48,7 @@
@SmallTest
@OptIn(ExperimentalCoroutinesApi::class)
-@EnableFlags(Flags.FLAG_GLANCEABLE_HUB_SHORTCUT_BUTTON)
+@EnableFlags(Flags.FLAG_GLANCEABLE_HUB_SHORTCUT_BUTTON, Flags.FLAG_GLANCEABLE_HUB_V2)
@RunWith(ParameterizedAndroidJunit4::class)
class GlanceableHubQuickAffordanceConfigTest(flags: FlagsParameterization?) : SysuiTestCase() {
private val kosmos = testKosmos()
@@ -69,6 +69,7 @@
context = context,
communalInteractor = kosmos.communalInteractor,
communalSceneRepository = kosmos.communalSceneRepository,
+ communalSettingsInteractor = kosmos.communalSettingsInteractor,
sceneInteractor = kosmos.sceneInteractor,
)
}
@@ -76,28 +77,30 @@
@Test
fun lockscreenState_whenGlanceableHubEnabled_returnsVisible() =
testScope.runTest {
- kosmos.setCommunalEnabled(true)
+ kosmos.setCommunalV2Enabled(true)
runCurrent()
val lockScreenState by collectLastValue(underTest.lockScreenState)
- assertTrue(lockScreenState is KeyguardQuickAffordanceConfig.LockScreenState.Visible)
+ assertThat(lockScreenState)
+ .isInstanceOf(KeyguardQuickAffordanceConfig.LockScreenState.Visible::class.java)
}
@Test
fun lockscreenState_whenGlanceableHubDisabled_returnsHidden() =
testScope.runTest {
- kosmos.setCommunalEnabled(false)
+ kosmos.setCommunalV2Enabled(false)
val lockScreenState by collectLastValue(underTest.lockScreenState)
runCurrent()
- assertTrue(lockScreenState is KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
+ assertThat(lockScreenState)
+ .isEqualTo(KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
}
@Test
fun pickerScreenState_whenGlanceableHubEnabled_returnsDefault() =
testScope.runTest {
- kosmos.setCommunalEnabled(true)
+ kosmos.setCommunalV2Enabled(true)
runCurrent()
assertThat(underTest.getPickerScreenState())
@@ -107,7 +110,7 @@
@Test
fun pickerScreenState_whenGlanceableHubDisabled_returnsDisabled() =
testScope.runTest {
- kosmos.setCommunalEnabled(false)
+ kosmos.setCommunalV2Enabled(false)
runCurrent()
assertThat(
@@ -143,7 +146,8 @@
@Parameters(name = "{0}")
fun getParams(): List<FlagsParameterization> {
return FlagsParameterization.allCombinationsOf(
- Flags.FLAG_GLANCEABLE_HUB_SHORTCUT_BUTTON
+ Flags.FLAG_GLANCEABLE_HUB_SHORTCUT_BUTTON,
+ Flags.FLAG_GLANCEABLE_HUB_V2,
)
.andSceneContainer()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt
index 5e9badc..4dbe7c8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModelTest.kt
@@ -28,6 +28,7 @@
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -171,8 +172,10 @@
// WHEN transition is cancelled
repository.sendTransitionStep(step(.1f, TransitionState.CANCELED))
- // THEN alpha is immediately set to 1f (expected lockscreen alpha state)
- assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(1f)
+ // THEN alpha updates according to whether the scene framework is enabled (CANCELED is
+ // ignored when the scene framework is enabled).
+ assertThat(deviceEntryBackgroundViewAlpha)
+ .isEqualTo(if (SceneContainerFlag.isEnabled) 0f else 1f)
}
@Test
@@ -195,14 +198,14 @@
private fun step(
value: Float,
- state: TransitionState = TransitionState.RUNNING
+ state: TransitionState = TransitionState.RUNNING,
): TransitionStep {
return TransitionStep(
from = KeyguardState.AOD,
to = KeyguardState.LOCKSCREEN,
value = value,
transitionState = state,
- ownerName = "AodToLockscreenTransitionViewModelTest"
+ ownerName = "AodToLockscreenTransitionViewModelTest",
)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
index d0da2e9..576795d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
@@ -38,6 +38,7 @@
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.ShadeTestUtil
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.testKosmos
@@ -178,11 +179,13 @@
),
testScope = testScope,
)
- assertThat(values.size).isEqualTo(3)
+ assertThat(values.size).isEqualTo(if (SceneContainerFlag.isEnabled) 2 else 3)
values.forEach { assertThat(it).isIn(Range.closed(0f, 100f)) }
- // Cancel will reset the translation
- assertThat(values[2]).isEqualTo(0)
+ // When the scene framework is not enabled, cancel will reset the translation
+ if (!SceneContainerFlag.isEnabled) {
+ assertThat(values.last()).isEqualTo(0f)
+ }
}
@Test
@@ -242,8 +245,9 @@
// WHEN transition is canceled
repository.sendTransitionStep(step(1f, TransitionState.CANCELED))
- // THEN alpha is immediately set to 0f
- assertThat(actual).isEqualTo(0f)
+ // THEN alpha updates according to whether the scene framework is enabled (CANCELED is
+ // ignored when the scene framework is enabled).
+ assertThat(actual).isEqualTo(if (SceneContainerFlag.isEnabled) 1f else 0f)
}
private fun step(
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 111b3b6..4457d9b 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
@@ -38,6 +38,7 @@
import com.android.systemui.qs.panels.domain.interactor.tileSquishinessInteractor
import com.android.systemui.qs.panels.ui.viewmodel.setConfigurationForMediaInRow
import com.android.systemui.res.R
+import com.android.systemui.shade.data.repository.fakeShadeRepository
import com.android.systemui.shade.largeScreenHeaderHelper
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
@@ -436,6 +437,28 @@
}
}
+ @Test
+ fun qsVisibleAndAnyShadeVisible() =
+ with(kosmos) {
+ testScope.testWithinLifecycle {
+ underTest.isQsVisible = false
+ fakeShadeRepository.setLegacyExpandedOrAwaitingInputTransfer(false)
+ assertThat(underTest.isQsVisibleAndAnyShadeExpanded).isFalse()
+
+ underTest.isQsVisible = true
+ fakeShadeRepository.setLegacyExpandedOrAwaitingInputTransfer(false)
+ assertThat(underTest.isQsVisibleAndAnyShadeExpanded).isFalse()
+
+ underTest.isQsVisible = false
+ fakeShadeRepository.setLegacyExpandedOrAwaitingInputTransfer(true)
+ assertThat(underTest.isQsVisibleAndAnyShadeExpanded).isFalse()
+
+ underTest.isQsVisible = true
+ fakeShadeRepository.setLegacyExpandedOrAwaitingInputTransfer(true)
+ assertThat(underTest.isQsVisibleAndAnyShadeExpanded).isTrue()
+ }
+ }
+
private fun TestScope.setMediaState(state: MediaState) {
with(kosmos) {
val activeMedia = state == ACTIVE_MEDIA
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepositoryTest.kt
new file mode 100644
index 0000000..eef195b
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepositoryTest.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.panels.data.repository
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType
+import com.android.systemui.qs.panels.shared.model.PaginatedGridLayoutType
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class GridLayoutTypeRepositoryTest : SysuiTestCase() {
+ val kosmos = testKosmos()
+
+ val underTest = kosmos.gridLayoutTypeRepository
+
+ @Test
+ fun defaultType_paginated() =
+ kosmos.runTest {
+ val type by collectLastValue(underTest.defaultLayoutType)
+
+ assertThat(type).isEqualTo(PaginatedGridLayoutType)
+ }
+
+ @Test
+ fun dualShadeType_infinite() =
+ kosmos.runTest {
+ val type by collectLastValue(underTest.dualShadeLayoutType)
+
+ assertThat(type).isEqualTo(InfiniteGridLayoutType)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractorTest.kt
new file mode 100644
index 0000000..b591538
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractorTest.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.panels.domain.interactor
+
+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.systemui.SysuiTestCase
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType
+import com.android.systemui.qs.panels.shared.model.PaginatedGridLayoutType
+import com.android.systemui.shade.data.repository.fakeShadeRepository
+import com.android.systemui.shade.shared.flag.DualShade
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class GridLayoutTypeInteractorTest : SysuiTestCase() {
+ val kosmos = testKosmos()
+
+ val Kosmos.underTest by Kosmos.Fixture { kosmos.gridLayoutTypeInteractor }
+
+ @DisableFlags(DualShade.FLAG_NAME)
+ @Test
+ fun noDualShade_gridAlwaysPaginated() =
+ kosmos.runTest {
+ val type by collectLastValue(underTest.layout)
+
+ fakeShadeRepository.setShadeLayoutWide(false)
+ assertThat(type).isEqualTo(PaginatedGridLayoutType)
+
+ fakeShadeRepository.setShadeLayoutWide(true)
+ assertThat(type).isEqualTo(PaginatedGridLayoutType)
+ }
+
+ @EnableFlags(DualShade.FLAG_NAME)
+ @Test
+ fun dualShade_gridAlwaysInfinite() =
+ kosmos.runTest {
+ val type by collectLastValue(underTest.layout)
+
+ fakeShadeRepository.setShadeLayoutWide(false)
+ assertThat(type).isEqualTo(InfiniteGridLayoutType)
+
+ fakeShadeRepository.setShadeLayoutWide(true)
+ assertThat(type).isEqualTo(InfiniteGridLayoutType)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayoutTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayoutTest.kt
index a9a527f..4891c9f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayoutTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayoutTest.kt
@@ -22,7 +22,7 @@
import com.android.systemui.kosmos.testScope
import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepository
import com.android.systemui.qs.panels.data.repository.defaultLargeTilesRepository
-import com.android.systemui.qs.panels.domain.interactor.infiniteGridLayout
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.infiniteGridLayout
import com.android.systemui.qs.panels.ui.viewmodel.MockTileViewModel
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.testKosmos
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
index 583db72..bbfa7e7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
@@ -21,6 +21,7 @@
import android.graphics.drawable.TestStubDrawable
import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
+import com.android.internal.logging.uiEventLoggerFake
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.ContentDescription
@@ -29,9 +30,12 @@
import com.android.systemui.common.ui.compose.toAnnotatedString
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.qs.FakeQSFactory
import com.android.systemui.qs.FakeQSTile
+import com.android.systemui.qs.QSEditEvent
import com.android.systemui.qs.panels.data.repository.stockTilesRepository
import com.android.systemui.qs.panels.domain.interactor.FakeTileAvailabilityInteractor
import com.android.systemui.qs.panels.domain.interactor.tileAvailabilityInteractorsMap
@@ -42,8 +46,10 @@
import com.android.systemui.qs.pipeline.data.repository.fakeMinimumTilesRepository
import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.pipeline.shared.metricSpec
import com.android.systemui.qs.qsTileFactory
import com.android.systemui.qs.shared.model.TileCategory
+import com.android.systemui.qs.tiles.impl.airplane.qsAirplaneModeTileConfig
import com.android.systemui.qs.tiles.impl.alarm.qsAlarmTileConfig
import com.android.systemui.qs.tiles.impl.battery.qsBatterySaverTileConfig
import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig
@@ -86,6 +92,7 @@
qsFlashlightTileConfig,
qsBatterySaverTileConfig,
qsAlarmTileConfig,
+ qsAirplaneModeTileConfig,
qsCameraSensorPrivacyToggleTileConfig,
qsMicrophoneSensorPrivacyToggleTileConfig,
)
@@ -116,7 +123,7 @@
fakeInstalledTilesRepository.setInstalledServicesForUser(
userTracker.userId,
- listOf(serviceInfo1, serviceInfo2)
+ listOf(serviceInfo1, serviceInfo2),
)
with(fakeQSTileConfigProvider) { configs.forEach { putConfig(it.tileSpec, it) } }
@@ -424,10 +431,7 @@
testScope.runTest {
val tiles by collectLastValue(underTest.tiles)
val currentTiles =
- mutableListOf(
- TileSpec.create("flashlight"),
- TileSpec.create("airplane"),
- )
+ mutableListOf(TileSpec.create("flashlight"), TileSpec.create("airplane"))
currentTilesInteractor.setTiles(currentTiles)
assertThat(currentTiles.size).isLessThan(minNumberOfTiles)
@@ -549,6 +553,156 @@
}
}
+ // UI EVENT TESTS
+
+ @Test
+ fun startEditing_onlyOneEvent() =
+ kosmos.runTest {
+ underTest.startEditing()
+ underTest.startEditing()
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+
+ assertThat(uiEventLoggerFake[0].eventId).isEqualTo(QSEditEvent.QS_EDIT_OPEN.id)
+ }
+
+ @Test
+ fun stopEditing_notEditing_noEvent() =
+ kosmos.runTest {
+ underTest.stopEditing()
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(0)
+ }
+
+ @Test
+ fun stopEditing_whenEditing_correctEvent() =
+ kosmos.runTest {
+ underTest.startEditing()
+ underTest.stopEditing()
+
+ assertThat(uiEventLoggerFake[1].eventId).isEqualTo(QSEditEvent.QS_EDIT_CLOSED.id)
+ }
+
+ @Test
+ fun addTile_correctPackageAndPosition() =
+ kosmos.runTest {
+ val flashlightTile = TileSpec.create("flashlight")
+ val airplaneTile = TileSpec.create("airplane")
+ val internetTile = TileSpec.create("internet")
+ val customTile = TileSpec.create(component2)
+ currentTilesInteractor.setTiles(listOf(flashlightTile))
+ runCurrent()
+
+ underTest.addTile(airplaneTile)
+ underTest.addTile(internetTile, position = 0)
+ underTest.addTile(customTile, position = 1)
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(3)
+
+ with(uiEventLoggerFake[0]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_ADD.id)
+ assertThat(packageName).isEqualTo(airplaneTile.metricSpec)
+ assertThat(position).isEqualTo(-1)
+ }
+ with(uiEventLoggerFake[1]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_ADD.id)
+ assertThat(packageName).isEqualTo(internetTile.metricSpec)
+ assertThat(position).isEqualTo(0)
+ }
+ with(uiEventLoggerFake[2]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_ADD.id)
+ assertThat(packageName).isEqualTo(customTile.metricSpec)
+ assertThat(position).isEqualTo(1)
+ }
+ }
+
+ @Test
+ fun addTile_alreadyThere_usesMoveEvent() =
+ kosmos.runTest {
+ val flashlightTile = TileSpec.create("flashlight")
+ val airplaneTile = TileSpec.create("airplane")
+ val internetTile = TileSpec.create("internet")
+ currentTilesInteractor.setTiles(listOf(flashlightTile, airplaneTile, internetTile))
+ runCurrent()
+
+ underTest.addTile(flashlightTile) // adding at the end, should use correct position
+ underTest.addTile(internetTile, 0)
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
+
+ with(uiEventLoggerFake[0]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_MOVE.id)
+ assertThat(packageName).isEqualTo(flashlightTile.metricSpec)
+ // adding at the end, should use correct position
+ assertThat(position).isEqualTo(2)
+ }
+ with(uiEventLoggerFake[1]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_MOVE.id)
+ assertThat(packageName).isEqualTo(internetTile.metricSpec)
+ assertThat(position).isEqualTo(0)
+ }
+ }
+
+ @Test
+ fun removeTileEvent() =
+ kosmos.runTest {
+ val flashlightTile = TileSpec.create("flashlight")
+ val airplaneTile = TileSpec.create("airplane")
+ val internetTile = TileSpec.create("internet")
+ currentTilesInteractor.setTiles(listOf(flashlightTile, airplaneTile, internetTile))
+ runCurrent()
+
+ underTest.removeTile(airplaneTile)
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+
+ with(uiEventLoggerFake[0]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_REMOVE.id)
+ assertThat(packageName).isEqualTo(airplaneTile.metricSpec)
+ }
+ }
+
+ @Test
+ fun setTiles_emitsCorrectOperation_individualOperations() =
+ kosmos.runTest {
+ val flashlightTile = TileSpec.create("flashlight")
+ val airplaneTile = TileSpec.create("airplane")
+ val internetTile = TileSpec.create("internet")
+ val alarmTile = TileSpec.create("alarm")
+
+ currentTilesInteractor.setTiles(listOf(flashlightTile, airplaneTile, internetTile))
+ runCurrent()
+
+ // 0. Move flashlightTile to position 2
+ underTest.setTiles(listOf(airplaneTile, internetTile, flashlightTile))
+ runCurrent()
+
+ // 1. Add alarm tile at position 1
+ underTest.setTiles(listOf(airplaneTile, alarmTile, internetTile, flashlightTile))
+ runCurrent()
+
+ // 2. Remove internetTile
+ underTest.setTiles(listOf(airplaneTile, alarmTile, flashlightTile))
+ runCurrent()
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(3)
+
+ with(uiEventLoggerFake[0]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_MOVE.id)
+ assertThat(packageName).isEqualTo(flashlightTile.metricSpec)
+ assertThat(position).isEqualTo(2)
+ }
+ with(uiEventLoggerFake[1]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_ADD.id)
+ assertThat(packageName).isEqualTo(alarmTile.metricSpec)
+ assertThat(position).isEqualTo(1)
+ }
+ with(uiEventLoggerFake[2]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_REMOVE.id)
+ assertThat(packageName).isEqualTo(internetTile.metricSpec)
+ }
+ }
+
companion object {
private val drawable1 = TestStubDrawable("drawable1")
private val appName1 = "App1"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/EditModeButtonViewModelTest.kt
similarity index 95%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/EditModeButtonViewModelTest.kt
index f2bfd72..a8e390c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/EditModeButtonViewModelTest.kt
@@ -23,6 +23,7 @@
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.runTest
+import com.android.systemui.qs.panels.ui.viewmodel.toolbar.editModeButtonViewModelFactory
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
index 869ab6c..1fc1c0f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
@@ -85,6 +85,24 @@
assertThat(TileSpec.create("")).isEqualTo(TileSpec.Invalid)
}
+ @Test
+ fun metricSpec_invalid() {
+ assertThat(TileSpec.Invalid.metricSpec).isEmpty()
+ }
+
+ @Test
+ fun metricSpec_platform_specName() {
+ val tile = "spec"
+ assertThat(TileSpec.create(tile).metricSpec).isEqualTo(tile)
+ }
+
+ @Test
+ fun metricSpec_custom_packageName() {
+ val componentName = ComponentName("test_pkg", "test_cls")
+
+ assertThat(TileSpec.create(componentName).metricSpec).isEqualTo(componentName.packageName)
+ }
+
companion object {
private const val CUSTOM_TILE_PREFIX = "custom("
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
index 3f4a134..b921ff7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
@@ -18,8 +18,9 @@
import android.net.ConnectivityManager
import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.internal.telephony.flags.Flags
@@ -31,6 +32,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.flags.QsInCompose.isEnabled
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -51,11 +53,17 @@
import org.mockito.kotlin.any
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
-class AirplaneModeTileTest : SysuiTestCase() {
+class AirplaneModeTileTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
@Mock private lateinit var mHost: QSHost
@Mock private lateinit var mMetricsLogger: MetricsLogger
@@ -149,4 +157,12 @@
QSTileImpl.ResourceIcon.get(resId)
}
}
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
index ae00349..cf9ef4d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
@@ -18,9 +18,10 @@
import android.content.Context
import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.systemui.SysuiTestCase
@@ -31,6 +32,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.flags.QsInCompose.isEnabled
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -51,14 +53,26 @@
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@RunWithLooper(setAsMainLooper = true)
@SmallTest
-class BatterySaverTileTest : SysuiTestCase() {
+class BatterySaverTileTest(flagsParameterization: FlagsParameterization) : SysuiTestCase() {
companion object {
private const val USER = 10
+
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
+ }
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flagsParameterization)
}
@Mock private lateinit var userContext: Context
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
index 31519c5..6bb6713 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
@@ -17,10 +17,11 @@
package com.android.systemui.qs.tiles
import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.provider.Settings
import android.safetycenter.SafetyCenterManager
import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.systemui.SysuiTestCase
@@ -30,6 +31,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLoggerFake
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.flags.QsInCompose.isEnabled
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -45,15 +47,27 @@
import org.mockito.Mock
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
-class CameraToggleTileTest : SysuiTestCase() {
+class CameraToggleTileTest(flags: FlagsParameterization) : SysuiTestCase() {
companion object {
/* isBlocked */
const val CAMERA_TOGGLE_ENABLED: Boolean = false
const val CAMERA_TOGGLE_DISABLED: Boolean = true
+
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
+ }
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
}
@Mock private lateinit var host: QSHost
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
index 2c796a9..a58dd63 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
@@ -16,6 +16,10 @@
package com.android.systemui.qs.tiles;
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -25,10 +29,10 @@
import android.content.Intent;
import android.os.Handler;
+import android.platform.test.flag.junit.FlagsParameterization;
import android.provider.Settings;
import android.testing.TestableLooper;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -55,13 +59,23 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class ColorInversionTileTest extends SysuiTestCase {
private static final Integer COLOR_INVERSION_DISABLED = 0;
private static final Integer COLOR_INVERSION_ENABLED = 1;
+ @Parameters(name = "{0}")
+ public static List<FlagsParameterization> getParams() {
+ return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+ }
+
@Mock
private QSHost mHost;
@Mock
@@ -81,6 +95,11 @@
private SecureSettings mSecureSettings;
private ColorInversionTile mTile;
+ public ColorInversionTileTest(FlagsParameterization flags) {
+ super();
+ mSetFlagsRule.setFlagsParameterization(flags);
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt
index 23be9da..27fd281 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DataSaverTileTest.kt
@@ -17,8 +17,9 @@
package com.android.systemui.qs.tiles
import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.systemui.SysuiTestCase
@@ -29,6 +30,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.flags.QsInCompose.isEnabled
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -44,11 +46,17 @@
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
-class DataSaverTileTest : SysuiTestCase() {
+class DataSaverTileTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
@Mock private lateinit var mHost: QSHost
@Mock private lateinit var mMetricsLogger: MetricsLogger
@@ -121,4 +129,12 @@
QSTileImpl.ResourceIcon.get(resId)
}
}
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
index 33748b9..9e4cf94 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
@@ -20,11 +20,14 @@
import android.content.Context
import android.content.Intent
import android.os.Handler
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.provider.Settings
import android.service.quicksettings.Tile
import android.testing.TestableLooper
import androidx.lifecycle.LifecycleOwner
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.systemui.SysuiTestCase
@@ -43,7 +46,9 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.res.R
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
@@ -67,11 +72,17 @@
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@SmallTest
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
-class DeviceControlsTileTest : SysuiTestCase() {
+class DeviceControlsTileTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
@Mock private lateinit var qsHost: QSHost
@Mock private lateinit var metricsLogger: MetricsLogger
@@ -151,7 +162,7 @@
}
`when`(controlsComponent.getTileTitleId()).thenReturn(R.string.quick_controls_title)
- `when`(controlsComponent.getTileTitleId()).thenReturn(R.drawable.controls_icon)
+ `when`(controlsComponent.getTileImageId()).thenReturn(R.drawable.controls_icon)
}
@Test
@@ -378,6 +389,28 @@
assertThat(tile.tileLabel).isEqualTo(context.getText(controlsComponent.getTileTitleId()))
}
+ @Test
+ @DisableFlags(QSComposeFragment.FLAG_NAME)
+ fun tileIconEqualsResourceFromComponent_composeFlagDisabled() {
+ tile.refreshState()
+ testableLooper.processAllMessages()
+ assertThat(tile.state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.controls_icon))
+ }
+
+ @Test
+ @EnableFlags(QSComposeFragment.FLAG_NAME)
+ fun tileIconEqualsResourceFromComponent_composeFlagEnable() {
+ tile.refreshState()
+ testableLooper.processAllMessages()
+ assertThat(tile.state.icon)
+ .isEqualTo(
+ QSTileImpl.DrawableIconWithRes(
+ mContext.getDrawable(R.drawable.controls_icon),
+ R.drawable.controls_icon,
+ )
+ )
+ }
+
private fun createTile(): DeviceControlsTile {
return DeviceControlsTile(
qsHost,
@@ -396,6 +429,14 @@
testableLooper.processAllMessages()
}
}
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
+ }
}
private const val CONTROLS_ACTIVITY_CLASS_NAME = "com.android.systemui.controls.ui.ControlsActivity"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
index 3cb9091..6a15a5b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/FlashlightTileTest.kt
@@ -1,9 +1,9 @@
package com.android.systemui.qs.tiles
-import android.content.Context
import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.systemui.SysuiTestCase
@@ -13,6 +13,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.flags.QsInCompose.isEnabled
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -27,13 +28,17 @@
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
-class FlashlightTileTest : SysuiTestCase() {
+class FlashlightTileTest(flags: FlagsParameterization) : SysuiTestCase() {
- @Mock private lateinit var mockContext: Context
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
@Mock private lateinit var qsLogger: QSLogger
@@ -58,7 +63,7 @@
MockitoAnnotations.initMocks(this)
testableLooper = TestableLooper.get(this)
- Mockito.`when`(qsHost.context).thenReturn(mockContext)
+ Mockito.`when`(qsHost.context).thenReturn(mContext)
tile =
FlashlightTile(
@@ -122,4 +127,12 @@
QSTileImpl.ResourceIcon.get(resId)
}
}
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
index f33de4d..eeccbdf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
@@ -17,10 +17,11 @@
package com.android.systemui.qs.tiles
import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.service.quicksettings.Tile
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.systemui.SysuiTestCase
@@ -29,6 +30,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tiles.dialog.InternetDialogManager
import com.android.systemui.qs.tiles.dialog.WifiStateWorker
@@ -62,12 +64,18 @@
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWithLooper(setAsMainLooper = true)
-@RunWith(AndroidJUnit4::class)
-class InternetTileNewImplTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class InternetTileNewImplTest(flags: FlagsParameterization) : SysuiTestCase() {
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
+
lateinit var underTest: InternetTileNewImpl
private val testDispatcher = StandardTestDispatcher()
@@ -252,5 +260,11 @@
const val WIFI_SSID = "test ssid"
val ACTIVE_WIFI =
WifiNetworkModel.Active.of(isValidated = true, level = 4, ssid = WIFI_SSID)
+
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileTest.java
index b5a64b3..d7b183e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileTest.java
@@ -16,6 +16,10 @@
package com.android.systemui.qs.tiles;
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq;
@@ -25,10 +29,10 @@
import static org.mockito.Mockito.when;
import android.os.Handler;
+import android.platform.test.flag.junit.FlagsParameterization;
import android.service.quicksettings.Tile;
import android.testing.TestableLooper;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -57,11 +61,21 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class InternetTileTest extends SysuiTestCase {
+ @Parameters(name = "{0}")
+ public static List<FlagsParameterization> getParams() {
+ return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+ }
+
@Mock
private QSHost mHost;
@Mock
@@ -78,6 +92,11 @@
private TestableLooper mTestableLooper;
private InternetTile mTile;
+ public InternetTileTest(FlagsParameterization flags) {
+ super();
+ mSetFlagsRule.setFlagsParameterization(flags);
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/LocationTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
index 4be1899..a581b57 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
@@ -16,10 +16,10 @@
package com.android.systemui.qs.tiles
-import android.content.Context
import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.systemui.SysuiTestCase
@@ -29,6 +29,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.flags.QsInCompose.isEnabled
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
@@ -48,13 +49,18 @@
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
-class LocationTileTest : SysuiTestCase() {
+class LocationTileTest(flags: FlagsParameterization) : SysuiTestCase() {
- @Mock private lateinit var mockContext: Context
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
+
@Mock private lateinit var qsLogger: QSLogger
@Mock private lateinit var qsHost: QSHost
@Mock private lateinit var metricsLogger: MetricsLogger
@@ -73,7 +79,7 @@
fun setUp() {
MockitoAnnotations.initMocks(this)
testableLooper = TestableLooper.get(this)
- `when`(qsHost.context).thenReturn(mockContext)
+ `when`(qsHost.context).thenReturn(mContext)
tile =
LocationTile(
@@ -139,4 +145,12 @@
QSTileImpl.ResourceIcon.get(resId)
}
}
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
index afe9713..a39692d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
@@ -17,10 +17,11 @@
package com.android.systemui.qs.tiles
import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.provider.Settings
import android.safetycenter.SafetyCenterManager
import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.systemui.SysuiTestCase
@@ -30,6 +31,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.flags.QsInCompose.isEnabled
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -45,15 +47,27 @@
import org.mockito.Mock
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
-class MicrophoneToggleTileTest : SysuiTestCase() {
+class MicrophoneToggleTileTest(flags: FlagsParameterization) : SysuiTestCase() {
companion object {
/* isBlocked */
const val MICROPHONE_TOGGLE_ENABLED: Boolean = false
const val MICROPHONE_TOGGLE_DISABLED: Boolean = true
+
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
+ }
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
}
@Mock private lateinit var host: QSHost
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt
index 69dab39..a193cbc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/NightDisplayTileTest.kt
@@ -19,8 +19,9 @@
import android.hardware.display.ColorDisplayManager
import android.hardware.display.NightDisplayListener
import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.systemui.SysuiTestCase
@@ -31,6 +32,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.flags.QsInCompose.isEnabled
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -46,11 +48,18 @@
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
-class NightDisplayTileTest : SysuiTestCase() {
+class NightDisplayTileTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
+
@Mock private lateinit var mHost: QSHost
@Mock private lateinit var mMetricsLogger: MetricsLogger
@@ -135,4 +144,12 @@
QSTileImpl.ResourceIcon.get(resId)
}
}
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
index 2345128..c244984 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
@@ -16,6 +16,10 @@
package com.android.systemui.qs.tiles;
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
+
import static junit.framework.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
@@ -28,10 +32,10 @@
import android.os.Handler;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.FlagsParameterization;
import android.service.quicksettings.Tile;
import android.testing.TestableLooper;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.R;
@@ -59,10 +63,21 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class ReduceBrightColorsTileTest extends SysuiTestCase {
+
+ @Parameters(name = "{0}")
+ public static List<FlagsParameterization> getParams() {
+ return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+ }
+
@Mock
private QSHost mHost;
@Mock
@@ -85,6 +100,11 @@
private TestableLooper mTestableLooper;
private ReduceBrightColorsTile mTile;
+ public ReduceBrightColorsTileTest(FlagsParameterization flags) {
+ super();
+ mSetFlagsRule.setFlagsParameterization(flags);
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
index 7fb0eab..fee358a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
@@ -17,6 +17,9 @@
package com.android.systemui.qs.tiles;
import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
import static junit.framework.TestCase.assertEquals;
@@ -27,10 +30,10 @@
import android.content.pm.PackageManager;
import android.hardware.SensorPrivacyManager;
import android.os.Handler;
+import android.platform.test.flag.junit.FlagsParameterization;
import android.testing.TestableLooper;
import android.testing.TestableResources;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -59,7 +62,12 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class RotationLockTileTest extends SysuiTestCase {
@@ -70,6 +78,11 @@
"1:2"
};
+ @Parameters(name = "{0}")
+ public static List<FlagsParameterization> getParams() {
+ return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+ }
+
@Mock
private PackageManager mPackageManager;
@Mock
@@ -98,6 +111,11 @@
private RotationLockTile mLockTile;
private TestableResources mTestableResources;
+ public RotationLockTileTest(FlagsParameterization flags) {
+ super();
+ mSetFlagsRule.setFlagsParameterization(flags);
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
index a7c7a78..fc1d73b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
@@ -16,6 +16,10 @@
package com.android.systemui.qs.tiles;
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
@@ -31,10 +35,10 @@
import android.app.Dialog;
import android.media.projection.StopReason;
import android.os.Handler;
+import android.platform.test.flag.junit.FlagsParameterization;
import android.service.quicksettings.Tile;
import android.testing.TestableLooper;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -66,11 +70,21 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class ScreenRecordTileTest extends SysuiTestCase {
+ @Parameters(name = "{0}")
+ public static List<FlagsParameterization> getParams() {
+ return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+ }
+
@Mock
private RecordingController mController;
@Mock
@@ -105,6 +119,11 @@
private TestableLooper mTestableLooper;
private ScreenRecordTile mTile;
+ public ScreenRecordTileTest(FlagsParameterization flags) {
+ super();
+ mSetFlagsRule.setFlagsParameterization(flags);
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt
index 773e225..3246e64 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/UiModeNightTileTest.kt
@@ -17,12 +17,11 @@
package com.android.systemui.qs.tiles
import android.app.UiModeManager
-import android.content.Context
import android.content.res.Configuration
-import android.content.res.Resources
import android.os.Handler
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.systemui.SysuiTestCase
@@ -32,6 +31,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.flags.QsInCompose.isEnabled
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -48,15 +48,19 @@
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
-class UiModeNightTileTest : SysuiTestCase() {
+class UiModeNightTileTest(flags: FlagsParameterization) : SysuiTestCase() {
- @Mock private lateinit var mockContext: Context
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
+
@Mock private lateinit var uiModeManager: UiModeManager
- @Mock private lateinit var resources: Resources
@Mock private lateinit var qsLogger: QSLogger
@Mock private lateinit var qsHost: QSHost
@Mock private lateinit var metricsLogger: MetricsLogger
@@ -70,19 +74,19 @@
private val falsingManager = FalsingManagerFake()
private lateinit var testableLooper: TestableLooper
private lateinit var tile: UiModeNightTile
- private lateinit var configuration: Configuration
+ private val configuration = Configuration()
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
+ val initialConfiguration = mContext.resources.configuration
+ onTeardown { mContext.resources.configuration.updateFrom(initialConfiguration) }
+
testableLooper = TestableLooper.get(this)
- configuration = Configuration()
mContext.addMockSystemService(UiModeManager::class.java, uiModeManager)
- `when`(qsHost.context).thenReturn(mockContext)
+ `when`(qsHost.context).thenReturn(mContext)
`when`(qsHost.userContext).thenReturn(mContext)
- `when`(mockContext.resources).thenReturn(resources)
- `when`(resources.configuration).thenReturn(configuration)
tile =
UiModeNightTile(
@@ -118,7 +122,7 @@
}
@Test
- fun testIcon_whenNightModeOn_isOffState() {
+ fun testIcon_whenNightModeOff_isOffState() {
val state = QSTile.BooleanState()
setNightModeOff()
@@ -131,11 +135,13 @@
private fun setNightModeOn() {
`when`(uiModeManager.nightMode).thenReturn(UiModeManager.MODE_NIGHT_YES)
configuration.uiMode = Configuration.UI_MODE_NIGHT_YES
+ mContext.resources.configuration.updateFrom(configuration)
}
private fun setNightModeOff() {
`when`(uiModeManager.nightMode).thenReturn(UiModeManager.MODE_NIGHT_NO)
configuration.uiMode = Configuration.UI_MODE_NIGHT_NO
+ mContext.resources.configuration.updateFrom(configuration)
}
private fun createExpectedIcon(resId: Int): QSTile.Icon {
@@ -145,4 +151,12 @@
QSTileImpl.ResourceIcon.get(resId)
}
}
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt
index 52c476e..e4a9888 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt
@@ -33,6 +33,7 @@
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.nullable
import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -136,4 +137,13 @@
verify(wifiStateWorker, times(1)).isWifiEnabled = eq(true)
}
+
+ @Test
+ fun detailsViewModel() =
+ kosmos.testScope.runTest {
+ assertThat(underTest.detailsViewModel.getTitle())
+ .isEqualTo("Internet")
+ assertThat(underTest.detailsViewModel.getSubTitle())
+ .isEqualTo("Tab a network to connect")
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
index 954215ee..2edb9c6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
@@ -173,6 +173,21 @@
.isEqualTo(FakeQSTileDataInteractor.AvailabilityRequest(USER))
}
+ @Test
+ fun tileDetails() =
+ testScope.runTest {
+ assertThat(tileUserActionInteractor.detailsViewModel).isNotNull()
+ assertThat(tileUserActionInteractor.detailsViewModel?.getTitle())
+ .isEqualTo("FakeQSTileUserActionInteractor")
+ assertThat(underTest.detailsViewModel).isNotNull()
+ assertThat(underTest.detailsViewModel?.getTitle())
+ .isEqualTo("FakeQSTileUserActionInteractor")
+
+ tileUserActionInteractor.detailsViewModel = null
+ assertThat(tileUserActionInteractor.detailsViewModel).isNull()
+ assertThat(underTest.detailsViewModel).isNull()
+ }
+
private fun createViewModel(
scope: TestScope,
config: QSTileConfig = tileConfig,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/CommunalSmartspaceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/CommunalSmartspaceControllerTest.kt
index 7842d75..f9b4488 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/CommunalSmartspaceControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/CommunalSmartspaceControllerTest.kt
@@ -111,6 +111,8 @@
override fun getCurrentCardTopPadding(): Int {
return 0
}
+
+ override fun setHorizontalPaddings(horizontalPadding: Int) {}
}
@Before
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
index c83c82d..70ba00e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
@@ -127,6 +127,8 @@
override fun getCurrentCardTopPadding(): Int {
return 0
}
+
+ override fun setHorizontalPaddings(horizontalPadding: Int) {}
}
@Before
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
index 3ebf9f7..a62d9d5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
@@ -34,6 +34,7 @@
import com.android.systemui.statusbar.chips.ui.model.ColorsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
@@ -163,6 +164,28 @@
}
@Test
+ @EnableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON, StatusBarConnectedDisplays.FLAG_NAME)
+ fun chip_positiveStartTime_notifIconAndConnectedDisplaysFlagOn_iconIsNotifIcon() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ val notifKey = "testNotifKey"
+ repo.setOngoingCallState(
+ inCallModel(startTimeMs = 1000, notificationIcon = null, notificationKey = notifKey)
+ )
+
+ assertThat((latest as OngoingActivityChipModel.Shown).icon)
+ .isInstanceOf(
+ OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon::class.java
+ )
+ val actualNotifKey =
+ (((latest as OngoingActivityChipModel.Shown).icon)
+ as OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon)
+ .notificationKey
+ assertThat(actualNotifKey).isEqualTo(notifKey)
+ }
+
+ @Test
@DisableFlags(FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON)
fun chip_zeroStartTime_notifIconFlagOff_iconIsPhone() =
testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt
index e96dd16..f06bab7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractorTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.chips.notification.domain.interactor
+import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -25,6 +26,8 @@
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.chips.notification.domain.model.NotificationChipModel
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -111,6 +114,27 @@
}
@Test
+ @EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
+ fun notificationChip_cdEnabled_missingStatusBarIconChipView_inConstructor_emitsNotNull() =
+ kosmos.runTest {
+ val underTest =
+ factory.create(
+ activeNotificationModel(
+ key = "notif1",
+ statusBarChipIcon = null,
+ whenTime = 123L,
+ )
+ )
+
+ val latest by collectLastValue(underTest.notificationChip)
+
+ assertThat(latest)
+ .isEqualTo(
+ NotificationChipModel("notif1", statusBarChipIconView = null, whenTime = 123L)
+ )
+ }
+
+ @Test
fun notificationChip_missingStatusBarIconChipView_inSet_emitsNull() =
kosmos.runTest {
val startingNotif = activeNotificationModel(key = "notif1", statusBarChipIcon = mock())
@@ -126,6 +150,29 @@
}
@Test
+ @EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
+ fun notificationChip_missingStatusBarIconChipView_inSet_cdEnabled_emitsNotNull() =
+ kosmos.runTest {
+ val startingNotif = activeNotificationModel(key = "notif1", statusBarChipIcon = mock())
+ val underTest = factory.create(startingNotif)
+ val latest by collectLastValue(underTest.notificationChip)
+ assertThat(latest).isNotNull()
+
+ underTest.setNotification(
+ activeNotificationModel(key = "notif1", statusBarChipIcon = null, whenTime = 123L)
+ )
+
+ assertThat(latest)
+ .isEqualTo(
+ NotificationChipModel(
+ key = "notif1",
+ statusBarChipIconView = null,
+ whenTime = 123L,
+ )
+ )
+ }
+
+ @Test
fun notificationChip_appIsVisibleOnCreation_emitsNull() =
kosmos.runTest {
activityManagerRepository.fake.startingIsAppVisibleValue = true
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
index 11831ca..8a4ddce 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
@@ -29,6 +29,7 @@
import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
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
@@ -107,6 +108,30 @@
}
@Test
+ @EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
+ fun chips_onePromotedNotif_connectedDisplaysFlagEnabled_statusBarIconMatches() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.chips)
+
+ val notifKey = "notif"
+ setNotifs(
+ listOf(
+ activeNotificationModel(
+ key = notifKey,
+ statusBarChipIcon = null,
+ promotedContent = PromotedNotificationContentModel.Builder(notifKey).build(),
+ )
+ )
+ )
+
+ assertThat(latest).hasSize(1)
+ val chip = latest!![0]
+ assertThat(chip).isInstanceOf(OngoingActivityChipModel.Shown.ShortTimeDelta::class.java)
+ assertThat(chip.icon)
+ .isEqualTo(OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(notifKey))
+ }
+
+ @Test
fun chips_onlyForPromotedNotifs() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
@@ -139,6 +164,41 @@
}
@Test
+ @EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
+ fun chips_connectedDisplaysFlagEnabled_onlyForPromotedNotifs() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.chips)
+
+ val firstKey = "notif1"
+ val secondKey = "notif2"
+ val thirdKey = "notif3"
+ setNotifs(
+ listOf(
+ activeNotificationModel(
+ key = firstKey,
+ statusBarChipIcon = null,
+ promotedContent = PromotedNotificationContentModel.Builder(firstKey).build(),
+ ),
+ activeNotificationModel(
+ key = secondKey,
+ statusBarChipIcon = null,
+ promotedContent =
+ PromotedNotificationContentModel.Builder(secondKey).build(),
+ ),
+ activeNotificationModel(
+ key = thirdKey,
+ statusBarChipIcon = null,
+ promotedContent = null,
+ ),
+ )
+ )
+
+ assertThat(latest).hasSize(2)
+ assertIsNotifKey(latest!![0], firstKey)
+ assertIsNotifKey(latest!![1], secondKey)
+ }
+
+ @Test
fun chips_clickingChipNotifiesInteractor() =
kosmos.runTest {
val latest by collectLastValue(underTest.chips)
@@ -178,5 +238,12 @@
assertThat((latest as OngoingActivityChipModel.Shown).icon)
.isEqualTo(OngoingActivityChipModel.ChipIcon.StatusBarView(expectedIcon))
}
+
+ fun assertIsNotifKey(latest: OngoingActivityChipModel?, expectedKey: String) {
+ assertThat(latest)
+ .isInstanceOf(OngoingActivityChipModel.Shown.ShortTimeDelta::class.java)
+ assertThat((latest as OngoingActivityChipModel.Shown).icon)
+ .isEqualTo(OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(expectedKey))
+ }
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
index fe287ef..611ae3d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
@@ -1109,6 +1109,9 @@
override fun getCurrentCardTopPadding(): Int {
return 0
}
+
+ override fun setHorizontalPaddings(horizontalPadding: Int) {
+ }
})
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
index 689fc7c..9e7befd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
package com.android.systemui.statusbar.notification.collection.coordinator
import android.app.Notification
@@ -22,671 +24,809 @@
import android.os.UserHandle
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.FlagsParameterization
import android.service.notification.StatusBarNotification
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.SceneKey
import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.keyguardUpdateMonitor
import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING
import com.android.systemui.SysuiTestCase
-import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
-import com.android.systemui.kosmos.applicationCoroutineScope
-import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.flags.andSceneContainer
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.plugins.statusbar.fakeStatusBarStateController
+import com.android.systemui.plugins.statusbar.statusBarStateController
import com.android.systemui.scene.domain.interactor.SceneInteractor
+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.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.RankingBuilder
import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.DynamicPrivacyController
import com.android.systemui.statusbar.notification.collection.ListEntry
import com.android.systemui.statusbar.notification.collection.NotifPipeline
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
-import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable
+import com.android.systemui.statusbar.notification.collection.notifPipeline
+import com.android.systemui.statusbar.notification.dynamicPrivacyController
+import com.android.systemui.statusbar.notification.mockDynamicPrivacyController
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
-import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.statusbar.notificationLockscreenUserManager
import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController
+import com.android.systemui.statusbar.policy.mockSensitiveNotificationProtectionController
+import com.android.systemui.statusbar.policy.sensitiveNotificationProtectionController
import com.android.systemui.testKosmos
-import com.android.systemui.user.domain.interactor.SelectedUserInteractor
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.withArgCaptor
-import dagger.BindsInstance
-import dagger.Component
-import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
+import org.mockito.kotlin.any
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@SmallTest
-@RunWith(AndroidJUnit4::class)
-class SensitiveContentCoordinatorTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class SensitiveContentCoordinatorTest(flags: FlagsParameterization) : SysuiTestCase() {
- val kosmos = testKosmos()
+ val kosmos =
+ testKosmos().apply {
+ // Override some Kosmos objects with mocks or fakes for easier testability
+ dynamicPrivacyController = mockDynamicPrivacyController
+ sensitiveNotificationProtectionController =
+ mockSensitiveNotificationProtectionController
+ statusBarStateController = fakeStatusBarStateController
+ }
- val dynamicPrivacyController: DynamicPrivacyController = mock()
- val lockscreenUserManager: NotificationLockscreenUserManager = mock()
- val pipeline: NotifPipeline = mock()
- val keyguardUpdateMonitor: KeyguardUpdateMonitor = mock()
- val statusBarStateController: StatusBarStateController = mock()
- val keyguardStateController: KeyguardStateController = mock()
- val mSelectedUserInteractor: SelectedUserInteractor = mock()
+ val testScope = kosmos.testScope
+
+ val dynamicPrivacyController: DynamicPrivacyController = kosmos.mockDynamicPrivacyController
+ val lockscreenUserManager: NotificationLockscreenUserManager =
+ kosmos.notificationLockscreenUserManager
+ val pipeline: NotifPipeline = kosmos.notifPipeline
+ val keyguardUpdateMonitor: KeyguardUpdateMonitor = kosmos.keyguardUpdateMonitor
+ val statusBarStateController: SysuiStatusBarStateController =
+ kosmos.fakeStatusBarStateController
val sensitiveNotificationProtectionController: SensitiveNotificationProtectionController =
- mock()
- val deviceEntryInteractor: DeviceEntryInteractor = mock()
- val sceneInteractor: SceneInteractor = mock()
+ kosmos.mockSensitiveNotificationProtectionController
+ val deviceEntryInteractor: DeviceEntryInteractor
+ get() = kosmos.deviceEntryInteractor
- val coordinator: SensitiveContentCoordinator =
- DaggerTestSensitiveContentCoordinatorComponent.factory()
- .create(
- dynamicPrivacyController,
- lockscreenUserManager,
- keyguardUpdateMonitor,
- statusBarStateController,
- keyguardStateController,
- mSelectedUserInteractor,
- sensitiveNotificationProtectionController,
- deviceEntryInteractor,
- sceneInteractor,
- kosmos.applicationCoroutineScope,
- )
- .coordinator
+ val faceAuthRepository = kosmos.fakeDeviceEntryFaceAuthRepository
+ val sceneInteractor: SceneInteractor
+ get() = kosmos.sceneInteractor
+
+ val coordinator: SensitiveContentCoordinator by lazy { kosmos.sensitiveContentCoordinator }
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return FlagsParameterization.allCombinationsOf().andSceneContainer()
+ }
+ }
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
@Test
- fun onDynamicPrivacyChanged_invokeInvalidationListener() {
- coordinator.attach(pipeline)
- val invalidator =
- withArgCaptor<Invalidator> { verify(pipeline).addPreRenderInvalidator(capture()) }
- val dynamicPrivacyListener =
- withArgCaptor<DynamicPrivacyController.Listener> {
- verify(dynamicPrivacyController).addListener(capture())
- }
+ @EnableSceneContainer
+ fun onLockscreenDynamicallyUnlocked_invokeInvalidationListener() =
+ testScope.runTest {
+ // Setup
+ coordinator.attach(pipeline)
+ val invalidator =
+ withArgCaptor<Invalidator> { verify(pipeline).addPreRenderInvalidator(capture()) }
+ val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>()
+ invalidator.setInvalidationListener(invalidationListener)
- val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>()
- invalidator.setInvalidationListener(invalidationListener)
+ // Given the lockscreen is shown
+ setupLockScreen(canSwipeUp = false)
+ clearInvocations(invalidationListener)
- dynamicPrivacyListener.onDynamicPrivacyChanged()
+ // When the device gets unlocked
+ faceAuthRepository.isAuthenticated.value = true
+ runCurrent()
- verify(invalidationListener).onPluggableInvalidated(eq(invalidator), any())
- }
+ // Then the invalidationListener is called
+ verify(invalidationListener).onPluggableInvalidated(eq(invalidator), any())
+ }
+
+ @Test
+ @DisableSceneContainer
+ fun onDynamicPrivacyChanged_invokeInvalidationListener() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val invalidator =
+ withArgCaptor<Invalidator> { verify(pipeline).addPreRenderInvalidator(capture()) }
+ val dynamicPrivacyListener =
+ withArgCaptor<DynamicPrivacyController.Listener> {
+ verify(dynamicPrivacyController).addListener(capture())
+ }
+
+ val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>()
+ invalidator.setInvalidationListener(invalidationListener)
+
+ dynamicPrivacyListener.onDynamicPrivacyChanged()
+
+ verify(invalidationListener).onPluggableInvalidated(eq(invalidator), any())
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun onSensitiveStateChanged_invokeInvalidationListener() {
- coordinator.attach(pipeline)
- val invalidator =
- withArgCaptor<Invalidator> { verify(pipeline).addPreRenderInvalidator(capture()) }
- val onSensitiveStateChangedListener =
- withArgCaptor<Runnable> {
- verify(sensitiveNotificationProtectionController)
- .registerSensitiveStateListener(capture())
- }
+ fun onSensitiveStateChanged_invokeInvalidationListener() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val invalidator =
+ withArgCaptor<Invalidator> { verify(pipeline).addPreRenderInvalidator(capture()) }
+ val onSensitiveStateChangedListener =
+ withArgCaptor<Runnable> {
+ verify(sensitiveNotificationProtectionController)
+ .registerSensitiveStateListener(capture())
+ }
- val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>()
- invalidator.setInvalidationListener(invalidationListener)
+ val invalidationListener = mock<Pluggable.PluggableListener<Invalidator>>()
+ invalidator.setInvalidationListener(invalidationListener)
- onSensitiveStateChangedListener.run()
+ onSensitiveStateChangedListener.run()
- verify(invalidationListener).onPluggableInvalidated(eq(invalidator), any())
- }
+ verify(invalidationListener).onPluggableInvalidated(eq(invalidator), any())
+ }
@Test
@DisableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun screenshareSecretFilter_flagDisabled_filterNoAdded() {
- coordinator.attach(pipeline)
+ fun screenshareSecretFilter_flagDisabled_filterNoAdded() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
- verify(pipeline, never()).addFinalizeFilter(any(NotifFilter::class.java))
- }
+ verify(pipeline, never()).addFinalizeFilter(any())
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun screenshareSecretFilter_sensitiveInctive_noFiltersSecret() {
- whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(false)
+ fun screenshareSecretFilter_sensitiveInctive_noFiltersSecret() =
+ testScope.runTest {
+ whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+ .thenReturn(false)
- coordinator.attach(pipeline)
- val filter = withArgCaptor<NotifFilter> { verify(pipeline).addFinalizeFilter(capture()) }
+ coordinator.attach(pipeline)
+ val filter =
+ withArgCaptor<NotifFilter> { verify(pipeline).addFinalizeFilter(capture()) }
- val defaultNotification = createNotificationEntry("test", false, false)
- val notificationWithSecretVisibility = createNotificationEntry("test", true, false)
- val notificationOnSecretChannel = createNotificationEntry("test", false, true)
+ val defaultNotification = createNotificationEntry("test", false, false)
+ val notificationWithSecretVisibility = createNotificationEntry("test", true, false)
+ val notificationOnSecretChannel = createNotificationEntry("test", false, true)
- assertFalse(filter.shouldFilterOut(defaultNotification, 0))
- assertFalse(filter.shouldFilterOut(notificationWithSecretVisibility, 0))
- assertFalse(filter.shouldFilterOut(notificationOnSecretChannel, 0))
- }
+ assertFalse(filter.shouldFilterOut(defaultNotification, 0))
+ assertFalse(filter.shouldFilterOut(notificationWithSecretVisibility, 0))
+ assertFalse(filter.shouldFilterOut(notificationOnSecretChannel, 0))
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun screenshareSecretFilter_sensitiveActive_filtersSecret() {
- whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+ fun screenshareSecretFilter_sensitiveActive_filtersSecret() =
+ testScope.runTest {
+ whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+ .thenReturn(true)
- coordinator.attach(pipeline)
- val filter = withArgCaptor<NotifFilter> { verify(pipeline).addFinalizeFilter(capture()) }
+ coordinator.attach(pipeline)
+ val filter =
+ withArgCaptor<NotifFilter> { verify(pipeline).addFinalizeFilter(capture()) }
- val defaultNotification = createNotificationEntry("test", false, false)
- val notificationWithSecretVisibility = createNotificationEntry("test", true, false)
- val notificationOnSecretChannel = createNotificationEntry("test", false, true)
+ val defaultNotification = createNotificationEntry("test", false, false)
+ val notificationWithSecretVisibility = createNotificationEntry("test", true, false)
+ val notificationOnSecretChannel = createNotificationEntry("test", false, true)
- assertFalse(filter.shouldFilterOut(defaultNotification, 0))
- assertTrue(filter.shouldFilterOut(notificationWithSecretVisibility, 0))
- assertTrue(filter.shouldFilterOut(notificationOnSecretChannel, 0))
- }
+ assertFalse(filter.shouldFilterOut(defaultNotification, 0))
+ assertTrue(filter.shouldFilterOut(notificationWithSecretVisibility, 0))
+ assertTrue(filter.shouldFilterOut(notificationOnSecretChannel, 0))
+ }
@Test
- fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, false)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(true)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, false)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(false, false)
- }
+ verify(entry.representativeEntry!!).setSensitive(false, false)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction_sensitiveActive() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction_sensitiveActive() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, false)
- whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(true)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, false)
+ whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(false, true)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
- }
+ verify(entry.representativeEntry!!).setSensitive(false, true)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction_shouldProtectNotification() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceUnlocked_notifDoesNotNeedRedaction_shouldProtectNotification() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, false)
- whenever(
- sensitiveNotificationProtectionController.shouldProtectNotification(
- entry.getRepresentativeEntry()
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(true)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, false)
+ whenever(
+ sensitiveNotificationProtectionController.shouldProtectNotification(
+ entry.getRepresentativeEntry()
+ )
)
- )
- .thenReturn(true)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(true, false)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
- }
+ verify(entry.representativeEntry!!).setSensitive(true, false)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+ }
@Test
- fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, true)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(true)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(false, false)
- }
+ verify(entry.representativeEntry!!).setSensitive(false, false)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction_sensitiveActive() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction_sensitiveActive() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, true)
- whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(true)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, true)
+ whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(false, true)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
- }
+ verify(entry.representativeEntry!!).setSensitive(false, true)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction_shouldProtectNotification() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceUnlocked_notifWouldNeedRedaction_shouldProtectNotification() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, true)
- whenever(
- sensitiveNotificationProtectionController.shouldProtectNotification(
- entry.getRepresentativeEntry()
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(false)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(true)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, true)
+ whenever(
+ sensitiveNotificationProtectionController.shouldProtectNotification(
+ entry.getRepresentativeEntry()
+ )
)
- )
- .thenReturn(true)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(true, false)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
- }
+ verify(entry.representativeEntry!!).setSensitive(true, false)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+ }
@Test
- fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, false)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(true)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, false)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(false, false)
- }
+ verify(entry.representativeEntry!!).setSensitive(false, false)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs_sensitiveActive() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs_sensitiveActive() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, false)
- whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(true)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, false)
+ whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(false, true)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
- }
+ verify(entry.representativeEntry!!).setSensitive(false, true)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs_shouldProtectNotification() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceLocked_userAllowsPublicNotifs_shouldProtectNotification() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(true)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, false)
- whenever(
- sensitiveNotificationProtectionController.shouldProtectNotification(
- entry.getRepresentativeEntry()
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(true)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, false)
+ whenever(
+ sensitiveNotificationProtectionController.shouldProtectNotification(
+ entry.getRepresentativeEntry()
+ )
)
- )
- .thenReturn(true)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(true, false)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
- }
+ verify(entry.representativeEntry!!).setSensitive(true, false)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+ }
@Test
- fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, false)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, false)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(false, true)
- }
+ verify(entry.representativeEntry!!).setSensitive(false, true)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
@Suppress("ktlint:standard:max-line-length")
- fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction_sensitiveActive() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction_sensitiveActive() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, false)
- whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, false)
+ whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(false, true)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
- }
+ verify(entry.representativeEntry!!).setSensitive(false, true)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
@Suppress("ktlint:standard:max-line-length")
- fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction_shouldProtectNotification() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceLocked_userDisallowsPublicNotifs_notifDoesNotNeedRedaction_shouldProtectNotification() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, false)
- whenever(
- sensitiveNotificationProtectionController.shouldProtectNotification(
- entry.getRepresentativeEntry()
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, false)
+ whenever(
+ sensitiveNotificationProtectionController.shouldProtectNotification(
+ entry.getRepresentativeEntry()
+ )
)
- )
- .thenReturn(true)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(true, true)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
- }
+ verify(entry.representativeEntry!!).setSensitive(true, true)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+ }
@Test
- fun onBeforeRenderList_deviceLocked_notifNeedsRedaction() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceLocked_notifNeedsRedaction() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, true)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(true, true)
- }
+ verify(entry.representativeEntry!!).setSensitive(true, true)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun onBeforeRenderList_deviceLocked_notifNeedsRedaction_sensitiveActive() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceLocked_notifNeedsRedaction_sensitiveActive() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, true)
- whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, true)
+ whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(true, true)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
- }
+ verify(entry.representativeEntry!!).setSensitive(true, true)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun onBeforeRenderList_deviceLocked_notifNeedsRedaction_shouldProtectNotification() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceLocked_notifNeedsRedaction_shouldProtectNotification() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(false)
- val entry = fakeNotification(1, true)
- whenever(
- sensitiveNotificationProtectionController.shouldProtectNotification(
- entry.getRepresentativeEntry()
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = false)
+ val entry = fakeNotification(1, true)
+ whenever(
+ sensitiveNotificationProtectionController.shouldProtectNotification(
+ entry.getRepresentativeEntry()
+ )
)
- )
- .thenReturn(true)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(true, true)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
- }
+ verify(entry.representativeEntry!!).setSensitive(true, true)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+ }
@Test
- fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
- val entry = fakeNotification(1, true)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = true)
+ val entry = fakeNotification(1, true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(false, true)
- }
+ verify(entry.representativeEntry!!).setSensitive(false, true)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction_sensitiveActive() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction_sensitiveActive() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
- val entry = fakeNotification(1, true)
- whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = true)
+ val entry = fakeNotification(1, true)
+ whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(false, true)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
- }
+ verify(entry.representativeEntry!!).setSensitive(false, true)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
@Suppress("ktlint:standard:max-line-length")
- fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction_shouldProtectNotification() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceDynamicallyUnlocked_notifNeedsRedaction_shouldProtectNotification() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
- val entry = fakeNotification(1, true)
- whenever(
- sensitiveNotificationProtectionController.shouldProtectNotification(
- entry.getRepresentativeEntry()
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = true)
+ val entry = fakeNotification(1, true)
+ whenever(
+ sensitiveNotificationProtectionController.shouldProtectNotification(
+ entry.getRepresentativeEntry()
+ )
)
- )
- .thenReturn(true)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(true, true)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
- }
+ verify(entry.representativeEntry!!).setSensitive(true, true)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+ }
@Test
- fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
- whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
- val entry = fakeNotification(2, true)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = true)
+ whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
+ val entry = fakeNotification(2, true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(true, true)
- }
+ verify(entry.representativeEntry!!).setSensitive(true, true)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
- fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge_sensitiveActive() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge_sensitiveActive() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
- whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
- val entry = fakeNotification(2, true)
- whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = true)
+ whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
+ val entry = fakeNotification(2, true)
+ whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(true, true)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
- }
+ verify(entry.representativeEntry!!).setSensitive(true, true)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true)
+ }
@Test
@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
@Suppress("ktlint:standard:max-line-length")
- fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge_shouldProtectNotification() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceDynamicallyUnlocked_notifUserNeedsWorkChallenge_shouldProtectNotification() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
- whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
- val entry = fakeNotification(2, true)
- whenever(
- sensitiveNotificationProtectionController.shouldProtectNotification(
- entry.getRepresentativeEntry()
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = true)
+ whenever(lockscreenUserManager.needsSeparateWorkChallenge(2)).thenReturn(true)
+ val entry = fakeNotification(2, true)
+ whenever(
+ sensitiveNotificationProtectionController.shouldProtectNotification(
+ entry.getRepresentativeEntry()
+ )
)
- )
- .thenReturn(true)
+ .thenReturn(true)
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!).setSensitive(true, true)
- verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
- }
+ verify(entry.representativeEntry!!).setSensitive(true, true)
+ verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false)
+ }
@Test
- fun onBeforeRenderList_deviceDynamicallyUnlocked_deviceBiometricBypassingLockScreen() {
- coordinator.attach(pipeline)
- val onBeforeRenderListListener =
- withArgCaptor<OnBeforeRenderListListener> {
- verify(pipeline).addOnBeforeRenderListListener(capture())
- }
+ fun onBeforeRenderList_deviceDynamicallyUnlocked_deviceBiometricBypassingLockScreen() =
+ testScope.runTest {
+ coordinator.attach(pipeline)
+ val onBeforeRenderListListener =
+ withArgCaptor<OnBeforeRenderListListener> {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
- whenever(lockscreenUserManager.currentUserId).thenReturn(1)
- whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
- whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1)).thenReturn(false)
- whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(true)
- whenever(statusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD)
- whenever(keyguardUpdateMonitor.getUserUnlockedWithBiometricAndIsBypassing(any()))
- .thenReturn(true)
- val entry = fakeNotification(2, true)
- whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
- whenever(sensitiveNotificationProtectionController.shouldProtectNotification(any()))
- .thenReturn(true)
+ whenever(lockscreenUserManager.currentUserId).thenReturn(1)
+ whenever(lockscreenUserManager.isLockscreenPublicMode(1)).thenReturn(true)
+ whenever(lockscreenUserManager.userAllowsPrivateNotificationsInPublic(1))
+ .thenReturn(false)
+ setupLockScreen(canSwipeUp = true)
+ whenever(keyguardUpdateMonitor.getUserUnlockedWithBiometricAndIsBypassing(any()))
+ .thenReturn(true)
+ val entry = fakeNotification(2, true)
+ whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+ .thenReturn(true)
+ whenever(sensitiveNotificationProtectionController.shouldProtectNotification(any()))
+ .thenReturn(true)
+ statusBarStateController.state = StatusBarState.KEYGUARD
- onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+ onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
- verify(entry.representativeEntry!!, never()).setSensitive(any(), any())
- verify(entry.representativeEntry!!.row!!, never()).setPublicExpanderVisible(any())
+ verify(entry.representativeEntry!!, never()).setSensitive(any(), any())
+ verify(entry.representativeEntry!!.row!!, never()).setPublicExpanderVisible(any())
+ }
+
+ private fun TestScope.setupLockScreen(canSwipeUp: Boolean) {
+ if (SceneContainerFlag.isEnabled) {
+ val authMethod =
+ if (canSwipeUp) AuthenticationMethodModel.None
+ else AuthenticationMethodModel.Password
+ kosmos.fakeAuthenticationRepository.setAuthenticationMethod(authMethod)
+ kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true)
+ switchToScene(Scenes.Lockscreen)
+ } else {
+ whenever(dynamicPrivacyController.isDynamicallyUnlocked).thenReturn(canSwipeUp)
+ }
+ }
+
+ private fun TestScope.switchToScene(sceneKey: SceneKey) {
+ sceneInteractor.changeScene(sceneKey, "reason")
+ sceneInteractor.setTransitionState(flowOf(ObservableTransitionState.Idle(sceneKey)))
+ runCurrent()
}
private fun fakeNotification(notifUserId: Int, needsRedaction: Boolean): ListEntry {
@@ -733,26 +873,3 @@
return notificationEntry
}
}
-
-@CoordinatorScope
-@Component(modules = [SensitiveContentCoordinatorModule::class])
-interface TestSensitiveContentCoordinatorComponent {
- val coordinator: SensitiveContentCoordinator
-
- @Component.Factory
- interface Factory {
- fun create(
- @BindsInstance dynamicPrivacyController: DynamicPrivacyController,
- @BindsInstance lockscreenUserManager: NotificationLockscreenUserManager,
- @BindsInstance keyguardUpdateMonitor: KeyguardUpdateMonitor,
- @BindsInstance statusBarStateController: StatusBarStateController,
- @BindsInstance keyguardStateController: KeyguardStateController,
- @BindsInstance selectedUserInteractor: SelectedUserInteractor,
- @BindsInstance
- sensitiveNotificationProtectionController: SensitiveNotificationProtectionController,
- @BindsInstance deviceEntryInteractor: DeviceEntryInteractor,
- @BindsInstance sceneInteractor: SceneInteractor,
- @BindsInstance @Application scope: CoroutineScope,
- ): TestSensitiveContentCoordinatorComponent
- }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplOldTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplOldTest.kt
deleted file mode 100644
index 8b4f53a..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplOldTest.kt
+++ /dev/null
@@ -1,698 +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.systemui.statusbar.notification.headsup
-
-import android.app.Notification
-import android.app.PendingIntent
-import android.app.Person
-import android.os.Handler
-import android.platform.test.annotations.DisableFlags
-import android.platform.test.annotations.EnableFlags
-import android.platform.test.flag.junit.FlagsParameterization
-import android.testing.TestableLooper.RunWithLooper
-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.log.logcatLogBuffer
-import com.android.systemui.res.R
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
-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.headsup.HeadsUpManagerImpl.HeadsUpEntry
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
-import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
-import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
-import com.android.systemui.util.concurrency.FakeExecutor
-import com.android.systemui.util.concurrency.mockExecutorHandler
-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
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.flow.MutableStateFlow
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers
-import org.mockito.Mock
-import org.mockito.Mockito
-import org.mockito.invocation.InvocationOnMock
-import org.mockito.junit.MockitoJUnit
-import org.mockito.junit.MockitoRule
-import org.mockito.kotlin.eq
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4
-import platform.test.runner.parameterized.Parameters
-
-@SmallTest
-@RunWithLooper
-@RunWith(ParameterizedAndroidJunit4::class)
-// TODO(b/378142453): Merge this with HeadsUpManagerImplTest.
-open class HeadsUpManagerImplOldTest(flags: FlagsParameterization?) : SysuiTestCase() {
- protected var mKosmos: KosmosJavaAdapter = KosmosJavaAdapter(this)
-
- @JvmField @Rule var rule: MockitoRule = MockitoJUnit.rule()
-
- private val mUiEventLoggerFake = UiEventLoggerFake()
-
- private val mLogger: HeadsUpManagerLogger = Mockito.spy(HeadsUpManagerLogger(logcatLogBuffer()))
-
- @Mock private val mBgHandler: Handler? = null
-
- @Mock private val dumpManager: DumpManager? = null
-
- @Mock private val mShadeInteractor: ShadeInteractor? = null
- private var mAvalancheController: AvalancheController? = null
-
- @Mock private val mAccessibilityMgr: AccessibilityManagerWrapper? = null
-
- protected val globalSettings: FakeGlobalSettings = FakeGlobalSettings()
- protected val systemClock: FakeSystemClock = FakeSystemClock()
- protected val executor: FakeExecutor = FakeExecutor(systemClock)
-
- @Mock protected var mRow: ExpandableNotificationRow? = null
-
- private fun createHeadsUpManager(): HeadsUpManagerImpl {
- return HeadsUpManagerImpl(
- mContext,
- mLogger,
- mKosmos.statusBarStateController,
- mKosmos.keyguardBypassController,
- GroupMembershipManagerImpl(),
- mKosmos.visualStabilityProvider,
- mKosmos.configurationController,
- mockExecutorHandler(executor),
- globalSettings,
- systemClock,
- executor,
- mAccessibilityMgr,
- mUiEventLoggerFake,
- JavaAdapter(mKosmos.testScope),
- mShadeInteractor,
- mAvalancheController,
- )
- }
-
- private fun createStickyEntry(id: Int): NotificationEntry {
- val notif =
- Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .setFullScreenIntent(
- Mockito.mock(PendingIntent::class.java), /* highPriority */
- true,
- )
- .build()
- return HeadsUpManagerTestUtil.createEntry(id, notif)
- }
-
- private fun createStickyForSomeTimeEntry(id: Int): NotificationEntry {
- val notif =
- Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .setFlag(Notification.FLAG_FSI_REQUESTED_BUT_DENIED, true)
- .build()
- return HeadsUpManagerTestUtil.createEntry(id, notif)
- }
-
- private fun useAccessibilityTimeout(use: Boolean) {
- if (use) {
- Mockito.doReturn(TEST_A11Y_AUTO_DISMISS_TIME)
- .`when`(mAccessibilityMgr!!)
- .getRecommendedTimeoutMillis(ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt())
- } else {
- Mockito.`when`(
- mAccessibilityMgr!!.getRecommendedTimeoutMillis(
- ArgumentMatchers.anyInt(),
- ArgumentMatchers.anyInt(),
- )
- )
- .then { i: InvocationOnMock -> i.getArgument(0) }
- }
- }
-
- init {
- mSetFlagsRule.setFlagsParameterization(flags!!)
- }
-
- @Throws(Exception::class)
- override fun SysuiSetup() {
- super.SysuiSetup()
- mContext.getOrCreateTestableResources().apply {
- this.addOverride(R.integer.ambient_notification_extension_time, TEST_EXTENSION_TIME)
- this.addOverride(R.integer.touch_acceptance_delay, TEST_TOUCH_ACCEPTANCE_TIME)
- this.addOverride(
- R.integer.heads_up_notification_minimum_time,
- TEST_MINIMUM_DISPLAY_TIME,
- )
- this.addOverride(
- R.integer.heads_up_notification_minimum_time_with_throttling,
- TEST_MINIMUM_DISPLAY_TIME,
- )
- this.addOverride(R.integer.heads_up_notification_decay, TEST_AUTO_DISMISS_TIME)
- this.addOverride(
- R.integer.sticky_heads_up_notification_time,
- TEST_STICKY_AUTO_DISMISS_TIME,
- )
- }
-
- mAvalancheController =
- AvalancheController(dumpManager!!, mUiEventLoggerFake, mLogger, mBgHandler!!)
- Mockito.`when`(mShadeInteractor!!.isAnyExpanded).thenReturn(MutableStateFlow(true))
- Mockito.`when`(mKosmos.keyguardBypassController.bypassEnabled).thenReturn(false)
- }
-
- @Test
- fun testHasNotifications_headsUpManagerMapNotEmpty_true() {
- val bhum = createHeadsUpManager()
- val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
- bhum.showNotification(entry)
-
- Truth.assertThat(bhum.mHeadsUpEntryMap).isNotEmpty()
- Truth.assertThat(bhum.hasNotifications()).isTrue()
- }
-
- @Test
- @EnableFlags(NotificationThrottleHun.FLAG_NAME)
- fun testHasNotifications_avalancheMapNotEmpty_true() {
- val bhum = createHeadsUpManager()
- val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
- val headsUpEntry = bhum.createHeadsUpEntry(notifEntry)
- mAvalancheController!!.addToNext(headsUpEntry) {}
-
- Truth.assertThat(mAvalancheController!!.getWaitingEntryList()).isNotEmpty()
- Truth.assertThat(bhum.hasNotifications()).isTrue()
- }
-
- @Test
- @EnableFlags(NotificationThrottleHun.FLAG_NAME)
- fun testHasNotifications_false() {
- val bhum = createHeadsUpManager()
- Truth.assertThat(bhum.mHeadsUpEntryMap).isEmpty()
- Truth.assertThat(mAvalancheController!!.getWaitingEntryList()).isEmpty()
- Truth.assertThat(bhum.hasNotifications()).isFalse()
- }
-
- @Test
- @EnableFlags(NotificationThrottleHun.FLAG_NAME)
- fun testGetHeadsUpEntryList_includesAvalancheEntryList() {
- val bhum = createHeadsUpManager()
- val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
- val headsUpEntry = bhum.createHeadsUpEntry(notifEntry)
- mAvalancheController!!.addToNext(headsUpEntry) {}
-
- Truth.assertThat(bhum.headsUpEntryList).contains(headsUpEntry)
- }
-
- @Test
- @EnableFlags(NotificationThrottleHun.FLAG_NAME)
- fun testGetHeadsUpEntry_returnsAvalancheEntry() {
- val bhum = createHeadsUpManager()
- val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
- val headsUpEntry = bhum.createHeadsUpEntry(notifEntry)
- mAvalancheController!!.addToNext(headsUpEntry) {}
-
- Truth.assertThat(bhum.getHeadsUpEntry(notifEntry.key)).isEqualTo(headsUpEntry)
- }
-
- @Test
- fun testShowNotification_addsEntry() {
- val alm = createHeadsUpManager()
- val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-
- alm.showNotification(entry)
-
- assertThat(alm.isHeadsUpEntry(entry.key)).isTrue()
- assertThat(alm.hasNotifications()).isTrue()
- assertThat(alm.getEntry(entry.key)).isEqualTo(entry)
- }
-
- @Test
- fun testShowNotification_autoDismisses() {
- val alm = createHeadsUpManager()
- val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-
- alm.showNotification(entry)
- systemClock.advanceTime((TEST_AUTO_DISMISS_TIME * 3 / 2).toLong())
-
- assertThat(alm.isHeadsUpEntry(entry.key)).isFalse()
- }
-
- @Test
- fun testRemoveNotification_removeDeferred() {
- val alm = createHeadsUpManager()
- val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-
- alm.showNotification(entry)
-
- val removedImmediately =
- alm.removeNotification(entry.key, /* releaseImmediately= */ false, "removeDeferred")
- assertThat(removedImmediately).isFalse()
- assertThat(alm.isHeadsUpEntry(entry.key)).isTrue()
- }
-
- @Test
- fun testRemoveNotification_forceRemove() {
- val alm = createHeadsUpManager()
- val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-
- alm.showNotification(entry)
-
- val removedImmediately =
- alm.removeNotification(entry.key, /* releaseImmediately= */ true, "forceRemove")
- assertThat(removedImmediately).isTrue()
- assertThat(alm.isHeadsUpEntry(entry.key)).isFalse()
- }
-
- @Test
- fun testReleaseAllImmediately() {
- val alm = createHeadsUpManager()
- for (i in 0 until TEST_NUM_NOTIFICATIONS) {
- val entry = HeadsUpManagerTestUtil.createEntry(i, mContext)
- entry.row = mRow
- alm.showNotification(entry)
- }
-
- alm.releaseAllImmediately()
-
- assertThat(alm.allEntries.count()).isEqualTo(0)
- }
-
- @Test
- fun testCanRemoveImmediately_notShownLongEnough() {
- val alm = createHeadsUpManager()
- val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-
- alm.showNotification(entry)
-
- // The entry has just been added so we should not remove immediately.
- assertThat(alm.canRemoveImmediately(entry.key)).isFalse()
- }
-
- @Test
- fun testHunRemovedLogging() {
- val hum = createHeadsUpManager()
- val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
- val headsUpEntry = Mockito.mock(HeadsUpEntry::class.java)
- Mockito.`when`(headsUpEntry.pinnedStatus)
- .thenReturn(MutableStateFlow(PinnedStatus.NotPinned))
- headsUpEntry.mEntry = notifEntry
-
- hum.onEntryRemoved(headsUpEntry, "test")
-
- Mockito.verify(mLogger, Mockito.times(1)).logNotificationActuallyRemoved(eq(notifEntry))
- }
-
- @Test
- fun testShowNotification_autoDismissesIncludingTouchAcceptanceDelay() {
- val hum = createHeadsUpManager()
- val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
- useAccessibilityTimeout(false)
-
- hum.showNotification(entry)
- systemClock.advanceTime((TEST_TOUCH_ACCEPTANCE_TIME / 2 + TEST_AUTO_DISMISS_TIME).toLong())
-
- assertThat(hum.isHeadsUpEntry(entry.key)).isTrue()
- }
-
- @Test
- fun testShowNotification_autoDismissesWithDefaultTimeout() {
- val hum = createHeadsUpManager()
- val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
- useAccessibilityTimeout(false)
-
- hum.showNotification(entry)
- systemClock.advanceTime(
- (TEST_TOUCH_ACCEPTANCE_TIME +
- (TEST_AUTO_DISMISS_TIME + TEST_A11Y_AUTO_DISMISS_TIME) / 2)
- .toLong()
- )
-
- assertThat(hum.isHeadsUpEntry(entry.key)).isFalse()
- }
-
- @Test
- fun testShowNotification_stickyForSomeTime_autoDismissesWithStickyTimeout() {
- val hum = createHeadsUpManager()
- val entry = createStickyForSomeTimeEntry(/* id= */ 0)
- useAccessibilityTimeout(false)
-
- hum.showNotification(entry)
- systemClock.advanceTime(
- (TEST_TOUCH_ACCEPTANCE_TIME +
- (TEST_AUTO_DISMISS_TIME + TEST_STICKY_AUTO_DISMISS_TIME) / 2)
- .toLong()
- )
-
- assertThat(hum.isHeadsUpEntry(entry.key)).isTrue()
- }
-
- @Test
- fun testShowNotification_sticky_neverAutoDismisses() {
- val hum = createHeadsUpManager()
- val entry = createStickyEntry(/* id= */ 0)
- useAccessibilityTimeout(false)
-
- hum.showNotification(entry)
- systemClock.advanceTime(
- (TEST_TOUCH_ACCEPTANCE_TIME + 2 * TEST_A11Y_AUTO_DISMISS_TIME).toLong()
- )
-
- assertThat(hum.isHeadsUpEntry(entry.key)).isTrue()
- }
-
- @Test
- fun testShowNotification_autoDismissesWithAccessibilityTimeout() {
- val hum = createHeadsUpManager()
- val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
- useAccessibilityTimeout(true)
-
- hum.showNotification(entry)
- systemClock.advanceTime(
- (TEST_TOUCH_ACCEPTANCE_TIME +
- (TEST_AUTO_DISMISS_TIME + TEST_A11Y_AUTO_DISMISS_TIME) / 2)
- .toLong()
- )
-
- assertThat(hum.isHeadsUpEntry(entry.key)).isTrue()
- }
-
- @Test
- fun testShowNotification_stickyForSomeTime_autoDismissesWithAccessibilityTimeout() {
- val hum = createHeadsUpManager()
- val entry = createStickyForSomeTimeEntry(/* id= */ 0)
- useAccessibilityTimeout(true)
-
- hum.showNotification(entry)
- systemClock.advanceTime(
- (TEST_TOUCH_ACCEPTANCE_TIME +
- (TEST_STICKY_AUTO_DISMISS_TIME + TEST_A11Y_AUTO_DISMISS_TIME) / 2)
- .toLong()
- )
-
- assertThat(hum.isHeadsUpEntry(entry.key)).isTrue()
- }
-
- @Test
- fun testRemoveNotification_beforeMinimumDisplayTime() {
- val hum = createHeadsUpManager()
- val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
- useAccessibilityTimeout(false)
-
- hum.showNotification(entry)
-
- val removedImmediately =
- hum.removeNotification(
- entry.key,
- /* releaseImmediately = */ false,
- "beforeMinimumDisplayTime",
- )
- assertThat(removedImmediately).isFalse()
- assertThat(hum.isHeadsUpEntry(entry.key)).isTrue()
-
- systemClock.advanceTime(((TEST_MINIMUM_DISPLAY_TIME + TEST_AUTO_DISMISS_TIME) / 2).toLong())
-
- assertThat(hum.isHeadsUpEntry(entry.key)).isFalse()
- }
-
- @Test
- fun testRemoveNotification_afterMinimumDisplayTime() {
- val hum = createHeadsUpManager()
- val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
- useAccessibilityTimeout(false)
-
- hum.showNotification(entry)
- systemClock.advanceTime(((TEST_MINIMUM_DISPLAY_TIME + TEST_AUTO_DISMISS_TIME) / 2).toLong())
-
- assertThat(hum.isHeadsUpEntry(entry.key)).isTrue()
-
- val removedImmediately =
- hum.removeNotification(
- entry.key,
- /* releaseImmediately = */ false,
- "afterMinimumDisplayTime",
- )
- assertThat(removedImmediately).isTrue()
- assertThat(hum.isHeadsUpEntry(entry.key)).isFalse()
- }
-
- @Test
- fun testRemoveNotification_releaseImmediately() {
- val hum = createHeadsUpManager()
- val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-
- hum.showNotification(entry)
-
- val removedImmediately =
- hum.removeNotification(
- entry.key,
- /* releaseImmediately = */ true,
- "afterMinimumDisplayTime",
- )
- assertThat(removedImmediately).isTrue()
- assertThat(hum.isHeadsUpEntry(entry.key)).isFalse()
- }
-
- @Test
- fun testIsSticky_rowPinnedAndExpanded_true() {
- val hum = createHeadsUpManager()
- val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
- Mockito.`when`(mRow!!.isPinned).thenReturn(true)
- notifEntry.row = mRow
-
- hum.showNotification(notifEntry)
-
- val headsUpEntry = hum.getHeadsUpEntry(notifEntry.key)
- headsUpEntry!!.setExpanded(true)
-
- assertThat(hum.isSticky(notifEntry.key)).isTrue()
- }
-
- @Test
- fun testIsSticky_remoteInputActive_true() {
- val hum = createHeadsUpManager()
- val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-
- hum.showNotification(notifEntry)
-
- val headsUpEntry = hum.getHeadsUpEntry(notifEntry.key)
- headsUpEntry!!.mRemoteInputActive = true
-
- assertThat(hum.isSticky(notifEntry.key)).isTrue()
- }
-
- @Test
- fun testIsSticky_hasFullScreenIntent_true() {
- val hum = createHeadsUpManager()
- val notifEntry = HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id= */ 0, mContext)
-
- hum.showNotification(notifEntry)
-
- assertThat(hum.isSticky(notifEntry.key)).isTrue()
- }
-
- @Test
- fun testIsSticky_stickyForSomeTime_false() {
- val hum = createHeadsUpManager()
- val entry = createStickyForSomeTimeEntry(/* id= */ 0)
-
- hum.showNotification(entry)
-
- assertThat(hum.isSticky(entry.key)).isFalse()
- }
-
- @Test
- fun testIsSticky_false() {
- val hum = createHeadsUpManager()
- val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-
- hum.showNotification(notifEntry)
-
- val headsUpEntry = hum.getHeadsUpEntry(notifEntry.key)
- headsUpEntry!!.setExpanded(false)
- headsUpEntry.mRemoteInputActive = false
-
- assertThat(hum.isSticky(notifEntry.key)).isFalse()
- }
-
- @Test
- fun testCompareTo_withNullEntries() {
- val hum = createHeadsUpManager()
- val alertEntry = NotificationEntryBuilder().setTag("alert").build()
-
- hum.showNotification(alertEntry)
-
- assertThat(hum.compare(alertEntry, null)).isLessThan(0)
- assertThat(hum.compare(null, alertEntry)).isGreaterThan(0)
- assertThat(hum.compare(null, null)).isEqualTo(0)
- }
-
- @Test
- fun testCompareTo_withNonAlertEntries() {
- val hum = createHeadsUpManager()
-
- val nonAlertEntry1 = NotificationEntryBuilder().setTag("nae1").build()
- val nonAlertEntry2 = NotificationEntryBuilder().setTag("nae2").build()
- val alertEntry = NotificationEntryBuilder().setTag("alert").build()
- hum.showNotification(alertEntry)
-
- assertThat(hum.compare(alertEntry, nonAlertEntry1)).isLessThan(0)
- assertThat(hum.compare(nonAlertEntry1, alertEntry)).isGreaterThan(0)
- assertThat(hum.compare(nonAlertEntry1, nonAlertEntry2)).isEqualTo(0)
- }
-
- @Test
- fun testAlertEntryCompareTo_ongoingCallLessThanActiveRemoteInput() {
- val hum = createHeadsUpManager()
-
- val ongoingCall =
- hum.HeadsUpEntry(
- NotificationEntryBuilder()
- .setSbn(
- HeadsUpManagerTestUtil.createSbn(
- /* id = */ 0,
- Notification.Builder(mContext, "")
- .setCategory(Notification.CATEGORY_CALL)
- .setOngoing(true),
- )
- )
- .build()
- )
-
- val activeRemoteInput =
- hum.HeadsUpEntry(HeadsUpManagerTestUtil.createEntry(/* id= */ 1, mContext))
- activeRemoteInput.mRemoteInputActive = true
-
- assertThat(ongoingCall.compareTo(activeRemoteInput)).isLessThan(0)
- assertThat(activeRemoteInput.compareTo(ongoingCall)).isGreaterThan(0)
- }
-
- @Test
- fun testAlertEntryCompareTo_incomingCallLessThanActiveRemoteInput() {
- val hum = createHeadsUpManager()
-
- val person = Person.Builder().setName("person").build()
- val intent = Mockito.mock(PendingIntent::class.java)
- val incomingCall =
- hum.HeadsUpEntry(
- NotificationEntryBuilder()
- .setSbn(
- HeadsUpManagerTestUtil.createSbn(
- /* id = */ 0,
- Notification.Builder(mContext, "")
- .setStyle(
- Notification.CallStyle.forIncomingCall(person, intent, intent)
- ),
- )
- )
- .build()
- )
-
- val activeRemoteInput =
- hum.HeadsUpEntry(HeadsUpManagerTestUtil.createEntry(/* id= */ 1, mContext))
- activeRemoteInput.mRemoteInputActive = true
-
- assertThat(incomingCall.compareTo(activeRemoteInput)).isLessThan(0)
- assertThat(activeRemoteInput.compareTo(incomingCall)).isGreaterThan(0)
- }
-
- @Test
- @EnableFlags(NotificationThrottleHun.FLAG_NAME)
- fun testPinEntry_logsPeek_throttleEnabled() {
- val hum = createHeadsUpManager()
-
- // Needs full screen intent in order to be pinned
- val entryToPin =
- hum.HeadsUpEntry(
- HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id= */ 0, mContext)
- )
-
- // Note: the standard way to show a notification would be calling showNotification rather
- // than onAlertEntryAdded. However, in practice showNotification in effect adds
- // the notification and then updates it; in order to not log twice, the entry needs
- // to have a functional ExpandableNotificationRow that can keep track of whether it's
- // pinned or not (via isRowPinned()). That feels like a lot to pull in to test this one bit.
- hum.onEntryAdded(entryToPin)
-
- assertThat(mUiEventLoggerFake.numLogs()).isEqualTo(2)
- assertThat(AvalancheController.ThrottleEvent.AVALANCHE_THROTTLING_HUN_SHOWN.getId())
- .isEqualTo(mUiEventLoggerFake.eventId(0))
- assertThat(HeadsUpManagerImpl.NotificationPeekEvent.NOTIFICATION_PEEK.id)
- .isEqualTo(mUiEventLoggerFake.eventId(1))
- }
-
- @Test
- @DisableFlags(NotificationThrottleHun.FLAG_NAME)
- fun testPinEntry_logsPeek_throttleDisabled() {
- val hum = createHeadsUpManager()
-
- // Needs full screen intent in order to be pinned
- val entryToPin =
- hum.HeadsUpEntry(
- HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id= */ 0, mContext)
- )
-
- // Note: the standard way to show a notification would be calling showNotification rather
- // than onAlertEntryAdded. However, in practice showNotification in effect adds
- // the notification and then updates it; in order to not log twice, the entry needs
- // to have a functional ExpandableNotificationRow that can keep track of whether it's
- // pinned or not (via isRowPinned()). That feels like a lot to pull in to test this one bit.
- hum.onEntryAdded(entryToPin)
-
- assertThat(mUiEventLoggerFake.numLogs()).isEqualTo(1)
- assertThat(HeadsUpManagerImpl.NotificationPeekEvent.NOTIFICATION_PEEK.id)
- .isEqualTo(mUiEventLoggerFake.eventId(0))
- }
-
- @Test
- fun testSetUserActionMayIndirectlyRemove() {
- val hum = createHeadsUpManager()
- val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
-
- hum.showNotification(notifEntry)
-
- assertThat(hum.canRemoveImmediately(notifEntry.key)).isFalse()
-
- hum.setUserActionMayIndirectlyRemove(notifEntry)
-
- assertThat(hum.canRemoveImmediately(notifEntry.key)).isTrue()
- }
-
- companion object {
- const val TEST_TOUCH_ACCEPTANCE_TIME: Int = 200
- const val TEST_A11Y_AUTO_DISMISS_TIME: Int = 1000
- const val TEST_EXTENSION_TIME = 500
-
- const val TEST_MINIMUM_DISPLAY_TIME: Int = 400
- const val TEST_AUTO_DISMISS_TIME: Int = 600
- const val TEST_STICKY_AUTO_DISMISS_TIME: Int = 800
-
- // Number of notifications to use in tests requiring multiple notifications
- private const val TEST_NUM_NOTIFICATIONS = 4
-
- init {
- Truth.assertThat(TEST_MINIMUM_DISPLAY_TIME).isLessThan(TEST_AUTO_DISMISS_TIME)
- Truth.assertThat(TEST_AUTO_DISMISS_TIME).isLessThan(TEST_STICKY_AUTO_DISMISS_TIME)
- Truth.assertThat(TEST_STICKY_AUTO_DISMISS_TIME).isLessThan(TEST_A11Y_AUTO_DISMISS_TIME)
- }
-
- @get:Parameters(name = "{0}")
- @JvmStatic
- val flags: List<FlagsParameterization>
- get() = FlagsParameterization.allCombinationsOf(NotificationThrottleHun.FLAG_NAME)
- }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt
index a5fecb8..8420c49 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt
@@ -15,25 +15,38 @@
*/
package com.android.systemui.statusbar.notification.headsup
+import android.app.Notification
+import android.app.PendingIntent
+import android.app.Person
import android.os.Handler
+import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
+import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
+import android.view.accessibility.accessibilityManager
import android.view.accessibility.accessibilityManagerWrapper
import androidx.test.filters.SmallTest
import com.android.internal.logging.uiEventLoggerFake
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.dump.dumpManager
+import com.android.systemui.flags.BrokenWithSceneContainer
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
-import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.res.R
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.shadeTestUtil
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.provider.visualStabilityProvider
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManagerImpl.HeadsUpEntry
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.NotificationTestHelper
import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
import com.android.systemui.statusbar.phone.keyguardBypassController
import com.android.systemui.statusbar.policy.configurationController
@@ -41,12 +54,19 @@
import com.android.systemui.testKosmos
import com.android.systemui.util.concurrency.mockExecutorHandler
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
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters
@@ -54,19 +74,26 @@
@SmallTest
@RunWith(ParameterizedAndroidJunit4::class)
@RunWithLooper
-class HeadsUpManagerImplTest(flags: FlagsParameterization) : HeadsUpManagerImplOldTest(flags) {
-
- private val headsUpManagerLogger = HeadsUpManagerLogger(logcatLogBuffer())
+class HeadsUpManagerImplTest(flags: FlagsParameterization) : SysuiTestCase() {
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
private val kosmos = testKosmos().useUnconfinedTestDispatcher()
private val testScope = kosmos.testScope
private val groupManager = mock<GroupMembershipManager>()
private val bgHandler = mock<Handler>()
+ private val headsUpManagerLogger = mock<HeadsUpManagerLogger>()
val statusBarStateController = kosmos.sysuiStatusBarStateController
+ private val globalSettings = kosmos.fakeGlobalSettings
+ private val systemClock = kosmos.fakeSystemClock
+ private val executor = kosmos.fakeExecutor
+ private val uiEventLoggerFake = kosmos.uiEventLoggerFake
private val javaAdapter: JavaAdapter = JavaAdapter(testScope.backgroundScope)
+ private lateinit var testHelper: NotificationTestHelper
private lateinit var avalancheController: AvalancheController
private lateinit var underTest: HeadsUpManagerImpl
@@ -90,12 +117,15 @@
)
}
+ allowTestableLooperAsMainThread()
+ testHelper = NotificationTestHelper(mContext, mDependency, TestableLooper.get(this))
+
whenever(kosmos.keyguardBypassController.bypassEnabled).thenReturn(false)
kosmos.visualStabilityProvider.isReorderingAllowed = true
avalancheController =
AvalancheController(
kosmos.dumpManager,
- kosmos.uiEventLoggerFake,
+ uiEventLoggerFake,
headsUpManagerLogger,
bgHandler,
)
@@ -113,7 +143,7 @@
systemClock,
executor,
kosmos.accessibilityManagerWrapper,
- kosmos.uiEventLoggerFake,
+ uiEventLoggerFake,
javaAdapter,
kosmos.shadeInteractor,
avalancheController,
@@ -121,6 +151,220 @@
}
@Test
+ fun testHasNotifications_headsUpManagerMapNotEmpty_true() {
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ underTest.showNotification(entry)
+
+ assertThat(underTest.mHeadsUpEntryMap).isNotEmpty()
+ assertThat(underTest.hasNotifications()).isTrue()
+ }
+
+ @Test
+ @EnableFlags(NotificationThrottleHun.FLAG_NAME)
+ fun testHasNotifications_avalancheMapNotEmpty_true() {
+ val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ val headsUpEntry = underTest.createHeadsUpEntry(notifEntry)
+ avalancheController.addToNext(headsUpEntry) {}
+
+ assertThat(avalancheController.getWaitingEntryList()).isNotEmpty()
+ assertThat(underTest.hasNotifications()).isTrue()
+ }
+
+ @Test
+ @EnableFlags(NotificationThrottleHun.FLAG_NAME)
+ fun testHasNotifications_false() {
+ assertThat(underTest.mHeadsUpEntryMap).isEmpty()
+ assertThat(avalancheController.getWaitingEntryList()).isEmpty()
+ assertThat(underTest.hasNotifications()).isFalse()
+ }
+
+ @Test
+ @EnableFlags(NotificationThrottleHun.FLAG_NAME)
+ fun testGetHeadsUpEntryList_includesAvalancheEntryList() {
+ val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ val headsUpEntry = underTest.createHeadsUpEntry(notifEntry)
+ avalancheController.addToNext(headsUpEntry) {}
+
+ assertThat(underTest.headsUpEntryList).contains(headsUpEntry)
+ }
+
+ @Test
+ @EnableFlags(NotificationThrottleHun.FLAG_NAME)
+ fun testGetHeadsUpEntry_returnsAvalancheEntry() {
+ val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ val headsUpEntry = underTest.createHeadsUpEntry(notifEntry)
+ avalancheController.addToNext(headsUpEntry) {}
+
+ assertThat(underTest.getHeadsUpEntry(notifEntry.key)).isEqualTo(headsUpEntry)
+ }
+
+ @Test
+ fun testShowNotification_addsEntry() {
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+ underTest.showNotification(entry)
+
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+ assertThat(underTest.hasNotifications()).isTrue()
+ assertThat(underTest.getEntry(entry.key)).isEqualTo(entry)
+ }
+
+ @Test
+ fun testShowNotification_autoDismisses() {
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+ underTest.showNotification(entry)
+ systemClock.advanceTime((TEST_AUTO_DISMISS_TIME * 3 / 2).toLong())
+
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isFalse()
+ }
+
+ @Test
+ fun testRemoveNotification_removeDeferred() {
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+ underTest.showNotification(entry)
+
+ val removedImmediately =
+ underTest.removeNotification(
+ entry.key,
+ /* releaseImmediately= */ false,
+ "removeDeferred",
+ )
+ assertThat(removedImmediately).isFalse()
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+ }
+
+ @Test
+ fun testRemoveNotification_forceRemove() {
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+ underTest.showNotification(entry)
+
+ val removedImmediately =
+ underTest.removeNotification(entry.key, /* releaseImmediately= */ true, "forceRemove")
+ assertThat(removedImmediately).isTrue()
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isFalse()
+ }
+
+ @Test
+ fun testReleaseAllImmediately() {
+ for (i in 0 until 4) {
+ val entry = HeadsUpManagerTestUtil.createEntry(i, mContext)
+ entry.row = mock<ExpandableNotificationRow>()
+ underTest.showNotification(entry)
+ }
+
+ underTest.releaseAllImmediately()
+
+ assertThat(underTest.allEntries.count()).isEqualTo(0)
+ }
+
+ @Test
+ fun testCanRemoveImmediately_notShownLongEnough() {
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+ underTest.showNotification(entry)
+
+ // The entry has just been added so we should not remove immediately.
+ assertThat(underTest.canRemoveImmediately(entry.key)).isFalse()
+ }
+
+ @Test
+ fun testHunRemovedLogging() {
+ val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ val headsUpEntry = underTest.HeadsUpEntry(notifEntry)
+ headsUpEntry.setRowPinnedStatus(PinnedStatus.NotPinned)
+
+ underTest.onEntryRemoved(headsUpEntry, "test")
+
+ verify(headsUpManagerLogger, times(1)).logNotificationActuallyRemoved(eq(notifEntry))
+ }
+
+ @Test
+ fun testShowNotification_autoDismissesIncludingTouchAcceptanceDelay() {
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ useAccessibilityTimeout(false)
+
+ underTest.showNotification(entry)
+ systemClock.advanceTime((TEST_TOUCH_ACCEPTANCE_TIME / 2 + TEST_AUTO_DISMISS_TIME).toLong())
+
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+ }
+
+ @Test
+ fun testShowNotification_autoDismissesWithDefaultTimeout() {
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ useAccessibilityTimeout(false)
+
+ underTest.showNotification(entry)
+ systemClock.advanceTime(
+ (TEST_TOUCH_ACCEPTANCE_TIME +
+ (TEST_AUTO_DISMISS_TIME + TEST_A11Y_AUTO_DISMISS_TIME) / 2)
+ .toLong()
+ )
+
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isFalse()
+ }
+
+ @Test
+ fun testRemoveNotification_beforeMinimumDisplayTime() {
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ useAccessibilityTimeout(false)
+
+ underTest.showNotification(entry)
+
+ val removedImmediately =
+ underTest.removeNotification(
+ entry.key,
+ /* releaseImmediately = */ false,
+ "beforeMinimumDisplayTime",
+ )
+ assertThat(removedImmediately).isFalse()
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+
+ systemClock.advanceTime(((TEST_MINIMUM_DISPLAY_TIME + TEST_AUTO_DISMISS_TIME) / 2).toLong())
+
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isFalse()
+ }
+
+ @Test
+ fun testRemoveNotification_afterMinimumDisplayTime() {
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ useAccessibilityTimeout(false)
+
+ underTest.showNotification(entry)
+ systemClock.advanceTime(((TEST_MINIMUM_DISPLAY_TIME + TEST_AUTO_DISMISS_TIME) / 2).toLong())
+
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+
+ val removedImmediately =
+ underTest.removeNotification(
+ entry.key,
+ /* releaseImmediately = */ false,
+ "afterMinimumDisplayTime",
+ )
+ assertThat(removedImmediately).isTrue()
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isFalse()
+ }
+
+ @Test
+ fun testRemoveNotification_releaseImmediately() {
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+ underTest.showNotification(entry)
+
+ val removedImmediately =
+ underTest.removeNotification(
+ entry.key,
+ /* releaseImmediately = */ true,
+ "afterMinimumDisplayTime",
+ )
+ assertThat(removedImmediately).isTrue()
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isFalse()
+ }
+
+ @Test
fun testSnooze() {
val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
underTest.showNotification(entry)
@@ -160,7 +404,7 @@
fun testCanRemoveImmediately_notTopEntry() {
val earlierEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
val laterEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 1, mContext)
- laterEntry.row = mRow
+ laterEntry.row = mock<ExpandableNotificationRow>()
underTest.showNotification(earlierEntry)
underTest.showNotification(laterEntry)
@@ -226,6 +470,122 @@
}
@Test
+ fun testShowNotification_sticky_neverAutoDismisses() {
+ val entry = createStickyEntry(id = 0)
+ useAccessibilityTimeout(false)
+
+ underTest.showNotification(entry)
+ systemClock.advanceTime(
+ (TEST_TOUCH_ACCEPTANCE_TIME + 2 * TEST_A11Y_AUTO_DISMISS_TIME).toLong()
+ )
+
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+ }
+
+ @Test
+ fun testShowNotification_autoDismissesWithAccessibilityTimeout() {
+ val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ useAccessibilityTimeout(true)
+
+ underTest.showNotification(entry)
+ systemClock.advanceTime(
+ (TEST_TOUCH_ACCEPTANCE_TIME +
+ (TEST_AUTO_DISMISS_TIME + TEST_A11Y_AUTO_DISMISS_TIME) / 2)
+ .toLong()
+ )
+
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+ }
+
+ @Test
+ fun testShowNotification_stickyForSomeTime_autoDismissesWithStickyTimeout() {
+ val entry = createStickyForSomeTimeEntry(id = 0)
+ useAccessibilityTimeout(false)
+
+ underTest.showNotification(entry)
+ systemClock.advanceTime(
+ (TEST_TOUCH_ACCEPTANCE_TIME +
+ (TEST_AUTO_DISMISS_TIME + TEST_STICKY_AUTO_DISMISS_TIME) / 2)
+ .toLong()
+ )
+
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+ }
+
+ @Test
+ fun testShowNotification_stickyForSomeTime_autoDismissesWithAccessibilityTimeout() {
+ val entry = createStickyForSomeTimeEntry(id = 0)
+ useAccessibilityTimeout(true)
+
+ underTest.showNotification(entry)
+ systemClock.advanceTime(
+ (TEST_TOUCH_ACCEPTANCE_TIME +
+ (TEST_STICKY_AUTO_DISMISS_TIME + TEST_A11Y_AUTO_DISMISS_TIME) / 2)
+ .toLong()
+ )
+
+ assertThat(underTest.isHeadsUpEntry(entry.key)).isTrue()
+ }
+
+ @Test
+ fun testIsSticky_rowPinnedAndExpanded_true() {
+ val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+ val row = testHelper.createRow()
+ row.setPinnedStatus(PinnedStatus.PinnedBySystem)
+ notifEntry.row = row
+
+ underTest.showNotification(notifEntry)
+
+ val headsUpEntry = underTest.getHeadsUpEntry(notifEntry.key)
+ headsUpEntry!!.setExpanded(true)
+
+ assertThat(underTest.isSticky(notifEntry.key)).isTrue()
+ }
+
+ @Test
+ fun testIsSticky_remoteInputActive_true() {
+ val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+ underTest.showNotification(notifEntry)
+
+ val headsUpEntry = underTest.getHeadsUpEntry(notifEntry.key)
+ headsUpEntry!!.mRemoteInputActive = true
+
+ assertThat(underTest.isSticky(notifEntry.key)).isTrue()
+ }
+
+ @Test
+ fun testIsSticky_hasFullScreenIntent_true() {
+ val notifEntry = HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id= */ 0, mContext)
+
+ underTest.showNotification(notifEntry)
+
+ assertThat(underTest.isSticky(notifEntry.key)).isTrue()
+ }
+
+ @Test
+ fun testIsSticky_stickyForSomeTime_false() {
+ val entry = createStickyForSomeTimeEntry(id = 0)
+
+ underTest.showNotification(entry)
+
+ assertThat(underTest.isSticky(entry.key)).isFalse()
+ }
+
+ @Test
+ fun testIsSticky_false() {
+ val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+ underTest.showNotification(notifEntry)
+
+ val headsUpEntry = underTest.getHeadsUpEntry(notifEntry.key)
+ headsUpEntry!!.setExpanded(false)
+ headsUpEntry.mRemoteInputActive = false
+
+ assertThat(underTest.isSticky(notifEntry.key)).isFalse()
+ }
+
+ @Test
fun testShouldHeadsUpBecomePinned_noFSI_false() =
kosmos.runTest {
statusBarStateController.setState(StatusBarState.KEYGUARD)
@@ -270,11 +630,13 @@
}
@Test
+ @BrokenWithSceneContainer(381869885) // because `ShadeTestUtil.setShadeExpansion(0f)`
+ // still causes `ShadeInteractor.isAnyExpanded` to emit `true`, when it should emit `false`.
fun shouldHeadsUpBecomePinned_shadeNotExpanded_true() =
kosmos.runTest {
// GIVEN
- shadeTestUtil.setShadeExpansion(0f)
- // TODO(b/381869885): Determine why we need both of these ShadeTestUtil calls.
+ // TODO(b/381869885): We should be able to use `ShadeTestUtil.setShadeExpansion(0f)`
+ // instead.
shadeTestUtil.setLegacyExpandedOrAwaitingInputTransfer(false)
val entry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
@@ -347,8 +709,183 @@
assertThat(underTest.shouldHeadsUpBecomePinned(entry)).isFalse()
}
+ @Test
+ fun testCompareTo_withNullEntries() {
+ val alertEntry = NotificationEntryBuilder().setTag("alert").build()
+
+ underTest.showNotification(alertEntry)
+
+ assertThat(underTest.compare(alertEntry, null)).isLessThan(0)
+ assertThat(underTest.compare(null, alertEntry)).isGreaterThan(0)
+ assertThat(underTest.compare(null, null)).isEqualTo(0)
+ }
+
+ @Test
+ fun testCompareTo_withNonAlertEntries() {
+ val nonAlertEntry1 = NotificationEntryBuilder().setTag("nae1").build()
+ val nonAlertEntry2 = NotificationEntryBuilder().setTag("nae2").build()
+ val alertEntry = NotificationEntryBuilder().setTag("alert").build()
+ underTest.showNotification(alertEntry)
+
+ assertThat(underTest.compare(alertEntry, nonAlertEntry1)).isLessThan(0)
+ assertThat(underTest.compare(nonAlertEntry1, alertEntry)).isGreaterThan(0)
+ assertThat(underTest.compare(nonAlertEntry1, nonAlertEntry2)).isEqualTo(0)
+ }
+
+ @Test
+ fun testAlertEntryCompareTo_ongoingCallLessThanActiveRemoteInput() {
+ val ongoingCall =
+ underTest.HeadsUpEntry(
+ NotificationEntryBuilder()
+ .setSbn(
+ HeadsUpManagerTestUtil.createSbn(
+ /* id = */ 0,
+ Notification.Builder(mContext, "")
+ .setCategory(Notification.CATEGORY_CALL)
+ .setOngoing(true),
+ )
+ )
+ .build()
+ )
+
+ val activeRemoteInput =
+ underTest.HeadsUpEntry(HeadsUpManagerTestUtil.createEntry(/* id= */ 1, mContext))
+ activeRemoteInput.mRemoteInputActive = true
+
+ assertThat(ongoingCall.compareTo(activeRemoteInput)).isLessThan(0)
+ assertThat(activeRemoteInput.compareTo(ongoingCall)).isGreaterThan(0)
+ }
+
+ @Test
+ fun testAlertEntryCompareTo_incomingCallLessThanActiveRemoteInput() {
+ val person = Person.Builder().setName("person").build()
+ val intent = mock<PendingIntent>()
+ val incomingCall =
+ underTest.HeadsUpEntry(
+ NotificationEntryBuilder()
+ .setSbn(
+ HeadsUpManagerTestUtil.createSbn(
+ /* id = */ 0,
+ Notification.Builder(mContext, "")
+ .setStyle(
+ Notification.CallStyle.forIncomingCall(person, intent, intent)
+ ),
+ )
+ )
+ .build()
+ )
+
+ val activeRemoteInput =
+ underTest.HeadsUpEntry(HeadsUpManagerTestUtil.createEntry(/* id= */ 1, mContext))
+ activeRemoteInput.mRemoteInputActive = true
+
+ assertThat(incomingCall.compareTo(activeRemoteInput)).isLessThan(0)
+ assertThat(activeRemoteInput.compareTo(incomingCall)).isGreaterThan(0)
+ }
+
+ @Test
+ @EnableFlags(NotificationThrottleHun.FLAG_NAME)
+ fun testPinEntry_logsPeek_throttleEnabled() {
+ // Needs full screen intent in order to be pinned
+ val entryToPin =
+ underTest.HeadsUpEntry(
+ HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id= */ 0, mContext)
+ )
+
+ // Note: the standard way to show a notification would be calling showNotification rather
+ // than onAlertEntryAdded. However, in practice showNotification in effect adds
+ // the notification and then updates it; in order to not log twice, the entry needs
+ // to have a functional ExpandableNotificationRow that can keep track of whether it's
+ // pinned or not (via isRowPinned()). That feels like a lot to pull in to test this one bit.
+ underTest.onEntryAdded(entryToPin)
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
+ assertThat(AvalancheController.ThrottleEvent.AVALANCHE_THROTTLING_HUN_SHOWN.getId())
+ .isEqualTo(uiEventLoggerFake.eventId(0))
+ assertThat(HeadsUpManagerImpl.NotificationPeekEvent.NOTIFICATION_PEEK.id)
+ .isEqualTo(uiEventLoggerFake.eventId(1))
+ }
+
+ @Test
+ @DisableFlags(NotificationThrottleHun.FLAG_NAME)
+ fun testPinEntry_logsPeek_throttleDisabled() {
+ // Needs full screen intent in order to be pinned
+ val entryToPin =
+ underTest.HeadsUpEntry(
+ HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id= */ 0, mContext)
+ )
+
+ // Note: the standard way to show a notification would be calling showNotification rather
+ // than onAlertEntryAdded. However, in practice showNotification in effect adds
+ // the notification and then updates it; in order to not log twice, the entry needs
+ // to have a functional ExpandableNotificationRow that can keep track of whether it's
+ // pinned or not (via isRowPinned()). That feels like a lot to pull in to test this one bit.
+ underTest.onEntryAdded(entryToPin)
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(HeadsUpManagerImpl.NotificationPeekEvent.NOTIFICATION_PEEK.id)
+ .isEqualTo(uiEventLoggerFake.eventId(0))
+ }
+
+ @Test
+ fun testSetUserActionMayIndirectlyRemove() {
+ val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
+
+ underTest.showNotification(notifEntry)
+
+ assertThat(underTest.canRemoveImmediately(notifEntry.key)).isFalse()
+
+ underTest.setUserActionMayIndirectlyRemove(notifEntry)
+
+ assertThat(underTest.canRemoveImmediately(notifEntry.key)).isTrue()
+ }
+
+ private fun createStickyEntry(id: Int): NotificationEntry {
+ val notif =
+ Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .setFullScreenIntent(mock<PendingIntent>(), /* highPriority= */ true)
+ .build()
+ return HeadsUpManagerTestUtil.createEntry(id, notif)
+ }
+
+ private fun createStickyForSomeTimeEntry(id: Int): NotificationEntry {
+ val notif =
+ Notification.Builder(mContext, "")
+ .setSmallIcon(R.drawable.ic_person)
+ .setFlag(Notification.FLAG_FSI_REQUESTED_BUT_DENIED, true)
+ .build()
+ return HeadsUpManagerTestUtil.createEntry(id, notif)
+ }
+
+ private fun useAccessibilityTimeout(use: Boolean) {
+ if (use) {
+ whenever(kosmos.accessibilityManager.getRecommendedTimeoutMillis(any(), any()))
+ .thenReturn(TEST_A11Y_AUTO_DISMISS_TIME)
+ } else {
+ doAnswer { it.getArgument(0) as Int }
+ .whenever(kosmos.accessibilityManager)
+ .getRecommendedTimeoutMillis(any(), any())
+ }
+ }
+
companion object {
+ const val TEST_TOUCH_ACCEPTANCE_TIME = 200
+ const val TEST_A11Y_AUTO_DISMISS_TIME = 1000
+ const val TEST_EXTENSION_TIME = 500
+
+ const val TEST_MINIMUM_DISPLAY_TIME = 400
+ const val TEST_AUTO_DISMISS_TIME = 600
+ const val TEST_STICKY_AUTO_DISMISS_TIME = 800
+
+ init {
+ assertThat(TEST_MINIMUM_DISPLAY_TIME).isLessThan(TEST_AUTO_DISMISS_TIME)
+ assertThat(TEST_AUTO_DISMISS_TIME).isLessThan(TEST_STICKY_AUTO_DISMISS_TIME)
+ assertThat(TEST_STICKY_AUTO_DISMISS_TIME).isLessThan(TEST_A11Y_AUTO_DISMISS_TIME)
+ }
+
@get:Parameters(name = "{0}")
+ @JvmStatic
val flags: List<FlagsParameterization>
get() = buildList {
addAll(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
index 9f98fd4..5a5ec90 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
@@ -21,9 +21,8 @@
import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.settingslib.Utils
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
import com.android.systemui.statusbar.notification.FakeShadowView
import com.android.systemui.statusbar.notification.NotificationUtils
import com.android.systemui.statusbar.notification.SourceType
@@ -62,8 +61,8 @@
} as T?
}
- mNormalColor = Utils.getColorAttrDefaultColor(mContext,
- com.android.internal.R.attr.materialColorSurfaceContainerHigh)
+ mNormalColor =
+ mContext.getColor(com.android.internal.R.color.materialColorSurfaceContainerHigh)
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index f76f1ce..7f139bd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
@@ -30,6 +30,8 @@
import android.os.PowerManager;
import android.os.UserHandle;
import android.os.Vibrator;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.view.HapticFeedbackConstants;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -45,6 +47,8 @@
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.QSPanelController;
+import com.android.systemui.qs.flags.QSComposeFragment;
import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.CameraLauncher;
@@ -54,15 +58,14 @@
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
import com.android.systemui.shade.domain.interactor.ShadeInteractor;
+import com.android.systemui.shade.shared.flag.DualShade;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
-import dagger.Lazy;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -72,6 +75,8 @@
import java.util.Optional;
+import dagger.Lazy;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
@@ -105,6 +110,7 @@
@Mock private ActivityStarter mActivityStarter;
@Mock private EmergencyGestureIntentFactory mEmergencyGestureIntentFactory;
@Mock private KeyguardInteractor mKeyguardInteractor;
+ @Mock private QSPanelController mQSPanelController;
CentralSurfacesCommandQueueCallbacks mSbcqCallbacks;
@@ -150,6 +156,7 @@
when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
when(mRemoteInputQuickSettingsDisabler.adjustDisableFlags(anyInt()))
.thenAnswer((Answer<Integer>) invocation -> invocation.getArgument(0));
+ when(mCentralSurfaces.getQSPanelController()).thenReturn(mQSPanelController);
}
@Test
@@ -230,4 +237,45 @@
verify(mQSHost).addTile(c, false);
}
+
+ @Test
+ @DisableFlags(value = {QSComposeFragment.FLAG_NAME, DualShade.FLAG_NAME})
+ public void clickQsTile_flagsDisabled_callsQSPanelController() {
+ ComponentName c = new ComponentName("testpkg", "testcls");
+
+ mSbcqCallbacks.clickTile(c);
+ verify(mQSPanelController).clickTile(c);
+ }
+
+ @Test
+ @DisableFlags(DualShade.FLAG_NAME)
+ @EnableFlags(QSComposeFragment.FLAG_NAME)
+ public void clickQsTile_onlyQSComposeFlag_callsQSHost() {
+ ComponentName c = new ComponentName("testpkg", "testcls");
+
+ mSbcqCallbacks.clickTile(c);
+ verify(mQSPanelController, never()).clickTile(c);
+ verify(mQSHost).clickTile(c);
+ }
+
+ @Test
+ @EnableFlags(DualShade.FLAG_NAME)
+ @DisableFlags(QSComposeFragment.FLAG_NAME)
+ public void clickQsTile_onlyDualShadeFlag_callsQSHost() {
+ ComponentName c = new ComponentName("testpkg", "testcls");
+
+ mSbcqCallbacks.clickTile(c);
+ verify(mQSPanelController, never()).clickTile(c);
+ verify(mQSHost).clickTile(c);
+ }
+
+ @Test
+ @EnableFlags(value = {QSComposeFragment.FLAG_NAME, DualShade.FLAG_NAME})
+ public void clickQsTile_qsComposeAndDualShadeFlags_callsQSHost() {
+ ComponentName c = new ComponentName("testpkg", "testcls");
+
+ mSbcqCallbacks.clickTile(c);
+ verify(mQSPanelController, never()).clickTile(c);
+ verify(mQSHost).clickTile(c);
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
index c0a206a..9ad2315 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
@@ -49,11 +49,7 @@
private val dispatcher = StandardTestDispatcher()
private val testScope = TestScope(dispatcher)
- private val iconsInteractor =
- FakeMobileIconsInteractor(
- FakeMobileMappingsProxy(),
- mock(),
- )
+ private val iconsInteractor = FakeMobileIconsInteractor(FakeMobileMappingsProxy(), mock())
private val repo = FakeDeviceBasedSatelliteRepository()
private val connectivityRepository = FakeConnectivityRepository()
@@ -515,7 +511,7 @@
// GIVEN, 2 connection
val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
- val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+ val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(2)
// WHEN all connections are NOT OOS.
i1.isInService.value = true
@@ -547,7 +543,7 @@
// GIVEN a condition that should return true (all conections OOS)
val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
- val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+ val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(2)
i1.isInService.value = true
i2.isInService.value = true
@@ -579,4 +575,40 @@
// THEN the interactor returns true due to the wifi network being active
assertThat(latest).isTrue()
}
+
+ @Test
+ @EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ fun isAnyConnectionNtn_trueWhenAnyNtn() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.isAnyConnectionNtn)
+
+ // GIVEN, 2 connection
+ val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+ val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(2)
+
+ // WHEN at least one connection is using ntn
+ i1.isNonTerrestrial.value = true
+ i2.isNonTerrestrial.value = false
+
+ // THEN the value is propagated to this interactor
+ assertThat(latest).isTrue()
+ }
+
+ @Test
+ @EnableFlags(FLAG_OEM_ENABLED_SATELLITE_FLAG)
+ fun isAnyConnectionNtn_falseWhenNoNtn() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.isAnyConnectionNtn)
+
+ // GIVEN, 2 connection
+ val i1 = iconsInteractor.getMobileConnectionInteractorForSubId(1)
+ val i2 = iconsInteractor.getMobileConnectionInteractorForSubId(2)
+
+ // WHEN at no connection is using ntn
+ i1.isNonTerrestrial.value = false
+ i2.isNonTerrestrial.value = false
+
+ // THEN the value is propagated to this interactor
+ assertThat(latest).isFalse()
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
index 509aa7a..fe5b56a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
@@ -327,10 +327,11 @@
// GIVEN satellite is allowed
repo.isSatelliteAllowedForCurrentLocation.value = true
- // GIVEN all icons are OOS
+ // GIVEN all icons are OOS and not ntn
val i1 = mobileIconsInteractor.getMobileConnectionInteractorForSubId(1)
i1.isInService.value = false
i1.isEmergencyOnly.value = false
+ i1.isNonTerrestrial.value = false
// GIVEN apm is disabled
airplaneModeRepository.setIsAirplaneMode(false)
@@ -344,6 +345,29 @@
}
@Test
+ fun icon_nullWhenConnected_mobileNtnConnectionExists() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.icon)
+
+ // GIVEN satellite is allowed
+ repo.isSatelliteAllowedForCurrentLocation.value = true
+
+ // GIVEN ntn connection exists
+ val i1 = mobileIconsInteractor.getMobileConnectionInteractorForSubId(1)
+ i1.isNonTerrestrial.value = true
+
+ // GIVEN apm is disabled
+ airplaneModeRepository.setIsAirplaneMode(false)
+
+ // GIVEN satellite reports that it is Connected
+ repo.connectionState.value = SatelliteConnectionState.On
+
+ // THEN icon is null because despite being connected, the mobile stack is reporting a
+ // nonTerrestrial network, and therefore will have its own icon
+ assertThat(latest).isNull()
+ }
+
+ @Test
fun icon_satelliteIsProvisioned() =
testScope.runTest {
val latest by collectLastValue(underTest.icon)
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 9888574..a2ca12c 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
@@ -30,6 +30,7 @@
var listener: StatusBarVisibilityChangeListener? = null
override fun bind(
+ displayId: Int,
view: View,
viewModel: HomeStatusBarViewModel,
systemEventChipAnimateIn: ((View) -> Unit)?,
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
index dcb15a7..b2083c2 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
@@ -213,6 +213,13 @@
default int getCurrentCardTopPadding() {
throw new UnsupportedOperationException("Not implemented by " + getClass());
}
+
+ /**
+ * Set the horizontal paddings for applicable children inside the SmartspaceView.
+ */
+ default void setHorizontalPaddings(int horizontalPadding) {
+ throw new UnsupportedOperationException("Not implemented by " + getClass());
+ }
}
/** Interface for launching Intents, which can differ on the lockscreen */
diff --git a/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml b/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml
index 47641ee..4a14f3b 100644
--- a/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml
+++ b/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/materialColorSecondaryFixedDim"/>
+ <item android:color="@androidprv:color/materialColorSecondaryFixedDim"/>
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml b/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
index 5e7cf3e..6a885a7 100644
--- a/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
+++ b/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
@@ -19,7 +19,7 @@
android:color="?attr/wallpaperTextColorSecondary">
<item android:id="@android:id/background">
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorTertiaryFixed"/>
+ <solid android:color="@androidprv:color/materialColorTertiaryFixed"/>
<corners android:radius="24dp"/>
</shape>
</item>
diff --git a/packages/SystemUI/res-keyguard/drawable/progress_bar.xml b/packages/SystemUI/res-keyguard/drawable/progress_bar.xml
index 910a74a..455d9d3 100644
--- a/packages/SystemUI/res-keyguard/drawable/progress_bar.xml
+++ b/packages/SystemUI/res-keyguard/drawable/progress_bar.xml
@@ -26,7 +26,7 @@
android:layout_height="match_parent"
android:shape="rectangle">
<corners android:radius="30dp" />
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHighest" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHighest" />
</shape>
</item>
<item
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
index 83736e9..eb9ee03 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
@@ -27,8 +27,8 @@
android:background="@drawable/kg_bouncer_secondary_button"
android:drawablePadding="10dp"
android:drawableStart="@drawable/ic_no_sim"
- android:drawableTint="?androidprv:attr/materialColorOnSurface"
+ android:drawableTint="@androidprv:color/materialColorOnSurface"
android:text="@string/disable_carrier_button_text"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textSize="@dimen/kg_status_line_font_size"
android:visibility="gone" />
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index ba0d7de..bfb37a0d 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -110,6 +110,7 @@
<dimen name="below_clock_padding_start">32dp</dimen>
<dimen name="below_clock_padding_end">16dp</dimen>
<dimen name="below_clock_padding_start_icons">28dp</dimen>
+ <dimen name="smartspace_padding_horizontal">16dp</dimen>
<!-- Proportion of the screen height to use to set the maximum height of the bouncer to when
the device is in the DEVICE_POSTURE_HALF_OPENED posture, for the PIN/pattern entry. 0 will
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index da12dd7..b256518e 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -23,13 +23,13 @@
<style name="Keyguard.TextView" parent="@android:style/Widget.DeviceDefault.TextView">
<item name="android:textSize">@dimen/kg_status_line_font_size</item>
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="Keyguard.Bouncer.PrimaryMessage" parent="Theme.SystemUI">
<item name="android:textSize">18sp</item>
<item name="android:lineHeight">24dp</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:singleLine">true</item>
<item name="android:textAlignment">center</item>
<item name="android:ellipsize">marquee</item>
@@ -41,10 +41,10 @@
<item name="android:textAlignment">center</item>
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
<item name="android:ellipsize">end</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
</style>
<style name="Keyguard.TextView.EmergencyButton" parent="Theme.SystemUI">
- <item name="android:textColor">?androidprv:attr/materialColorOnTertiaryFixed</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnTertiaryFixed</item>
<item name="android:textSize">16sp</item>
<item name="android:background">@drawable/kg_emergency_button_background</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
diff --git a/packages/SystemUI/res/color/connected_network_primary_color.xml b/packages/SystemUI/res/color/connected_network_primary_color.xml
index f173c8d..920047a 100644
--- a/packages/SystemUI/res/color/connected_network_primary_color.xml
+++ b/packages/SystemUI/res/color/connected_network_primary_color.xml
@@ -16,5 +16,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/materialColorOnPrimaryContainer" />
+ <item android:color="@androidprv:color/materialColorOnPrimaryContainer" />
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/disconnected_network_primary_color.xml b/packages/SystemUI/res/color/disconnected_network_primary_color.xml
index 536bf78..f4b19a7 100644
--- a/packages/SystemUI/res/color/disconnected_network_primary_color.xml
+++ b/packages/SystemUI/res/color/disconnected_network_primary_color.xml
@@ -16,5 +16,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/materialColorPrimaryContainer" />
+ <item android:color="@androidprv:color/materialColorPrimaryContainer" />
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/menu_item_text.xml b/packages/SystemUI/res/color/menu_item_text.xml
index 0d05650..c1c9e2c1 100644
--- a/packages/SystemUI/res/color/menu_item_text.xml
+++ b/packages/SystemUI/res/color/menu_item_text.xml
@@ -17,8 +17,8 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:state_enabled="false"
- android:color="?androidprv:attr/materialColorOnSurface"
+ android:color="@androidprv:color/materialColorOnSurface"
android:alpha="0.38" />
- <item android:color="?androidprv:attr/materialColorOnSurface"/>
+ <item android:color="@androidprv:color/materialColorOnSurface"/>
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/notification_focus_overlay_color.xml b/packages/SystemUI/res/color/notification_focus_overlay_color.xml
index 6a3c7a1..5584363 100644
--- a/packages/SystemUI/res/color/notification_focus_overlay_color.xml
+++ b/packages/SystemUI/res/color/notification_focus_overlay_color.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:state_focused="true" android:color="?androidprv:attr/materialColorSecondary" />
+ <item android:state_focused="true" android:color="@androidprv:color/materialColorSecondary" />
<item android:color="@color/transparent" />
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/notification_guts_priority_button_bg_stroke.xml b/packages/SystemUI/res/color/notification_guts_priority_button_bg_stroke.xml
index d1b8a06..e0873b8 100644
--- a/packages/SystemUI/res/color/notification_guts_priority_button_bg_stroke.xml
+++ b/packages/SystemUI/res/color/notification_guts_priority_button_bg_stroke.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:state_selected="true"
- android:color="?androidprv:attr/materialColorOnSurfaceVariant" />
+ android:color="@androidprv:color/materialColorOnSurfaceVariant" />
<item android:color="@color/notification_guts_priority_button_bg_stroke_color" />
</selector>
diff --git a/packages/SystemUI/res/color/notification_guts_priority_contents.xml b/packages/SystemUI/res/color/notification_guts_priority_contents.xml
index cc8c25a..3b221e7 100644
--- a/packages/SystemUI/res/color/notification_guts_priority_contents.xml
+++ b/packages/SystemUI/res/color/notification_guts_priority_contents.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:state_selected="true"
- android:color="?androidprv:attr/materialColorOnSurfaceVariant" />
+ android:color="@androidprv:color/materialColorOnSurfaceVariant" />
<item android:color="@color/notification_guts_priority_button_content_color" />
</selector>
diff --git a/packages/SystemUI/res/color/notification_state_color_default.xml b/packages/SystemUI/res/color/notification_state_color_default.xml
index a14a7ad..9d77f60 100644
--- a/packages/SystemUI/res/color/notification_state_color_default.xml
+++ b/packages/SystemUI/res/color/notification_state_color_default.xml
@@ -19,7 +19,7 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<!-- Pressed state's alpha is set to 0.00 temporarily until this bug is resolved permanently
b/313920497 Design intended alpha is 0.15-->
- <item android:state_pressed="true" android:color="?androidprv:attr/materialColorOnSurface" android:alpha="0.00" />
- <item android:state_hovered="true" android:color="?androidprv:attr/materialColorOnSurface" android:alpha="0.11" />
+ <item android:state_pressed="true" android:color="@androidprv:color/materialColorOnSurface" android:alpha="0.00" />
+ <item android:state_hovered="true" android:color="@androidprv:color/materialColorOnSurface" android:alpha="0.11" />
<item android:color="@color/transparent" />
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_dialog_btn_filled_background.xml b/packages/SystemUI/res/color/qs_dialog_btn_filled_background.xml
index 40bab5e..898d589 100644
--- a/packages/SystemUI/res/color/qs_dialog_btn_filled_background.xml
+++ b/packages/SystemUI/res/color/qs_dialog_btn_filled_background.xml
@@ -17,7 +17,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:state_enabled="false"
- android:color="?androidprv:attr/materialColorPrimary"
+ android:color="@androidprv:color/materialColorPrimary"
android:alpha="0.30"/>
- <item android:color="?androidprv:attr/materialColorPrimary"/>
+ <item android:color="@androidprv:color/materialColorPrimary"/>
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_dialog_btn_filled_large_background.xml b/packages/SystemUI/res/color/qs_dialog_btn_filled_large_background.xml
index f8d4af5..c8ab4ad 100644
--- a/packages/SystemUI/res/color/qs_dialog_btn_filled_large_background.xml
+++ b/packages/SystemUI/res/color/qs_dialog_btn_filled_large_background.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:state_enabled="false"
- android:color="?androidprv:attr/materialColorPrimaryFixed"
+ android:color="@androidprv:color/materialColorPrimaryFixed"
android:alpha="0.30"/>
- <item android:color="?androidprv:attr/materialColorPrimaryFixed"/>
+ <item android:color="@androidprv:color/materialColorPrimaryFixed"/>
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_dialog_btn_filled_large_text.xml b/packages/SystemUI/res/color/qs_dialog_btn_filled_large_text.xml
index faba8fc..60b6245 100644
--- a/packages/SystemUI/res/color/qs_dialog_btn_filled_large_text.xml
+++ b/packages/SystemUI/res/color/qs_dialog_btn_filled_large_text.xml
@@ -16,7 +16,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:state_enabled="false"
- android:color="?androidprv:attr/materialColorOnPrimaryFixed"
+ android:color="@androidprv:color/materialColorOnPrimaryFixed"
android:alpha="0.30"/>
- <item android:color="?androidprv:attr/materialColorOnPrimaryFixed"/>
+ <item android:color="@androidprv:color/materialColorOnPrimaryFixed"/>
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_dialog_btn_filled_text_color.xml b/packages/SystemUI/res/color/qs_dialog_btn_filled_text_color.xml
index e76ad99..a5497a54 100644
--- a/packages/SystemUI/res/color/qs_dialog_btn_filled_text_color.xml
+++ b/packages/SystemUI/res/color/qs_dialog_btn_filled_text_color.xml
@@ -17,7 +17,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:state_enabled="false"
- android:color="?androidprv:attr/materialColorOnPrimary"
+ android:color="@androidprv:color/materialColorOnPrimary"
android:alpha="0.30"/>
- <item android:color="?androidprv:attr/materialColorOnPrimary"/>
+ <item android:color="@androidprv:color/materialColorOnPrimary"/>
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_dialog_btn_outline.xml b/packages/SystemUI/res/color/qs_dialog_btn_outline.xml
index 1adfe5b..7ef7e06 100644
--- a/packages/SystemUI/res/color/qs_dialog_btn_outline.xml
+++ b/packages/SystemUI/res/color/qs_dialog_btn_outline.xml
@@ -17,7 +17,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:state_enabled="false"
- android:color="?androidprv:attr/materialColorPrimary"
+ android:color="@androidprv:color/materialColorPrimary"
android:alpha="0.30"/>
- <item android:color="?androidprv:attr/materialColorPrimary"/>
+ <item android:color="@androidprv:color/materialColorPrimary"/>
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/qs_dialog_btn_outline_text.xml b/packages/SystemUI/res/color/qs_dialog_btn_outline_text.xml
index 5dc994f23..f139008 100644
--- a/packages/SystemUI/res/color/qs_dialog_btn_outline_text.xml
+++ b/packages/SystemUI/res/color/qs_dialog_btn_outline_text.xml
@@ -17,7 +17,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:state_enabled="false"
- android:color="?androidprv:attr/materialColorOnSurface"
+ android:color="@androidprv:color/materialColorOnSurface"
android:alpha="0.30"/>
- <item android:color="?androidprv:attr/materialColorOnSurface"/>
+ <item android:color="@androidprv:color/materialColorOnSurface"/>
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/remote_input_hint.xml b/packages/SystemUI/res/color/remote_input_hint.xml
index 0d90ee6..75d2bb8 100644
--- a/packages/SystemUI/res/color/remote_input_hint.xml
+++ b/packages/SystemUI/res/color/remote_input_hint.xml
@@ -16,5 +16,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/materialColorOnSurfaceVariant" android:alpha=".6" />
+ <item android:color="@androidprv:color/materialColorOnSurfaceVariant" android:alpha=".6" />
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/remote_input_send.xml b/packages/SystemUI/res/color/remote_input_send.xml
index 0acc66b..4c61c0c 100644
--- a/packages/SystemUI/res/color/remote_input_send.xml
+++ b/packages/SystemUI/res/color/remote_input_send.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:state_enabled="false" android:color="?androidprv:attr/materialColorPrimary" android:alpha=".3" />
- <item android:color="?androidprv:attr/materialColorPrimary" />
+ <item android:state_enabled="false" android:color="@androidprv:color/materialColorPrimary" android:alpha=".3" />
+ <item android:color="@androidprv:color/materialColorPrimary" />
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/remote_input_text.xml b/packages/SystemUI/res/color/remote_input_text.xml
index bf2c198..2ec09cd 100644
--- a/packages/SystemUI/res/color/remote_input_text.xml
+++ b/packages/SystemUI/res/color/remote_input_text.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:state_enabled="false" android:color="?androidprv:attr/materialColorOnSurfaceVariant" android:alpha=".6" />
- <item android:color="?androidprv:attr/materialColorOnSurfaceVariant" />
+ <item android:state_enabled="false" android:color="@androidprv:color/materialColorOnSurfaceVariant" android:alpha=".6" />
+ <item android:color="@androidprv:color/materialColorOnSurfaceVariant" />
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/screenshare_options_spinner_background.xml b/packages/SystemUI/res/color/screenshare_options_spinner_background.xml
index 922813dc..f3059f6 100644
--- a/packages/SystemUI/res/color/screenshare_options_spinner_background.xml
+++ b/packages/SystemUI/res/color/screenshare_options_spinner_background.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:state_hovered="false" android:state_focused="false" android:color="@android:color/transparent" />
- <item android:state_focused="true" android:color="?androidprv:attr/materialColorOnSurface" android:alpha=".1" />
- <item android:state_hovered="true" android:color="?androidprv:attr/materialColorOnSurface" android:alpha=".08" />
+ <item android:state_focused="true" android:color="@androidprv:color/materialColorOnSurface" android:alpha=".1" />
+ <item android:state_hovered="true" android:color="@androidprv:color/materialColorOnSurface" android:alpha=".08" />
</selector>
diff --git a/packages/SystemUI/res/color/slider_active_track_color.xml b/packages/SystemUI/res/color/slider_active_track_color.xml
index a5aa58d..8ba5e49 100644
--- a/packages/SystemUI/res/color/slider_active_track_color.xml
+++ b/packages/SystemUI/res/color/slider_active_track_color.xml
@@ -14,6 +14,6 @@
~ limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/materialColorPrimary" android:state_enabled="true" />
- <item android:color="?androidprv:attr/materialColorSurfaceContainerHighest" />
+ <item android:color="@androidprv:color/materialColorPrimary" android:state_enabled="true" />
+ <item android:color="@androidprv:color/materialColorSurfaceContainerHighest" />
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/slider_inactive_track_color.xml b/packages/SystemUI/res/color/slider_inactive_track_color.xml
index 89aef77..7980f80 100644
--- a/packages/SystemUI/res/color/slider_inactive_track_color.xml
+++ b/packages/SystemUI/res/color/slider_inactive_track_color.xml
@@ -14,6 +14,6 @@
~ limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/materialColorSurfaceContainerHighest" android:state_enabled="true" />
- <item android:color="?androidprv:attr/materialColorPrimary" />
+ <item android:color="@androidprv:color/materialColorSurfaceContainerHighest" android:state_enabled="true" />
+ <item android:color="@androidprv:color/materialColorPrimary" />
</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/slider_thumb_color.xml b/packages/SystemUI/res/color/slider_thumb_color.xml
index 5206049..8a98902 100644
--- a/packages/SystemUI/res/color/slider_thumb_color.xml
+++ b/packages/SystemUI/res/color/slider_thumb_color.xml
@@ -15,6 +15,6 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/materialColorSurfaceContainerHighest" android:state_enabled="false" />
- <item android:color="?androidprv:attr/materialColorPrimary" />
+ <item android:color="@androidprv:color/materialColorSurfaceContainerHighest" android:state_enabled="false" />
+ <item android:color="@androidprv:color/materialColorPrimary" />
</selector>
diff --git a/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_down.xml b/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_down.xml
index 16076b1..d54164b 100644
--- a/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_down.xml
+++ b/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_down.xml
@@ -24,8 +24,8 @@
android:viewportHeight="24">
<path
android:pathData="M0,12C0,5.373 5.373,0 12,0C18.627,0 24,5.373 24,12C24,18.627 18.627,24 12,24C5.373,24 0,18.627 0,12Z"
- android:fillColor="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+ android:fillColor="@androidprv:color/materialColorSurfaceContainerHigh"/>
<path
android:pathData="M7.607,9.059L6.667,9.999L12,15.332L17.333,9.999L16.393,9.059L12,13.445"
- android:fillColor="?androidprv:attr/materialColorOnSurface"/>
+ android:fillColor="@androidprv:color/materialColorOnSurface"/>
</vector>
diff --git a/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_up.xml b/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_up.xml
index 309770d..81184a1 100644
--- a/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_up.xml
+++ b/packages/SystemUI/res/drawable-night/privacy_dialog_expand_toggle_up.xml
@@ -24,8 +24,8 @@
android:viewportHeight="24">
<path
android:pathData="M0,12C0,5.3726 5.3726,0 12,0C18.6274,0 24,5.3726 24,12C24,18.6274 18.6274,24 12,24C5.3726,24 0,18.6274 0,12Z"
- android:fillColor="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+ android:fillColor="@androidprv:color/materialColorSurfaceContainerHigh"/>
<path
android:pathData="M16.3934,14.9393L17.3334,13.9993L12.0001,8.666L6.6667,13.9993L7.6068,14.9393L12.0001,10.5527"
- android:fillColor="?androidprv:attr/materialColorOnSurface"/>
+ android:fillColor="@androidprv:color/materialColorOnSurface"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/action_chip_background.xml b/packages/SystemUI/res/drawable/action_chip_background.xml
index 9492472..0958c84 100644
--- a/packages/SystemUI/res/drawable/action_chip_background.xml
+++ b/packages/SystemUI/res/drawable/action_chip_background.xml
@@ -20,7 +20,7 @@
android:color="@color/overlay_button_ripple">
<item android:id="@android:id/background">
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSecondary"/>
+ <solid android:color="@androidprv:color/materialColorSecondary"/>
<corners android:radius="@dimen/overlay_button_corner_radius"/>
</shape>
</item>
diff --git a/packages/SystemUI/res/drawable/action_chip_container_background.xml b/packages/SystemUI/res/drawable/action_chip_container_background.xml
index 2ee2710..5aced9d 100644
--- a/packages/SystemUI/res/drawable/action_chip_container_background.xml
+++ b/packages/SystemUI/res/drawable/action_chip_container_background.xml
@@ -18,6 +18,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceBright"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceBright"/>
<corners android:radius="@dimen/overlay_action_container_corner_radius"/>
</shape>
diff --git a/packages/SystemUI/res/drawable/biometric_prompt_vertical_list_content_view_background.xml b/packages/SystemUI/res/drawable/biometric_prompt_vertical_list_content_view_background.xml
index fdafe6d..63d0268 100644
--- a/packages/SystemUI/res/drawable/biometric_prompt_vertical_list_content_view_background.xml
+++ b/packages/SystemUI/res/drawable/biometric_prompt_vertical_list_content_view_background.xml
@@ -18,6 +18,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh"/>
<corners android:radius="@dimen/biometric_prompt_content_corner_radius"/>
</shape>
diff --git a/packages/SystemUI/res/drawable/brightness_bar.xml b/packages/SystemUI/res/drawable/brightness_bar.xml
index 3d1c1fb..a32496b 100644
--- a/packages/SystemUI/res/drawable/brightness_bar.xml
+++ b/packages/SystemUI/res/drawable/brightness_bar.xml
@@ -21,7 +21,7 @@
android:viewportHeight="48">
<path
android:pathData="M2,22L302,22A2,2 0,0 1,304 24L304,24A2,2 0,0 1,302 26L2,26A2,2 0,0 1,0 24L0,24A2,2 0,0 1,2 22z"
- android:fillColor="?androidprv:attr/customColorShadeInactive"/>
+ android:fillColor="@androidprv:color/customColorShadeInactive"/>
<path
android:pathData="M24,0L205.71,0A24,24 0,0 1,229.71 24L229.71,24A24,24 0,0 1,205.71 48L24,48A24,24 0,0 1,0 24L0,24A24,24 0,0 1,24 0z"
android:fillColor="?attr/shadeActive"/>
diff --git a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
index ec15b10..88d3ecb 100644
--- a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
+++ b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
@@ -25,7 +25,7 @@
<shape>
<size android:height="@dimen/rounded_slider_track_width" />
<corners android:radius="@dimen/rounded_slider_track_corner_radius" />
- <solid android:color="?androidprv:attr/customColorShadeInactive" />
+ <solid android:color="@androidprv:color/customColorShadeInactive" />
</shape>
</inset>
</item>
diff --git a/packages/SystemUI/res/drawable/brightness_slider_focus_bg.xml b/packages/SystemUI/res/drawable/brightness_slider_focus_bg.xml
index 22406ec..5462898 100644
--- a/packages/SystemUI/res/drawable/brightness_slider_focus_bg.xml
+++ b/packages/SystemUI/res/drawable/brightness_slider_focus_bg.xml
@@ -22,7 +22,7 @@
<inset android:inset="-5dp">
<shape>
<corners android:radius="16dp"/>
- <stroke android:width="3dp" android:color="?androidprv:attr/materialColorSecondaryFixed"/>
+ <stroke android:width="3dp" android:color="@androidprv:color/materialColorSecondaryFixed"/>
</shape>
</inset>
</item>
diff --git a/packages/SystemUI/res/drawable/chipbar_background.xml b/packages/SystemUI/res/drawable/chipbar_background.xml
index 7530f5b..15c9fcb 100644
--- a/packages/SystemUI/res/drawable/chipbar_background.xml
+++ b/packages/SystemUI/res/drawable/chipbar_background.xml
@@ -17,6 +17,6 @@
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <solid android:color="?androidprv:attr/materialColorSecondaryFixed" />
+ <solid android:color="@androidprv:color/materialColorSecondaryFixed" />
<corners android:radius="32dp" />
</shape>
diff --git a/packages/SystemUI/res/drawable/chipbar_end_button_background.xml b/packages/SystemUI/res/drawable/chipbar_end_button_background.xml
index a3832ee..fcf5b30 100644
--- a/packages/SystemUI/res/drawable/chipbar_end_button_background.xml
+++ b/packages/SystemUI/res/drawable/chipbar_end_button_background.xml
@@ -20,7 +20,7 @@
android:color="?android:textColorPrimary">
<item android:id="@android:id/background">
<shape>
- <solid android:color="?androidprv:attr/materialColorPrimaryFixedDim"/>
+ <solid android:color="@androidprv:color/materialColorPrimaryFixedDim"/>
<corners android:radius="24dp" />
</shape>
</item>
diff --git a/packages/SystemUI/res/drawable/contextual_edu_dialog_bg.xml b/packages/SystemUI/res/drawable/contextual_edu_dialog_bg.xml
index d7000d7..b891163 100644
--- a/packages/SystemUI/res/drawable/contextual_edu_dialog_bg.xml
+++ b/packages/SystemUI/res/drawable/contextual_edu_dialog_bg.xml
@@ -19,6 +19,6 @@
android:insetBottom="@dimen/contextual_edu_dialog_elevation">
<shape>
<corners android:radius="28dp" />
- <solid android:color="?androidprv:attr/materialColorTertiaryFixed" />
+ <solid android:color="@androidprv:color/materialColorTertiaryFixed" />
</shape>
</inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/hearing_devices_spinner_popup_background.xml b/packages/SystemUI/res/drawable/hearing_devices_spinner_popup_background.xml
index f35975e..5ddc860 100644
--- a/packages/SystemUI/res/drawable/hearing_devices_spinner_popup_background.xml
+++ b/packages/SystemUI/res/drawable/hearing_devices_spinner_popup_background.xml
@@ -18,5 +18,5 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/hearing_devices_preset_spinner_background_radius"/>
- <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_check_circle_filled_24dp.xml b/packages/SystemUI/res/drawable/ic_check_circle_filled_24dp.xml
index 16e2a3d..307f7eb 100644
--- a/packages/SystemUI/res/drawable/ic_check_circle_filled_24dp.xml
+++ b/packages/SystemUI/res/drawable/ic_check_circle_filled_24dp.xml
@@ -18,7 +18,7 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:width="24dp"
android:height="24dp"
- android:tint="?androidprv:attr/materialColorPrimary"
+ android:tint="@androidprv:color/materialColorPrimary"
android:viewportHeight="24"
android:viewportWidth="24">
<path
diff --git a/packages/SystemUI/res/drawable/ic_circle_outline_24dp.xml b/packages/SystemUI/res/drawable/ic_circle_outline_24dp.xml
index 82fa4f0..8304fd5 100644
--- a/packages/SystemUI/res/drawable/ic_circle_outline_24dp.xml
+++ b/packages/SystemUI/res/drawable/ic_circle_outline_24dp.xml
@@ -18,7 +18,7 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:width="24dp"
android:height="24dp"
- android:tint="?androidprv:attr/materialColorPrimary"
+ android:tint="@androidprv:color/materialColorPrimary"
android:viewportHeight="24"
android:viewportWidth="24">
<path
diff --git a/packages/SystemUI/res/drawable/ic_screensaver_auto.xml b/packages/SystemUI/res/drawable/ic_screensaver_auto.xml
new file mode 100644
index 0000000..7cccff6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_screensaver_auto.xml
@@ -0,0 +1,26 @@
+<?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.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M160,240Q160,240 160,240Q160,240 160,240L160,720Q160,720 160,720Q160,720 160,720L160,720Q160,720 160,720Q160,720 160,720L160,240Q160,240 160,240Q160,240 160,240L160,240Q160,240 160,240Q160,240 160,240Q160,240 160,240Q160,240 160,240ZM160,800Q127,800 103.5,776.5Q80,753 80,720L80,240Q80,207 103.5,183.5Q127,160 160,160L440,160Q440,179 440,199Q440,219 440,240L160,240Q160,240 160,240Q160,240 160,240L160,720Q160,720 160,720Q160,720 160,720L800,720Q800,720 800,720Q800,720 800,720L800,480Q823,480 843,480Q863,480 880,480L880,720Q880,753 856.5,776.5Q833,800 800,800L160,800ZM700,480Q700,388 636,324Q572,260 480,260Q572,260 636,196Q700,132 700,40Q700,132 764,196Q828,260 920,260Q828,260 764,324Q700,388 700,480Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_shortcutlist_search.xml b/packages/SystemUI/res/drawable/ic_shortcutlist_search.xml
index 0406f0e..ddff884 100644
--- a/packages/SystemUI/res/drawable/ic_shortcutlist_search.xml
+++ b/packages/SystemUI/res/drawable/ic_shortcutlist_search.xml
@@ -19,7 +19,7 @@
android:height="24dp"
android:viewportWidth="48"
android:viewportHeight="48"
- android:tint="?androidprv:attr/materialColorOnSurfaceVariant">
+ android:tint="@androidprv:color/materialColorOnSurfaceVariant">
<path
android:fillColor="@android:color/white"
android:strokeColor="@android:color/white"
diff --git a/packages/SystemUI/res/drawable/immersive_cling_bg.xml b/packages/SystemUI/res/drawable/immersive_cling_bg.xml
index de29c32..b28a423 100644
--- a/packages/SystemUI/res/drawable/immersive_cling_bg.xml
+++ b/packages/SystemUI/res/drawable/immersive_cling_bg.xml
@@ -20,5 +20,5 @@
<corners
android:bottomLeftRadius="28dp"
android:bottomRightRadius="28dp"/>
- <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
</shape>
diff --git a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
index 32dc4b3..6ad46d8 100644
--- a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
+++ b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
@@ -20,7 +20,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh"/>
<size
android:width="@dimen/keyguard_affordance_fixed_width"
android:height="@dimen/keyguard_affordance_fixed_height"/>
diff --git a/packages/SystemUI/res/drawable/keyguard_settings_popup_menu_background.xml b/packages/SystemUI/res/drawable/keyguard_settings_popup_menu_background.xml
index fe76ba7..fab0cc2 100644
--- a/packages/SystemUI/res/drawable/keyguard_settings_popup_menu_background.xml
+++ b/packages/SystemUI/res/drawable/keyguard_settings_popup_menu_background.xml
@@ -26,7 +26,7 @@
</item>
<item>
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSecondaryFixed" />
+ <solid android:color="@androidprv:color/materialColorSecondaryFixed" />
<corners android:radius="@dimen/keyguard_affordance_fixed_radius" />
</shape>
</item>
diff --git a/packages/SystemUI/res/drawable/notif_footer_btn_background.xml b/packages/SystemUI/res/drawable/notif_footer_btn_background.xml
index b959737..1d5e09d 100644
--- a/packages/SystemUI/res/drawable/notif_footer_btn_background.xml
+++ b/packages/SystemUI/res/drawable/notif_footer_btn_background.xml
@@ -26,7 +26,7 @@
<padding
android:left="20dp"
android:right="20dp" />
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
</shape>
</inset>
</item>
diff --git a/packages/SystemUI/res/drawable/notification_guts_bg.xml b/packages/SystemUI/res/drawable/notification_guts_bg.xml
index 84e2231..200976b 100644
--- a/packages/SystemUI/res/drawable/notification_guts_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_guts_bg.xml
@@ -17,7 +17,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
<!--The radius is 1dp smaller than the notification one, to avoid aliasing bugs on the corners -->
<corners android:radius="1dp" />
</shape>
diff --git a/packages/SystemUI/res/drawable/notification_material_bg.xml b/packages/SystemUI/res/drawable/notification_material_bg.xml
index 715be07..db3b969 100644
--- a/packages/SystemUI/res/drawable/notification_material_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_material_bg.xml
@@ -20,7 +20,7 @@
android:color="?android:attr/colorControlHighlight">
<item>
<shape>
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHigh" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHigh" />
</shape>
</item>
<item>
diff --git a/packages/SystemUI/res/drawable/overlay_border.xml b/packages/SystemUI/res/drawable/overlay_border.xml
index a59f923..381849b 100644
--- a/packages/SystemUI/res/drawable/overlay_border.xml
+++ b/packages/SystemUI/res/drawable/overlay_border.xml
@@ -18,6 +18,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceBright"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceBright"/>
<corners android:radius="16dp"/>
</shape>
diff --git a/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_down.xml b/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_down.xml
index f8b99f4..299b4c9 100644
--- a/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_down.xml
+++ b/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_down.xml
@@ -23,8 +23,8 @@
android:viewportHeight="24">
<path
android:pathData="M0,12C0,5.373 5.373,0 12,0C18.627,0 24,5.373 24,12C24,18.627 18.627,24 12,24C5.373,24 0,18.627 0,12Z"
- android:fillColor="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+ android:fillColor="@androidprv:color/materialColorSurfaceContainerHigh"/>
<path
android:pathData="M7.607,9.059L6.667,9.999L12,15.332L17.333,9.999L16.393,9.059L12,13.445"
- android:fillColor="?androidprv:attr/materialColorOnSurface"/>
+ android:fillColor="@androidprv:color/materialColorOnSurface"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_up.xml b/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_up.xml
index ae60d51..68e73e9 100644
--- a/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_up.xml
+++ b/packages/SystemUI/res/drawable/privacy_dialog_expand_toggle_up.xml
@@ -23,8 +23,8 @@
android:viewportHeight="24">
<path
android:pathData="M0,12C0,5.3726 5.3726,0 12,0C18.6274,0 24,5.3726 24,12C24,18.6274 18.6274,24 12,24C5.3726,24 0,18.6274 0,12Z"
- android:fillColor="?androidprv:attr/materialColorSurfaceContainerHigh"/>
+ android:fillColor="@androidprv:color/materialColorSurfaceContainerHigh"/>
<path
android:pathData="M16.3934,14.9393L17.3334,13.9993L12.0001,8.666L6.6667,13.9993L7.6068,14.9393L12.0001,10.5527"
- android:fillColor="?androidprv:attr/materialColorOnSurface"/>
+ android:fillColor="@androidprv:color/materialColorOnSurface"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/qs_hearing_devices_related_tools_background.xml b/packages/SystemUI/res/drawable/qs_hearing_devices_related_tools_background.xml
index 3c16684..e90473b 100644
--- a/packages/SystemUI/res/drawable/qs_hearing_devices_related_tools_background.xml
+++ b/packages/SystemUI/res/drawable/qs_hearing_devices_related_tools_background.xml
@@ -21,7 +21,7 @@
android:color="?android:attr/colorControlHighlight">
<item>
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorPrimaryContainer"/>
+ <solid android:color="@androidprv:color/materialColorPrimaryContainer"/>
<corners android:radius="@dimen/hearing_devices_preset_spinner_background_radius"/>
</shape>
</item>
diff --git a/packages/SystemUI/res/drawable/qs_tile_focused_background.xml b/packages/SystemUI/res/drawable/qs_tile_focused_background.xml
index 33f0d02..cdf6a1a 100644
--- a/packages/SystemUI/res/drawable/qs_tile_focused_background.xml
+++ b/packages/SystemUI/res/drawable/qs_tile_focused_background.xml
@@ -21,6 +21,6 @@
<corners android:radius="30dp" />
<stroke
android:width="3dp"
- android:color="?androidprv:attr/materialColorSecondaryFixed" />
+ android:color="@androidprv:color/materialColorSecondaryFixed" />
</shape>
</inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/remote_input_view_text_bg.xml b/packages/SystemUI/res/drawable/remote_input_view_text_bg.xml
index 45d1a53..01ecbcf 100644
--- a/packages/SystemUI/res/drawable/remote_input_view_text_bg.xml
+++ b/packages/SystemUI/res/drawable/remote_input_view_text_bg.xml
@@ -17,10 +17,10 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceDim" />
+ <solid android:color="@androidprv:color/materialColorSurfaceDim" />
<stroke
android:width="@dimen/remote_input_view_text_stroke"
- android:color="?androidprv:attr/materialColorPrimary"/>
+ android:color="@androidprv:color/materialColorPrimary"/>
<padding
android:bottom="0dp"
android:left="12dp"
diff --git a/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml b/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml
index 321a04a..323cb77 100644
--- a/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml
+++ b/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml
@@ -17,5 +17,5 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/screenrecord_spinner_background_radius"/>
- <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/screenshot_edit_background.xml b/packages/SystemUI/res/drawable/screenshot_edit_background.xml
index 07e5aff..ef1c30f 100644
--- a/packages/SystemUI/res/drawable/screenshot_edit_background.xml
+++ b/packages/SystemUI/res/drawable/screenshot_edit_background.xml
@@ -20,7 +20,7 @@
android:color="@color/overlay_button_ripple">
<item android:id="@android:id/background">
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSecondaryFixedDim"/>
+ <solid android:color="@androidprv:color/materialColorSecondaryFixedDim"/>
<corners android:radius="16dp"/>
</shape>
</item>
diff --git a/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml b/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml
index fab2d8d..2063d9f 100644
--- a/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml
+++ b/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml
@@ -20,7 +20,7 @@
android:color="?android:attr/colorControlHighlight">
<item>
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorPrimaryContainer"/>
+ <solid android:color="@androidprv:color/materialColorPrimaryContainer"/>
<corners android:radius="@dimen/settingslib_switch_bar_radius"/>
</shape>
</item>
diff --git a/packages/SystemUI/res/drawable/settingslib_thumb_on.xml b/packages/SystemUI/res/drawable/settingslib_thumb_on.xml
index e316a93..70a1e84 100644
--- a/packages/SystemUI/res/drawable/settingslib_thumb_on.xml
+++ b/packages/SystemUI/res/drawable/settingslib_thumb_on.xml
@@ -24,7 +24,7 @@
<size
android:height="@dimen/settingslib_switch_thumb_size"
android:width="@dimen/settingslib_switch_thumb_size"/>
- <solid android:color="?androidprv:attr/materialColorOnPrimary"/>
+ <solid android:color="@androidprv:color/materialColorOnPrimary"/>
</shape>
</item>
</layer-list>
diff --git a/packages/SystemUI/res/drawable/settingslib_track_on_background.xml b/packages/SystemUI/res/drawable/settingslib_track_on_background.xml
index e2e6468..e3476a4 100644
--- a/packages/SystemUI/res/drawable/settingslib_track_on_background.xml
+++ b/packages/SystemUI/res/drawable/settingslib_track_on_background.xml
@@ -22,6 +22,6 @@
android:height="@dimen/settingslib_switch_track_height">
<padding android:left="@dimen/settingslib_switch_thumb_margin"
android:right="@dimen/settingslib_switch_thumb_margin"/>
- <solid android:color="?androidprv:attr/materialColorPrimary"/>
+ <solid android:color="@androidprv:color/materialColorPrimary"/>
<corners android:radius="@dimen/settingslib_switch_track_radius"/>
</shape>
diff --git a/packages/SystemUI/res/drawable/shelf_action_chip_background.xml b/packages/SystemUI/res/drawable/shelf_action_chip_background.xml
index 63600be..faa3d68 100644
--- a/packages/SystemUI/res/drawable/shelf_action_chip_background.xml
+++ b/packages/SystemUI/res/drawable/shelf_action_chip_background.xml
@@ -20,7 +20,7 @@
android:color="@color/overlay_button_ripple">
<item android:id="@android:id/background">
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSecondary"/>
+ <solid android:color="@androidprv:color/materialColorSecondary"/>
<corners android:radius="10000dp"/> <!-- fully-rounded radius -->
</shape>
</item>
diff --git a/packages/SystemUI/res/drawable/shelf_action_chip_container_background.xml b/packages/SystemUI/res/drawable/shelf_action_chip_container_background.xml
index ad6c154..82f034b 100644
--- a/packages/SystemUI/res/drawable/shelf_action_chip_container_background.xml
+++ b/packages/SystemUI/res/drawable/shelf_action_chip_container_background.xml
@@ -21,7 +21,7 @@
<shape
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceBright"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceBright"/>
<corners android:radius="10000dp"/> <!-- fully-rounded radius -->
</shape>
</inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/shortcut_button_colored.xml b/packages/SystemUI/res/drawable/shortcut_button_colored.xml
index 2e2d9b9..b6a14c8 100644
--- a/packages/SystemUI/res/drawable/shortcut_button_colored.xml
+++ b/packages/SystemUI/res/drawable/shortcut_button_colored.xml
@@ -22,7 +22,7 @@
<item>
<shape android:shape="rectangle">
<corners android:radius="@dimen/ksh_button_corner_radius"/>
- <solid android:color="?androidprv:attr/materialColorSurfaceBright"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceBright"/>
</shape>
</item>
</ripple>
diff --git a/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml b/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml
index 5b88bb9..2b95a94 100644
--- a/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml
+++ b/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml
@@ -22,7 +22,7 @@
<item>
<shape android:shape="rectangle">
<corners android:radius="@dimen/ksh_button_corner_radius"/>
- <solid android:color="?androidprv:attr/materialColorPrimary"/>
+ <solid android:color="@androidprv:color/materialColorPrimary"/>
</shape>
</item>
</ripple>
diff --git a/packages/SystemUI/res/drawable/shortcut_search_background.xml b/packages/SystemUI/res/drawable/shortcut_search_background.xml
index d6847f0..07e5b3d 100644
--- a/packages/SystemUI/res/drawable/shortcut_search_background.xml
+++ b/packages/SystemUI/res/drawable/shortcut_search_background.xml
@@ -19,7 +19,7 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item>
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/materialColorSurfaceBright" />
+ <solid android:color="@androidprv:color/materialColorSurfaceBright" />
<corners android:radius="@dimen/ksh_search_box_corner_radius" />
</shape>
</item>
diff --git a/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml b/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml
index 2675906..6390c11d 100644
--- a/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml
+++ b/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml
@@ -20,7 +20,7 @@
<shape android:shape="oval">
<size android:width="24dp"
android:height="24dp" />
- <solid android:color="?androidprv:attr/materialColorSurfaceBright"/>
+ <solid android:color="@androidprv:color/materialColorSurfaceBright"/>
</shape>
</item>
</ripple>
diff --git a/packages/SystemUI/res/drawable/status_bar_notification_section_header_clear_btn.xml b/packages/SystemUI/res/drawable/status_bar_notification_section_header_clear_btn.xml
index 06bed00..42a5d30 100644
--- a/packages/SystemUI/res/drawable/status_bar_notification_section_header_clear_btn.xml
+++ b/packages/SystemUI/res/drawable/status_bar_notification_section_header_clear_btn.xml
@@ -21,6 +21,6 @@
android:viewportWidth="40"
android:viewportHeight="40">
<path
- android:fillColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:fillColor="@androidprv:color/materialColorOnSurfaceVariant"
android:pathData="M24.6667 16.2733L23.7267 15.3333L20 19.06L16.2734 15.3333L15.3334 16.2733L19.06 20L15.3334 23.7267L16.2734 24.6667L20 20.94L23.7267 24.6667L24.6667 23.7267L20.94 20L24.6667 16.2733Z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/volume_background_top.xml b/packages/SystemUI/res/drawable/volume_background_top.xml
index 132572a..7185d03 100644
--- a/packages/SystemUI/res/drawable/volume_background_top.xml
+++ b/packages/SystemUI/res/drawable/volume_background_top.xml
@@ -17,7 +17,7 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item>
<shape>
- <solid android:color="?androidprv:attr/materialColorSurface" />
+ <solid android:color="@androidprv:color/materialColorSurface" />
<corners android:topLeftRadius="@dimen/volume_dialog_background_corner_radius"
android:topRightRadius="@dimen/volume_dialog_background_corner_radius"/>
</shape>
diff --git a/packages/SystemUI/res/drawable/volume_dialog_background.xml b/packages/SystemUI/res/drawable/volume_dialog_background.xml
index 7d7498f..25d78e3 100644
--- a/packages/SystemUI/res/drawable/volume_dialog_background.xml
+++ b/packages/SystemUI/res/drawable/volume_dialog_background.xml
@@ -18,5 +18,5 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/volume_dialog_background_corner_radius" />
- <solid android:color="?androidprv:attr/materialColorSurface" />
+ <solid android:color="@androidprv:color/materialColorSurface" />
</shape>
diff --git a/packages/SystemUI/res/drawable/volume_dialog_background_small_radius.xml b/packages/SystemUI/res/drawable/volume_dialog_background_small_radius.xml
index 7d79496..9026d64 100644
--- a/packages/SystemUI/res/drawable/volume_dialog_background_small_radius.xml
+++ b/packages/SystemUI/res/drawable/volume_dialog_background_small_radius.xml
@@ -17,5 +17,5 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/volume_dialog_background_square_corner_radius" />
- <solid android:color="?androidprv:attr/materialColorSurface" />
+ <solid android:color="@androidprv:color/materialColorSurface" />
</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/volume_drawer_selection_bg.xml b/packages/SystemUI/res/drawable/volume_drawer_selection_bg.xml
index 131201e..555eebd 100644
--- a/packages/SystemUI/res/drawable/volume_drawer_selection_bg.xml
+++ b/packages/SystemUI/res/drawable/volume_drawer_selection_bg.xml
@@ -19,6 +19,6 @@
<size
android:height="@dimen/volume_dialog_ringer_drawer_button_size"
android:width="@dimen/volume_dialog_ringer_drawer_button_size" />
- <solid android:color="?androidprv:attr/materialColorPrimary" />
+ <solid android:color="@androidprv:color/materialColorPrimary" />
<corners android:radius="@dimen/volume_dialog_ringer_selected_button_background_radius" />
</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/volume_ringer_item_bg.xml b/packages/SystemUI/res/drawable/volume_ringer_item_bg.xml
index a8c9818..4b3edb9 100644
--- a/packages/SystemUI/res/drawable/volume_ringer_item_bg.xml
+++ b/packages/SystemUI/res/drawable/volume_ringer_item_bg.xml
@@ -17,6 +17,6 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle" >
<size android:width="@dimen/volume_dialog_ringer_drawer_button_size" android:height="@dimen/volume_dialog_ringer_drawer_button_size"/>
- <solid android:color="?androidprv:attr/materialColorSurfaceContainerHighest" />
+ <solid android:color="@androidprv:color/materialColorSurfaceContainerHighest" />
<corners android:radius="@dimen/volume_dialog_background_square_corner_radius" />
</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/volume_row_seekbar.xml b/packages/SystemUI/res/drawable/volume_row_seekbar.xml
index d7d75d4..c47d7c0 100644
--- a/packages/SystemUI/res/drawable/volume_row_seekbar.xml
+++ b/packages/SystemUI/res/drawable/volume_row_seekbar.xml
@@ -26,7 +26,7 @@
<shape>
<size android:height="@dimen/volume_dialog_track_width" />
<corners android:radius="@dimen/volume_dialog_panel_width_half" />
- <solid android:color="?androidprv:attr/materialColorOutlineVariant" />
+ <solid android:color="@androidprv:color/materialColorOutlineVariant" />
</shape>
</item>
<item android:id="@android:id/progress"
diff --git a/packages/SystemUI/res/layout/alert_dialog_title_systemui.xml b/packages/SystemUI/res/layout/alert_dialog_title_systemui.xml
index ca7df86..3e53bf4 100644
--- a/packages/SystemUI/res/layout/alert_dialog_title_systemui.xml
+++ b/packages/SystemUI/res/layout/alert_dialog_title_systemui.xml
@@ -42,7 +42,7 @@
android:layout_marginBottom="16dp"
android:scaleType="fitCenter"
android:src="@null"
- android:tint="?androidprv:attr/materialColorPrimary"
+ android:tint="@androidprv:color/materialColorPrimary"
/>
<TextView
diff --git a/packages/SystemUI/res/layout/app_clips_screenshot.xml b/packages/SystemUI/res/layout/app_clips_screenshot.xml
index 7b7c96cb..afc58cc 100644
--- a/packages/SystemUI/res/layout/app_clips_screenshot.xml
+++ b/packages/SystemUI/res/layout/app_clips_screenshot.xml
@@ -31,10 +31,10 @@
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:background="@drawable/overlay_button_background"
- android:backgroundTint="?androidprv:attr/materialColorPrimary"
+ android:backgroundTint="@androidprv:color/materialColorPrimary"
android:paddingHorizontal="24dp"
android:text="@string/app_clips_save_add_to_note"
- android:textColor="?androidprv:attr/materialColorOnPrimary"
+ android:textColor="@androidprv:color/materialColorOnPrimary"
app:layout_constraintBottom_toTopOf="@id/preview"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -61,7 +61,7 @@
android:button="@drawable/checkbox_circle_shape"
android:checked="true"
android:text="@string/backlinks_include_link"
- android:textColor="?androidprv:attr/materialColorOnBackground"
+ android:textColor="@androidprv:color/materialColorOnBackground"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/preview"
app:layout_constraintStart_toEndOf="@id/cancel"
@@ -89,11 +89,11 @@
android:layout_marginStart="8dp"
android:drawablePadding="4dp"
android:drawableStart="@drawable/ic_info_outline"
- android:drawableTint="?androidprv:attr/materialColorOnBackground"
+ android:drawableTint="@androidprv:color/materialColorOnBackground"
android:gravity="center"
android:paddingHorizontal="8dp"
android:text="@string/backlinks_cross_profile_error"
- android:textColor="?androidprv:attr/materialColorOnBackground"
+ android:textColor="@androidprv:color/materialColorOnBackground"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/preview"
app:layout_constraintStart_toEndOf="@id/backlinks_data"
diff --git a/packages/SystemUI/res/layout/bundle_notification_info.xml b/packages/SystemUI/res/layout/bundle_notification_info.xml
index 8700832..745066a 100644
--- a/packages/SystemUI/res/layout/bundle_notification_info.xml
+++ b/packages/SystemUI/res/layout/bundle_notification_info.xml
@@ -103,7 +103,7 @@
android:contentDescription="@string/notification_app_settings"
android:src="@drawable/ic_info"
android:layout_toStartOf="@id/info"
- android:tint="?androidprv:attr/materialColorPrimary"/>
+ android:tint="@androidprv:color/materialColorPrimary"/>
<ImageButton
android:id="@+id/info"
android:layout_width="@dimen/notification_importance_toggle_size"
@@ -112,7 +112,7 @@
android:contentDescription="@string/notification_more_settings"
android:background="@drawable/ripple_drawable_20dp"
android:src="@drawable/ic_settings"
- android:tint="?androidprv:attr/materialColorPrimary"
+ android:tint="@androidprv:color/materialColorPrimary"
android:layout_alignParentEnd="true" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/chipbar.xml b/packages/SystemUI/res/layout/chipbar.xml
index e1b8ab4..2fecf79 100644
--- a/packages/SystemUI/res/layout/chipbar.xml
+++ b/packages/SystemUI/res/layout/chipbar.xml
@@ -56,10 +56,10 @@
android:layout_height="wrap_content"
android:layout_weight="1"
style="@style/Chipbar.Text"
- android:textColor="?androidprv:attr/materialColorOnSecondaryFixed"
+ android:textColor="@androidprv:color/materialColorOnSecondaryFixed"
android:alpha="0.0"
/>
- <!-- LINT.ThenChange(systemui.temporarydisplay.chipbar.ChipbarInfo.kt) -->
+ <!-- LINT.ThenChange(/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt) -->
<!-- At most one of [loading, failure_icon, undo] will be visible at a time. -->
<ImageView
@@ -68,7 +68,7 @@
android:layout_height="@dimen/chipbar_end_icon_size"
android:layout_marginStart="@dimen/chipbar_end_item_start_margin"
android:src="@drawable/ic_progress_activity"
- android:tint="?androidprv:attr/materialColorOnSecondaryFixedVariant"
+ android:tint="@androidprv:color/materialColorOnSecondaryFixedVariant"
android:alpha="0.0"
/>
@@ -88,7 +88,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/chipbar_end_item_start_margin"
style="@style/Chipbar.Text"
- android:textColor="?androidprv:attr/materialColorOnPrimaryFixed"
+ android:textColor="@androidprv:color/materialColorOnPrimaryFixed"
android:paddingStart="@dimen/chipbar_outer_padding"
android:paddingEnd="@dimen/chipbar_outer_padding"
android:paddingTop="@dimen/chipbar_end_button_vertical_padding"
diff --git a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
index 14b3b55..3378dcc 100644
--- a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
+++ b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
@@ -17,8 +17,8 @@
android:paddingHorizontal="16dp"
android:background="@drawable/overlay_button_background"
android:text="@string/clipboard_edit_text_done"
- android:backgroundTint="?androidprv:attr/materialColorPrimary"
- android:textColor="?androidprv:attr/materialColorOnPrimary"
+ android:backgroundTint="@androidprv:color/materialColorPrimary"
+ android:textColor="@androidprv:color/materialColorOnPrimary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml
index 572f063..448b3e7 100644
--- a/packages/SystemUI/res/layout/clipboard_overlay.xml
+++ b/packages/SystemUI/res/layout/clipboard_overlay.xml
@@ -222,8 +222,8 @@
android:layout_height="match_parent"
android:layout_margin="@dimen/overlay_dismiss_button_margin"
android:background="@drawable/circular_background"
- android:backgroundTint="?androidprv:attr/materialColorPrimaryFixedDim"
- android:tint="?androidprv:attr/materialColorOnPrimaryFixed"
+ android:backgroundTint="@androidprv:color/materialColorPrimaryFixedDim"
+ android:tint="@androidprv:color/materialColorOnPrimaryFixed"
android:padding="4dp"
android:src="@drawable/ic_close"/>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/connected_display_dialog.xml b/packages/SystemUI/res/layout/connected_display_dialog.xml
index a71782b..b223555 100644
--- a/packages/SystemUI/res/layout/connected_display_dialog.xml
+++ b/packages/SystemUI/res/layout/connected_display_dialog.xml
@@ -30,11 +30,11 @@
android:layout_width="@dimen/connected_display_dialog_logo_size"
android:layout_height="@dimen/connected_display_dialog_logo_size"
android:background="@drawable/circular_background"
- android:backgroundTint="?androidprv:attr/materialColorSecondary"
+ android:backgroundTint="@androidprv:color/materialColorSecondary"
android:importantForAccessibility="no"
android:padding="6dp"
android:src="@drawable/stat_sys_connected_display"
- android:tint="?androidprv:attr/materialColorOnSecondary" />
+ android:tint="@androidprv:color/materialColorOnSecondary" />
<TextView
android:id="@+id/connected_display_dialog_title"
diff --git a/packages/SystemUI/res/layout/contextual_edu_dialog.xml b/packages/SystemUI/res/layout/contextual_edu_dialog.xml
index 7eb6efe..09aa8da 100644
--- a/packages/SystemUI/res/layout/contextual_edu_dialog.xml
+++ b/packages/SystemUI/res/layout/contextual_edu_dialog.xml
@@ -39,6 +39,7 @@
android:ellipsize="end"
android:fontFamily="google-sans-medium"
android:maxWidth="280dp"
- android:textColor="?androidprv:attr/materialColorOnTertiaryFixed"
- android:textSize="14sp" />
+ android:textColor="@androidprv:color/materialColorOnTertiaryFixed"
+ android:textSize="14sp"
+ android:textStyle="bold" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/hearing_devices_spinner_dropdown_view.xml b/packages/SystemUI/res/layout/hearing_devices_spinner_dropdown_view.xml
index 70f2cd5..2d799ae 100644
--- a/packages/SystemUI/res/layout/hearing_devices_spinner_dropdown_view.xml
+++ b/packages/SystemUI/res/layout/hearing_devices_spinner_dropdown_view.xml
@@ -28,7 +28,7 @@
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:tint="@androidprv:color/materialColorOnPrimaryContainer"
android:src="@drawable/ic_check"
android:contentDescription="@string/hearing_devices_spinner_item_selected"/>
<TextView
diff --git a/packages/SystemUI/res/layout/immersive_mode_cling.xml b/packages/SystemUI/res/layout/immersive_mode_cling.xml
index 20b7cd3..f12cf96 100644
--- a/packages/SystemUI/res/layout/immersive_mode_cling.xml
+++ b/packages/SystemUI/res/layout/immersive_mode_cling.xml
@@ -42,7 +42,7 @@
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:text="@string/immersive_cling_title"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textSize="24sp"
android:fontFamily="google-sans" />
@@ -54,7 +54,7 @@
android:paddingTop="14dp"
android:gravity="center_horizontal"
android:text="@string/immersive_cling_description"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
android:textSize="14sp"
android:fontFamily="google-sans" />
@@ -72,7 +72,7 @@
android:minWidth="48dp"
android:minHeight="48dp"
android:text="@string/immersive_cling_positive"
- android:textColor="?androidprv:attr/materialColorOnPrimary"
+ android:textColor="@androidprv:color/materialColorOnPrimary"
android:textAllCaps="false"
android:textSize="14sp"
android:textFontWeight="500"
diff --git a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
index 2b40df4..5922a7d 100644
--- a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
+++ b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
@@ -149,7 +149,8 @@
android:clickable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="start|center_vertical">
+ android:minHeight="72dp"
+ android:gravity="center_vertical">
<TextView
android:id="@+id/mobile_title"
android:maxLines="1"
diff --git a/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml b/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
index 5ab2327..4a40dda4 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
@@ -40,7 +40,7 @@
android:layout_height="wrap_content"
android:paddingEnd="12dp"
android:paddingBottom="4dp"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="16sp"
android:maxLines="5"
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml
index 6e7fde6..3e69a66 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml
@@ -21,7 +21,7 @@
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="14sp"
- android:textColor="?androidprv:attr/materialColorPrimary"
+ android:textColor="@androidprv:color/materialColorPrimary"
android:importantForAccessibility="yes"
android:paddingTop="20dp"
android:paddingBottom="10dp"/>
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_key_separator_view.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_key_separator_view.xml
index 8772a73..5bba9ba 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_key_separator_view.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_key_separator_view.xml
@@ -22,7 +22,7 @@
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:text="@string/keyboard_shortcut_join"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
android:singleLine="true"
android:gravity="center"
android:textSize="@dimen/ksh_item_text_size" />
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_key_view.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_key_view.xml
index 42bbf25..91558fd 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_key_view.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_key_view.xml
@@ -25,7 +25,7 @@
android:paddingBottom="@dimen/ksh_key_view_padding_vertical"
android:layout_marginStart="@dimen/ksh_item_margin_start"
android:background="@drawable/ksh_key_item_background"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
android:singleLine="true"
android:gravity="center"
android:textSize="@dimen/ksh_item_text_size" />
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml
index 45a4af9..18716ef 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml
@@ -52,14 +52,14 @@
android:drawableStart="@drawable/ic_shortcutlist_search"
android:drawablePadding="15dp"
android:singleLine="true"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
android:inputType="text"
android:textDirection="locale"
android:textAlignment="viewStart"
android:hint="@string/keyboard_shortcut_search_list_hint"
android:textAppearance="@android:style/TextAppearance.Material"
android:textSize="16sp"
- android:textColorHint="?androidprv:attr/materialColorOutline" />
+ android:textColorHint="@androidprv:color/materialColorOutline" />
<ImageButton
android:id="@+id/keyboard_shortcuts_search_cancel"
diff --git a/packages/SystemUI/res/layout/keyguard_settings_popup_menu.xml b/packages/SystemUI/res/layout/keyguard_settings_popup_menu.xml
index 636f479..e47fc62 100644
--- a/packages/SystemUI/res/layout/keyguard_settings_popup_menu.xml
+++ b/packages/SystemUI/res/layout/keyguard_settings_popup_menu.xml
@@ -32,7 +32,7 @@
android:layout_width="@dimen/keyguard_settings_popup_menu_icon_height"
android:layout_height="@dimen/keyguard_settings_popup_menu_icon_width"
android:layout_marginEnd="@dimen/keyguard_settings_popup_menu_icon_end_margin"
- android:tint="?androidprv:attr/materialColorOnSecondaryFixed"
+ android:tint="@androidprv:color/materialColorOnSecondaryFixed"
android:importantForAccessibility="no"
tools:ignore="UseAppTint" />
@@ -41,7 +41,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?androidprv:attr/materialColorOnSecondaryFixed"
+ android:textColor="@androidprv:color/materialColorOnSecondaryFixed"
android:textSize="14sp"
android:maxLines="1"
android:ellipsize="end" />
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index 4d207da..87433be 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -32,8 +32,8 @@
android:layout_marginStart="8dp"
android:layout_marginTop="@dimen/long_screenshot_action_bar_top_margin"
android:background="@drawable/overlay_button_background"
- android:backgroundTint="?androidprv:attr/materialColorPrimary"
- android:textColor="?androidprv:attr/materialColorOnPrimary"
+ android:backgroundTint="@androidprv:color/materialColorPrimary"
+ android:textColor="@androidprv:color/materialColorOnPrimary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/preview" />
@@ -47,8 +47,8 @@
android:layout_marginStart="6dp"
android:layout_marginTop="@dimen/long_screenshot_action_bar_top_margin"
android:background="@drawable/overlay_button_outline"
- android:backgroundTint="?androidprv:attr/materialColorPrimary"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:backgroundTint="@androidprv:color/materialColorPrimary"
+ android:textColor="@androidprv:color/materialColorOnSurface"
app:layout_constraintStart_toEndOf="@id/save"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/preview"
@@ -57,7 +57,7 @@
<ImageButton
android:id="@+id/share"
style="@android:style/Widget.Material.Button.Borderless"
- android:tint="?androidprv:attr/materialColorOnSurface"
+ android:tint="@androidprv:color/materialColorOnSurface"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="8dp"
@@ -114,10 +114,10 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:handleThickness="@dimen/screenshot_crop_handle_thickness"
- app:handleColor="?androidprv:attr/materialColorSecondary"
- app:scrimColor="?androidprv:attr/materialColorSurfaceContainer"
+ app:handleColor="@androidprv:color/materialColorSecondary"
+ app:scrimColor="@androidprv:color/materialColorSurfaceContainer"
app:scrimAlpha="128"
- app:containerBackgroundColor="?androidprv:attr/materialColorSurfaceContainer"
+ app:containerBackgroundColor="@androidprv:color/materialColorSurfaceContainer"
tools:background="?android:colorBackground"
tools:minHeight="100dp"
tools:minWidth="100dp" />
@@ -131,11 +131,11 @@
app:layout_constraintTop_toTopOf="@id/preview"
app:layout_constraintLeft_toLeftOf="parent"
app:handleThickness="@dimen/screenshot_crop_handle_thickness"
- app:handleColor="?androidprv:attr/materialColorSecondary"
- app:scrimColor="?androidprv:attr/materialColorSurfaceContainer"
+ app:handleColor="@androidprv:color/materialColorSecondary"
+ app:scrimColor="@androidprv:color/materialColorSurfaceContainer"
app:scrimAlpha="128"
app:borderThickness="4dp"
- app:borderColor="?androidprv:attr/materialColorSurfaceBright" />
+ app:borderColor="@androidprv:color/materialColorSurfaceBright" />
<ImageButton
android:id="@+id/edit"
@@ -147,7 +147,7 @@
android:background="@drawable/screenshot_edit_background"
android:src="@drawable/ic_screenshot_edit"
android:contentDescription="@string/screenshot_edit_label"
- android:tint="?androidprv:attr/materialColorOnSecondaryFixed"
+ android:tint="@androidprv:color/materialColorOnSecondaryFixed"
android:padding="16dp"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
diff --git a/packages/SystemUI/res/layout/notif_half_shelf.xml b/packages/SystemUI/res/layout/notif_half_shelf.xml
index d8d2985..9a66ca9 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf.xml
@@ -66,7 +66,7 @@
android:gravity="center_vertical|start"
android:ellipsize="end"
android:maxLines="2"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
android:textSize="16sp"
/>
diff --git a/packages/SystemUI/res/layout/notif_half_shelf_row.xml b/packages/SystemUI/res/layout/notif_half_shelf_row.xml
index 9ef342c..b2eaa6c 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf_row.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf_row.xml
@@ -60,7 +60,7 @@
android:ellipsize="end"
android:maxLines="1"
android:fontFamily="@*android:string/config_headlineFontFamily"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:textSize="16sp"
/>
@@ -75,7 +75,7 @@
android:maxLines="1"
android:layout_below="@id/channel_name"
android:fontFamily="@*android:string/config_bodyFontFamily"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
android:textSize="14sp"
/>
</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/notification_children_divider.xml b/packages/SystemUI/res/layout/notification_children_divider.xml
index 13e24a9..c1d94f9 100644
--- a/packages/SystemUI/res/layout/notification_children_divider.xml
+++ b/packages/SystemUI/res/layout/notification_children_divider.xml
@@ -21,4 +21,4 @@
android:id="@+id/notification_more_divider"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_divider_height"
- android:background="?androidprv:attr/materialColorOnSurfaceVariant" />
+ android:background="@androidprv:color/materialColorOnSurfaceVariant" />
diff --git a/packages/SystemUI/res/layout/notification_conversation_info.xml b/packages/SystemUI/res/layout/notification_conversation_info.xml
index 3a752c8..cb9d8115d 100644
--- a/packages/SystemUI/res/layout/notification_conversation_info.xml
+++ b/packages/SystemUI/res/layout/notification_conversation_info.xml
@@ -174,7 +174,7 @@
android:contentDescription="@string/notification_more_settings"
android:background="@drawable/ripple_drawable_20dp"
android:src="@drawable/ic_settings"
- android:tint="?androidprv:attr/materialColorPrimary"
+ android:tint="@androidprv:color/materialColorPrimary"
android:layout_alignParentEnd="true" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 19a3f2f..edca7e3 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -103,7 +103,7 @@
android:contentDescription="@string/notification_app_settings"
android:src="@drawable/ic_info"
android:layout_toStartOf="@id/info"
- android:tint="?androidprv:attr/materialColorPrimary"/>
+ android:tint="@androidprv:color/materialColorPrimary"/>
<ImageButton
android:id="@+id/info"
android:layout_width="@dimen/notification_importance_toggle_size"
@@ -112,7 +112,7 @@
android:contentDescription="@string/notification_more_settings"
android:background="@drawable/ripple_drawable_20dp"
android:src="@drawable/ic_settings"
- android:tint="?androidprv:attr/materialColorPrimary"
+ android:tint="@androidprv:color/materialColorPrimary"
android:layout_alignParentEnd="true" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/notification_snooze.xml b/packages/SystemUI/res/layout/notification_snooze.xml
index ce09385..f114f4c 100644
--- a/packages/SystemUI/res/layout/notification_snooze.xml
+++ b/packages/SystemUI/res/layout/notification_snooze.xml
@@ -23,7 +23,7 @@
android:orientation="vertical"
android:paddingTop="2dp"
android:paddingBottom="2dp"
- android:background="?androidprv:attr/materialColorSurfaceContainerHigh"
+ android:background="@androidprv:color/materialColorSurfaceContainerHigh"
android:theme="@style/Theme.SystemUI">
<RelativeLayout
@@ -38,7 +38,7 @@
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:paddingStart="@*android:dimen/notification_content_margin_end"
- android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textColor="@androidprv:color/materialColorOnSurface"
android:paddingEnd="4dp"/>
<ImageView
diff --git a/packages/SystemUI/res/layout/notification_snooze_option.xml b/packages/SystemUI/res/layout/notification_snooze_option.xml
index fa6f965..364b44c 100644
--- a/packages/SystemUI/res/layout/notification_snooze_option.xml
+++ b/packages/SystemUI/res/layout/notification_snooze_option.xml
@@ -23,4 +23,4 @@
android:layout_marginEnd="@*android:dimen/notification_content_margin_end"
android:gravity="center_vertical"
android:textSize="14sp"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"/>
\ No newline at end of file
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/privacy_dialog_item_v2.xml b/packages/SystemUI/res/layout/privacy_dialog_item_v2.xml
index b84f3a9..3ca4b94 100644
--- a/packages/SystemUI/res/layout/privacy_dialog_item_v2.xml
+++ b/packages/SystemUI/res/layout/privacy_dialog_item_v2.xml
@@ -25,7 +25,7 @@
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="28dp"
app:cardElevation="0dp"
- app:cardBackgroundColor="?androidprv:attr/materialColorSurfaceBright">
+ app:cardBackgroundColor="@androidprv:color/materialColorSurfaceBright">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/privacy_dialog_v2.xml b/packages/SystemUI/res/layout/privacy_dialog_v2.xml
index 76098a1..0392322 100644
--- a/packages/SystemUI/res/layout/privacy_dialog_v2.xml
+++ b/packages/SystemUI/res/layout/privacy_dialog_v2.xml
@@ -45,7 +45,7 @@
android:layout_height="wrap_content"
android:text="@string/privacy_dialog_summary"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
+ android:textColor="@androidprv:color/materialColorOnSurfaceVariant"
android:gravity="center"
android:layout_marginBottom="20dp"/>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/record_issue_dialog.xml b/packages/SystemUI/res/layout/record_issue_dialog.xml
index b2a8c4c..76a7d34 100644
--- a/packages/SystemUI/res/layout/record_issue_dialog.xml
+++ b/packages/SystemUI/res/layout/record_issue_dialog.xml
@@ -55,7 +55,7 @@
android:layout_height="@dimen/screenrecord_option_icon_size"
android:layout_weight="0"
android:src="@drawable/ic_screenrecord"
- app:tint="?androidprv:attr/materialColorOnSurface"
+ app:tint="@androidprv:color/materialColorOnSurface"
android:importantForAccessibility="no"
android:layout_gravity="center"
android:layout_marginEnd="@dimen/screenrecord_option_padding" />
@@ -95,7 +95,7 @@
android:layout_height="@dimen/screenrecord_option_icon_size"
android:layout_weight="0"
android:src="@drawable/ic_bugreport"
- app:tint="?androidprv:attr/materialColorOnSurface"
+ app:tint="@androidprv:color/materialColorOnSurface"
android:importantForAccessibility="no"
android:layout_gravity="center"
android:layout_marginEnd="@dimen/screenrecord_option_padding" />
diff --git a/packages/SystemUI/res/layout/screen_share_dialog.xml b/packages/SystemUI/res/layout/screen_share_dialog.xml
index 0533c7e..78d1ab2 100644
--- a/packages/SystemUI/res/layout/screen_share_dialog.xml
+++ b/packages/SystemUI/res/layout/screen_share_dialog.xml
@@ -36,7 +36,7 @@
android:layout_width="@dimen/screenrecord_logo_size"
android:layout_height="@dimen/screenrecord_logo_size"
android:src="@drawable/ic_media_projection_permission"
- android:tint="?androidprv:attr/materialColorPrimary"
+ android:tint="@androidprv:color/materialColorPrimary"
android:importantForAccessibility="no"/>
<TextView
android:id="@+id/screen_share_dialog_title"
diff --git a/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml b/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml
index 8c31713..1ef010b 100644
--- a/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml
+++ b/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml
@@ -39,6 +39,6 @@
android:ellipsize="marquee"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?androidprv:attr/materialColorError" />
+ android:textColor="@androidprv:color/materialColorError" />
</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/screenshot_shelf.xml b/packages/SystemUI/res/layout/screenshot_shelf.xml
index fff1de7..f03c032 100644
--- a/packages/SystemUI/res/layout/screenshot_shelf.xml
+++ b/packages/SystemUI/res/layout/screenshot_shelf.xml
@@ -127,8 +127,8 @@
android:layout_height="match_parent"
android:layout_margin="@dimen/overlay_dismiss_button_margin"
android:background="@drawable/circular_background"
- android:backgroundTint="?androidprv:attr/materialColorPrimary"
- android:tint="?androidprv:attr/materialColorOnPrimary"
+ android:backgroundTint="@androidprv:color/materialColorPrimary"
+ android:tint="@androidprv:color/materialColorOnPrimary"
android:padding="4dp"
android:src="@drawable/ic_close"/>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml b/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml
index 39ec09b..9803871 100644
--- a/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml
+++ b/packages/SystemUI/res/layout/screenshot_work_profile_first_run.xml
@@ -38,8 +38,8 @@
android:layout_height="24dp"
android:layout_gravity="center"
android:background="@drawable/circular_background"
- android:backgroundTint="?androidprv:attr/materialColorSurfaceContainerHigh"
- android:tint="?androidprv:attr/materialColorOnSurface"
+ android:backgroundTint="@androidprv:color/materialColorSurfaceContainerHigh"
+ android:tint="@androidprv:color/materialColorOnSurface"
android:padding="2dp"
android:src="@drawable/ic_close"/>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/shelf_action_chip.xml b/packages/SystemUI/res/layout/shelf_action_chip.xml
index 1c65e36..430e9f7 100644
--- a/packages/SystemUI/res/layout/shelf_action_chip.xml
+++ b/packages/SystemUI/res/layout/shelf_action_chip.xml
@@ -27,7 +27,7 @@
>
<ImageView
android:id="@+id/overlay_action_chip_icon"
- android:tint="?androidprv:attr/materialColorOnSecondary"
+ android:tint="@androidprv:color/materialColorOnSecondary"
android:tintMode="src_in"
android:layout_width="@dimen/overlay_action_chip_icon_size"
android:layout_height="@dimen/overlay_action_chip_icon_size"/>
@@ -37,5 +37,5 @@
android:layout_height="wrap_content"
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
android:textSize="@dimen/overlay_action_chip_text_size"
- android:textColor="?androidprv:attr/materialColorOnSecondary"/>
+ android:textColor="@androidprv:color/materialColorOnSecondary"/>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index b8544a6..a3bad8f 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -58,7 +58,7 @@
android:contentDescription="@string/accessibility_volume_settings"
android:soundEffectsEnabled="false"
android:src="@drawable/horizontal_ellipsis"
- android:tint="?androidprv:attr/materialColorPrimary"
+ android:tint="@androidprv:color/materialColorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/volume_dialog_main_slider_container"
app:layout_constraintStart_toStartOf="@id/volume_dialog_main_slider_container"
@@ -79,4 +79,4 @@
app:layout_constraintEnd_toStartOf="@id/volume_dialog_background"
app:layout_constraintTop_toTopOf="@id/volume_dialog_main_slider_container" />
-</androidx.constraintlayout.motion.widget.MotionLayout>
\ No newline at end of file
+</androidx.constraintlayout.motion.widget.MotionLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog_slider.xml b/packages/SystemUI/res/layout/volume_dialog_slider.xml
index c1852b1..9ac456c 100644
--- a/packages/SystemUI/res/layout/volume_dialog_slider.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_slider.xml
@@ -14,15 +14,21 @@
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="@dimen/volume_dialog_slider_width"
- android:layout_height="@dimen/volume_dialog_slider_height">
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
<com.google.android.material.slider.Slider
- style="@style/SystemUI.Material3.Slider.Volume"
android:id="@+id/volume_dialog_slider"
- android:layout_width="@dimen/volume_dialog_slider_height"
- android:layout_height="match_parent"
+ style="@style/SystemUI.Material3.Slider.Volume"
+ android:layout_width="@dimen/volume_dialog_slider_width"
+ android:layout_height="@dimen/volume_dialog_slider_height"
android:layout_gravity="center"
- android:rotation="270"
- android:theme="@style/Theme.Material3.Light" />
-</FrameLayout>
+ android:theme="@style/Theme.Material3.Light"
+ android:orientation="vertical"
+ app:thumbHeight="52dp"
+ app:trackCornerSize="12dp"
+ app:trackHeight="40dp"
+ app:trackStopIndicatorSize="6dp"
+ app:trackInsideCornerSize="2dp" />
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/volume_ringer_button.xml b/packages/SystemUI/res/layout/volume_ringer_button.xml
index 38bb783..e65d0b9 100644
--- a/packages/SystemUI/res/layout/volume_ringer_button.xml
+++ b/packages/SystemUI/res/layout/volume_ringer_button.xml
@@ -26,7 +26,7 @@
android:layout_marginBottom="@dimen/volume_dialog_components_spacing"
android:contentDescription="@string/volume_ringer_mode"
android:gravity="center"
- android:tint="?androidprv:attr/materialColorOnSurface"
+ android:tint="@androidprv:color/materialColorOnSurface"
android:src="@drawable/volume_ringer_item_bg"
android:background="@drawable/volume_ringer_item_bg"/>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index b91bfd6..cef0316 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -38,7 +38,7 @@
<string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Laat <xliff:g id="APPLICATION">%1$s</xliff:g> toe om by <xliff:g id="USB_DEVICE">%2$s</xliff:g> in te gaan?\nOpneemtoestemming is nie aan hierdie app verleen nie, maar dit kan oudio deur hierdie USB-toestel vasvang."</string>
<string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Gee <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Maak <xliff:g id="APPLICATION">%1$s</xliff:g> oop om <xliff:g id="USB_DEVICE">%2$s</xliff:g> te hanteer?"</string>
- <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Opneemtoestemming is nie aan hierdie program verleen nie, maar dit kan oudio deur hierdie USB-toestel opneem. As jy <xliff:g id="APPLICATION">%1$s</xliff:g> met hierdie toestel gebruik, kan dit verhinder dat jy oproepe, kennisgewings en wekkers hoor."</string>
+ <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Opneemtoestemming is nie aan hierdie app verleen nie, maar dit kan oudio deur hierdie USB-toestel opneem. As jy <xliff:g id="APPLICATION">%1$s</xliff:g> met hierdie toestel gebruik, kan dit verhinder dat jy oproepe, kennisgewings en wekkers hoor."</string>
<string name="usb_audio_device_prompt" msgid="7944987408206252949">"As jy <xliff:g id="APPLICATION">%1$s</xliff:g> met hierdie toestel gebruik, kan dit verhinder dat jy oproepe, kennisgewings en wekkers hoor."</string>
<string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Gee <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Hanteer <xliff:g id="USB_DEVICE">%2$s</xliff:g> met <xliff:g id="APPLICATION">%1$s</xliff:g>?"</string>
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Kennisgewings"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Gesprekke"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vee alle stil kennisgewings uit"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Kennisgewings onderbreek deur Moenie Steur Nie"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Geen kennisgewings nie}=1{Kennisgewings is deur {mode} onderbreek}=2{Kennisgewings is deur {mode} en een ander modus onderbreek}other{Kennisgewings is deur {mode} en # ander modusse onderbreek}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Begin nou"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Kopnasporing"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tik om luiermodus te verander"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"luiermodus"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"demp"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ontdemp"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibreer"</string>
@@ -1203,8 +1207,8 @@
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ontkoppel)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan nie wissel nie. Tik om weer te probeer."</string>
<string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Koppel ’n toestel"</string>
- <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Maak die program oop om hierdie sessie uit te saai."</string>
- <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende program"</string>
+ <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Maak die app oop om hierdie sessie uit te saai."</string>
+ <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende app"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Hou op uitsaai"</string>
<string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Beskikbare toestelle vir oudio-uitsette."</string>
<string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Druk die handelingsleutel op jou sleutelbord"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Welgedaan!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Jy het die Bekyk Onlangse Apps-gebaar voltooi"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Sleutelbordlig"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Vlak %1$d van %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Huiskontroles"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index cf73b71..5f77743 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ምግብር በመጠቀም መተግበሪያ ለመክፈት እርስዎ መሆንዎን ማረጋገጥ አለብዎት። እንዲሁም የእርስዎ ጡባዊ በተቆለፈበት ጊዜ እንኳን ማንኛውም ሰው እነሱን ማየት እንደሚችል ከግምት ውስጥ ያስገቡ። አንዳንድ ምግብሮች ለማያ ገፅ ቁልፍዎ የታሰቡ ላይሆኑ ይችላሉ እና እዚህ ለማከል አስተማማኝ ላይሆኑ ይችላሉ።"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ገባኝ"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ምግብሮች"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"የ«ምግብሮች» አቋራጭን ለማከል በቅንብሮች ውስጥ «ምግብሮችን በማያ ገፅ ቁልፍ ላይ አሳይ» የሚለው መንቃቱን ያረጋግጡ።"</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"ቅንብሮች"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ተጠቃሚ ቀይር"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ወደታች ተጎታች ምናሌ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"በዚህ ክፍለ-ጊዜ ውስጥ ያሉ ሁሉም መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ማሳወቂያዎች"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ውይይቶች"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ሁሉንም ጸጥ ያሉ ማሳወቂያዎችን ያጽዱ"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ማሳወቂያዎች በአትረብሽ ባሉበት ቆመዋል"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{ምንም ማሳወቂያዎች የሉም}=1{ማሳወቂያዎች በ{mode} ባሉበት ቆመዋል}=2{ማሳወቂያዎች በ{mode} እና አንድ ሌላ ሁነታ ባሉበት ቆመዋል}one{ማሳወቂያዎች በ{mode} እና # ሌላ ሁነታ ባሉበት ቆመዋል}other{ማሳወቂያዎች በ{mode} እና # ሌላ ሁነታዎች ባሉበት ቆመዋል}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"አሁን ጀምር"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"የጭንቅላት ክትትል"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"የደዋይ ሁነታን ለመቀየር መታ ያድርጉ"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ደዋይ ሁነታ"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ድምጸ-ከል አድርግ"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ድምጸ-ከልን አንሳ"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ንዘር"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"የቁልፍ ሰሌዳ አቋራጮች"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"የቁልፍ ሰሌዳ አቋራጮችን ያብጁ"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"አቋራጭ ይወገድ?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ወደ ነባሪ ዳግም ይጀመር?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"አቋራጭ ለመመደብ ቁልፍ ይጫኑ"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ይህ ብጁ አቋራጭዎን በቋሚነት ይሰርዛል።"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"ይህ ሁሉንም ብጁ አቋራጮችዎን በቋሚነት ይሰርዛል።"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"የፍለጋ አቋራጮች"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ምንም የፍለጋ ውጤቶች የሉም"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"መሰብሰቢያ አዶ"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"የቁልፍ ሰሌዳ ቅንብሮች"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"አቋራጭ አቀናብር"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"አስወግድ"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"አዎ፣ ዳግም አስጀምር"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ይቅር"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ቁልፍ ይጫኑ"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"የቁልፍ ጥምረት አስቀድሞ በሥራ ላይ ነው። ሌላ ቁልፍ ይሞክሩ።"</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"በቁልፍ ሰሌዳዎ ላይ ያለውን የተግባር ቁልፍ ይጫኑ"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ጥሩ ሠርተዋል!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"የሁሉንም መተግበሪያዎች አሳይ ምልክትን አጠናቅቀዋል"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"የቁልፍ ሰሌዳ የጀርባ ብርሃን"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"ደረጃ %1$d ከ %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"የቤት ውስጥ ቁጥጥሮች"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 4ff6131..dd6e850 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"لفتح تطبيق باستخدام تطبيق مصغَّر، عليك إثبات هويتك. يُرجى ملاحظة أنّ أي شخص يمكنه الاطّلاع محتوى التطبيقات المصغَّرة، حتى وإن كان جهازك اللوحي مُقفلاً. بعض التطبيقات المصغّرة قد لا تكون مُصمَّمة لإضافتها إلى شاشة القفل، وقد يكون هذا الإجراء غير آمن."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"حسنًا"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"التطبيقات المصغَّرة"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"لإضافة اختصار \"التطبيقات المصغّرة\"، يجب تفعيل خيار \"عرض التطبيقات المصغّرة على شاشة القفل\" من خلال الإعدادات."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"الإعدادات"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تبديل المستخدم"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"القائمة المنسدلة"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"سيتم حذف كل التطبيقات والبيانات في هذه الجلسة."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"الإشعارات"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"المحادثات"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"محو جميع الإشعارات الصامتة"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"تم إيقاف الإشعارات مؤقتًا وفقًا لإعداد \"عدم الإزعاج\""</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{ما مِن إشعارات}=1{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\"}=2{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\" ووضع واحد آخر}few{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\" و# أوضاع أخرى}many{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\" و# وضعًا آخر}other{تم إيقاف الإشعارات مؤقتًا بواسطة \"{mode}\" و# وضع آخر}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"البدء الآن"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"تتبُّع حركة الرأس"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"انقر لتغيير وضع الرنين."</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"وضع الرنين"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"كتم الصوت"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"إعادة الصوت"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"اهتزاز"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"اختصارات لوحة المفاتيح"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"تخصيص اختصارات لوحة المفاتيح"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"هل تريد إزالة هذا الاختصار؟"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"يُرجى تأكيد إعادة الضبط على الإعدادات التلقائية"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"اضغط على مفتاح لتخصيص الاختصار"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"سيؤدي هذا الإجراء إلى حذف الاختصار المخصّص نهائيًا."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"سيؤدي هذا الإجراء إلى حذف جميع الاختصارات المخصّصة نهائيًا."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"البحث في الاختصارات"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ما مِن نتائج بحث"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"رمز التصغير"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"إعدادات لوحة المفاتيح"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ضبط الاختصار"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"إزالة"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"نعم، أريد إعادة الضبط"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"إلغاء"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"اضغط على مفتاح"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"يتم حاليًا استخدام مجموعة المفاتيح هذه. يُرجى تجربة مفتاح آخر."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"اضغط على مفتاح الإجراء في لوحة المفاتيح"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"أحسنت!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"لقد أكملْت التدريب على إيماءة عرض جميع التطبيقات"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"الإضاءة الخلفية للوحة المفاتيح"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"مستوى الإضاءة: %1$d من %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"إدارة المنزل آليًّا"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index f91a3b0..86e13055 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"এটা ৱিজেট ব্যৱহাৰ কৰি কোনো এপ্ খুলিবলৈ, এয়া আপুনিয়েই বুলি সত্যাপন পৰীক্ষা কৰিব লাগিব। লগতে, মনত ৰাখিব যে যিকোনো লোকেই সেইবোৰ চাব পাৰে, আনকি আপোনাৰ টেবলেটটো লক হৈ থাকিলেও। কিছুমান ৱিজেট হয়তো আপোনাৰ লক স্ক্ৰীনৰ বাবে কৰা হোৱা নাই আৰু ইয়াত যোগ কৰাটো অসুৰক্ষিত হ’ব পাৰে।"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"বুজি পালোঁ"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ৱিজেট"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"ৱিজেট\"ৰ শ্বৰ্টকাট যোগ দিবলৈ, ছেটিঙত \"লক স্ক্ৰীনত ৱিজেট দেখুৱাওক\" সক্ষম কৰি থোৱাটো নিশ্চিত কৰক।"</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"ছেটিং"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যৱহাৰকাৰী সলনি কৰক"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুল-ডাউনৰ মেনু"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই ছেশ্বনৰ আটাইবোৰ এপ্ আৰু ডেটা মচা হ\'ব।"</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"জাননীসমূহ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"বাৰ্তালাপ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"আটাইবোৰ নীৰৱ জাননী মচক"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"অসুবিধা নিদিব-ই জাননী পজ কৰিছে"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{কোনো জাননী নাই}=1{{mode}এ জাননী পজ কৰিছে}=2{{mode} আৰু আন এটা ম’ডে জাননী পজ কৰিছে}one{{mode} আৰু আন # টা ম’ডে জাননী পজ কৰিছে}other{{mode} আৰু আন # টা ম’ডে জাননী পজ কৰিছে}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"এতিয়াই আৰম্ভ কৰক"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"হে’ড ট্ৰেকিং"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ৰিংগাৰ ম’ড সলনি কৰিবলৈ টিপক"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ৰিংগাৰ ম’ড"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"মিউট কৰক"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"আনমিউট কৰক"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"কম্পন কৰক"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"কীব’ৰ্ডৰ শ্বৰ্টকাট"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"কীব’ৰ্ডৰ শ্বৰ্টকাট কাষ্টমাইজ কৰক"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"শ্বৰ্টকাট আঁতৰাবনে?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ডিফ\'ল্ট হিচাপে পুনৰ ৰিছেট কৰিবনে?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"শ্বৰ্টকাটৰ ভূমিকা অৰ্পণ কৰিবলৈ কী টিপক"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"এইটোৱে আপোনাৰ কাষ্টম শ্বৰ্টকাট মচিব।"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"এইটোৱে আপোনাৰ আটাইবোৰ কাষ্টম শ্বৰ্টকাট স্থায়ীভাৱে মচিব।"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"সন্ধানৰ শ্বৰ্টকাট"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"সন্ধানৰ কোনো ফলাফল নাই"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"সংকোচন কৰাৰ চিহ্ন"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"কীব’ৰ্ডৰ ছেটিং"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"শ্বৰ্টকাট ছেট কৰক"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"আঁতৰাওক"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"হয়, ৰিছেট কৰক"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"বাতিল কৰক"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"কী টিপক"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"কীৰ মিশ্ৰণ ইতিমধ্যে ব্যৱহাৰ হৈ আছে। অন্য এটা কী ব্যৱহাৰ কৰি চাওক।"</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"আপোনাৰ কীব’ৰ্ডৰ কাৰ্য কীটোত টিপক"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"বঢ়িয়া!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"আপুনি আটাইবোৰ এপ্ চোৱাৰ নিৰ্দেশনাটো সম্পূৰ্ণ কৰিছে"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"কীব’ৰ্ডৰ বেকলাইট"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dৰ %1$d স্তৰ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ঘৰৰ সা-সৰঞ্জামৰ নিয়ন্ত্ৰণ"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 84299dc..3082284 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirişlər"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Söhbətlər"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Səssiz bildirişlərin hamısını silin"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bildirişlər \"Narahat Etməyin\" rejimi tərəfindən dayandırıldı"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Bildiriş yoxdur}=1{Bildirişlər {mode} tərəfindən dayandırıldı}=2{Bildirişlər {mode} və digər rejim tərəfindən dayandırıldı}other{Bildirişlər {mode} və # digər rejim tərəfindən dayandırıldı}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"İndi başlayın"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Baş izləməsi"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Zəng rejimini dəyişmək üçün toxunun"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"zəng səsi rejimi"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"susdurun"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"səssiz rejimdən çıxarın"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrasiya"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Klaviaturada fəaliyyət açarına basın"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Əla!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"\"Bütün tətbiqlərə baxın\" jestini tamamladınız"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatura işığı"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Səviyyə %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ev nizamlayıcıları"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index bc385a1..09aef06 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da biste otvorili aplikaciju koja koristi vidžet, treba da potvrdite da ste to vi. Imajte u vidu da svako može da ga vidi, čak i kada je tablet zaključan. Neki vidžeti možda nisu namenjeni za zaključani ekran i možda nije bezbedno da ih tamo dodate."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Važi"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Vidžeti"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Da biste dodali prečicu Vidžeti, uverite se da je u podešavanjima omogućeno Prikazuj vidžete na zaključanom ekranu."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Podešavanja"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zameni korisnika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Obaveštenja"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzacije"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obrišite sva nečujna obaveštenja"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obaveštenja su pauzirana režimom Ne uznemiravaj"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nema obaveštenja}=1{Obaveštenja je pauzirao {mode}}=2{Obaveštenja su pauzirali {mode} i još jedan režim}one{Obaveštenja su pauzirali {mode} i još # režim}few{Obaveštenja su pauzirali {mode} i još # režima}other{Obaveštenja su pauzirali {mode} i još # režima}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Započni"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Praćenje glave"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da biste promenili režim zvona"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"režim zvona"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibracija"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tasterske prečice"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite tasterske prečice"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Želite da uklonite prečicu?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Želite da resetujete na podrazumevano?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pritisnite taster da biste dodelili prečicu"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Ovim ćete trajno izbrisati prilagođenu prečicu."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Time ćete trajno izbrisati sve prilagođene prečice."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pretražite prečice"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretrage"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za skupljanje"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Podešavanja tastature"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Podesi prečicu"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Ukloni"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Da, resetuj"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Otkaži"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite taster"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinacija tastera se već koristi. Probajte sa drugim tasterom."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite taster radnji na tastaturi"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Odlično!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Dovršili ste pokret za prikazivanje svih aplikacija."</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvetljenje tastature"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrole za dom"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index a5f4da9..51cc35a 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Каб адкрыць праграму з дапамогай віджэта, вам неабходна будзе пацвердзіць сваю асобу. Таксама памятайце, што такія віджэты могуць пабачыць іншыя людзі, нават калі экран планшэта заблакіраваны. Некаторыя віджэты могуць не падыходзіць для выкарыстання на экране блакіроўкі, і дадаваць іх сюды можа быць небяспечна."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Зразумела"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Віджэты"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Каб дадаць спалучэнне клавіш \"Віджэты\", у наладах павінна быць уключана функцыя \"Паказваць віджэты на экране блакіроўкі\"."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Налады"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Перайсці да іншага карыстальніка"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"высоўнае меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усе праграмы і даныя гэтага сеанса будуць выдалены."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Апавяшчэнні"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Размовы"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Выдаліць усе апавяшчэнні без гуку"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Паказ апавяшчэнняў прыпынены ў рэжыме \"Не турбаваць\""</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Апавяшчэнняў няма}=1{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\"}=2{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ адным рэжымам}one{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ # рэжымам}few{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ # рэжымамі}many{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ # рэжымамі}other{Атрыманне апавяшчэнняў прыпынена рэжымам \"{mode}\" і яшчэ # рэжыму}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Пачаць зараз"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Адсочваць рух галавы"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Націсніце, каб змяніць рэжым званка"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"рэжым званка"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"выключыць гук"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"уключыць гук"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вібрыраваць"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Спалучэнні клавіш"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Наладзіць спалучэнні клавіш"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Выдаліць спалучэнне клавіш?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Скінуць налады да стандартных?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Націсніце клавішу, каб прызначыць спалучэнне клавіш"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Гэта дзеянне назаўсёды выдаліць прызначанае вамі спалучэнне клавіш."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Усе карыстальніцкія спалучэнні клавіш будуць назаўсёды выдалены."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пошук спалучэнняў клавіш"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма вынікаў пошуку"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Згарнуць\""</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Налады клавіятуры"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Наладзіць спалучэнне клавіш"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Выдаліць"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Так, скінуць"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Скасаваць"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Націсніце клавішу"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Гэта спалучэнне клавіш ужо выкарыстоўваецца. Паспрабуйце іншую клавішу."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Націсніце клавішу дзеяння на клавіятуры"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Выдатна!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Вы навучыліся рабіць жэст для прагляду ўсіх праграм"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Падсветка клавіятуры"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Узровень %1$d з %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Кіраванне домам"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index e36cf30..12e25cc 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Известия"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Разговори"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Изчистване на всички беззвучни известия"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Известията са поставени на пауза от режима „Не безпокойте“"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Няма известия}=1{Известията са поставени на пауза от {mode}}=2{Известията са поставени на пауза от {mode} и един друг режим}other{Известията са поставени на пауза от {mode} и # други режима}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Стартиране сега"</string>
@@ -707,6 +709,7 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Прослед. на движенията на главата"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Докоснете, за да промените режима на звънене"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"режим на звънене"</string>
+ <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>: докоснете, за да промените режима на звънене"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"спиране"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"пускане"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибриране"</string>
@@ -1482,6 +1485,7 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Натиснете клавиша за действия на клавиатурата си"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Браво!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Изпълнихте жеста за преглед на всички приложения"</string>
+ <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Анимация за урока. Кликнете, за да поставите на пауза и да възобновите възпроизвеждането."</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Подсветка на клавиатурата"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Ниво %1$d от %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Контроли за дома"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 8f5effc..8af32a8 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"বিজ্ঞপ্তি"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"কথোপকথন"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"সব নীরব বিজ্ঞপ্তি মুছুন"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'বিরক্ত করবে না\' দিয়ে বিজ্ঞপ্তি পজ করা হয়েছে"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{কোনও বিজ্ঞপ্তি নেই}=1{{mode}-এর জন্য বিজ্ঞপ্তি পজ করা হয়েছে}=2{{mode} ও অন্য আরেকটি মোডের জন্য বিজ্ঞপ্তি পজ করা হয়েছে}one{{mode} ও অন্য #টি মোডের জন্য বিজ্ঞপ্তি পজ করা হয়েছে}other{{mode} ও অন্য #টি মোডের জন্য বিজ্ঞপ্তি পজ করা হয়েছে}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"এখন শুরু করুন"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"হেড ট্র্যাকিং"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"রিঙ্গার মোড পরিবর্তন করতে ট্যাপ করুন"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"রিঙ্গার মোড"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"মিউট করুন"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"আনমিউট করুন"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ভাইব্রেট করান"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"আপনার কীবোর্ডে অ্যাকশন কী প্রেস করুন"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"দারুণ!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"আপনি \'সব অ্যাপের জেসচার দেখুন\' টিউটোরিয়াল সম্পূর্ণ করেছেন"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"কীবোর্ড ব্যাকলাইট"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-এর মধ্যে %1$d লেভেল"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"হোম কন্ট্রোল"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 0a88d44..fe38ba8 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da otvorite aplikaciju pomoću vidžeta, morat ćete potvrditi identitet. Također imajte na umu da ih svako može pregledati, čak i ako je tablet zaključan. Neki vidžeti možda nisu namijenjeni za vaš zaključani ekran i njihovo dodavanje ovdje možda nije sigurno."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Razumijem"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Vidžeti"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Da biste dodali prečac Widgeti, provjerite je li u postavkama omogućena opcija Prikaži widgete na zaključanom zaslonu."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Postavke"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zamijeni korisnika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Obavještenja"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Razgovori"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Obriši sva nečujna obavještenja"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Obavještenja su pauzirana načinom rada Ne ometaj"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nema obavještenja}=1{Obavještenja su pauzirana putem načina rada {mode}}=2{Obavještenja su pauzirana putem načina rada {mode} i još jednog načina rada}one{Obavještenja su pauzirana putem načina rada {mode} i još # načina rada}few{Obavještenja su pauzirana putem načina rada {mode} i još # načina rada}other{Obavještenja su pauzirana putem načina rada {mode} i još # načina rada}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Započni odmah"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Praćenje položaja glave"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da promijenite način rada zvuka zvona"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"način rada za zvuk zvona"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibriranje"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Prečice tastature"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite prečice na tastaturi"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Ukloniti prečicu?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Želite li vratiti na zadano?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pritisnite tipku da dodijelite prečicu"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Ovo će trajno izbrisati prilagođenu prečicu."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Time će se trajno izbrisati svi vaši prilagođeni prečaci."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečica pretraživanja"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sužavanja"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Postavke tastature"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Postavi prečicu"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Ukloni"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Da, vrati na zadano"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Otkaži"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipku"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ta se kombinacija tipki već koristi. Pokušajte s drugom tipkom."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite tipku radnji na tastaturi"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Odlično!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Izvršili ste pokret za prikaz svih aplikacija"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tastature"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrole za dom"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 614fe23..ba3c4ad 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Per obrir una aplicació utilitzant un widget, necessitaràs verificar la teva identitat. També has de tenir en compte que qualsevol persona pot veure els widgets, fins i tot quan la tauleta està bloquejada. És possible que alguns widgets no estiguin pensats per a la pantalla de bloqueig i que no sigui segur afegir-los-hi."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entesos"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgets"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Per afegir la drecera Widgets, assegura\'t que l\'opció Mostra els widgets a la pantalla de bloqueig estigui activada a la configuració."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Configuració"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Canvia d\'usuari"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificacions"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Converses"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Esborra totes les notificacions silencioses"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificacions pausades pel mode No molestis"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No hi ha cap notificació}=1{{mode} ha posat en pausa les notificacions}=2{{mode} i un altre mode han posat en pausa les notificacions}many{{mode} i # de modes més han posat en pausa les notificacions}other{{mode} i # modes més han posat en pausa les notificacions}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Comença ara"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seguiment del cap"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Toca per canviar el mode de timbre"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"mode de timbre"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"deixar de silenciar"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tecles de drecera"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalitza les tecles de drecera"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Vols suprimir la drecera?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Vols restablir els valors predeterminats?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Prem la tecla per assignar la drecera"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Aquesta acció suprimirà la drecera personalitzada permanentment."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Aquesta acció suprimirà totes les dreceres personalitzades permanentment."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Dreceres de cerca"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hi ha cap resultat de la cerca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Replega la icona"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Configuració del teclat"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Configura la drecera"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Suprimeix"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Sí, restableix"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel·la"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Prem una tecla"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"La combinació de tecles ja s\'està utilitzant. Prova-ho amb una altra tecla."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Prem la tecla d\'acció al teclat"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Enhorabona!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Has completat el gest per veure totes les aplicacions"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroil·luminació del teclat"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivell %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controls de la llar"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 9d5a97a..317061f 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Oznámení"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzace"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vymazat všechna tichá oznámení"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Oznámení jsou pozastavena režimem Nerušit"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Žádná oznámení}=1{Oznámení jsou pozastavená režimem {mode}}=2{Oznámení jsou pozastavená režimem {mode} a 1 dalším}few{Oznámení jsou pozastavená režimem {mode} a # dalšími}many{Oznámení jsou pozastavená režimem {mode} a # dalšího}other{Oznámení jsou pozastavená režimem {mode} a # dalšími}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Spustit"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Sledování hlavy"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Klepnutím změníte režim vyzvánění"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"režim vyzvánění"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnout zvuk"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnout zvuk"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrovat"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Stiskněte akční klávesu na klávesnici"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Výborně!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Provedli jste gesto k zobrazení všech aplikací"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvícení klávesnice"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Úroveň %1$d z %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ovládání domácnosti"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 53f3462..3c0dc42 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifikationer"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Samtaler"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ryd alle lydløse notifikationer"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifikationer er sat på pause af Forstyr ikke"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Ingen notifikationer}=1{Notifikationer er sat på pause af {mode}}=2{Notifikationer er sat på pause af {mode} og én anden tilstand}one{Notifikationer er sat på pause af {mode} og # anden tilstand}other{Notifikationer er sat på pause af {mode} og # andre tilstande}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Start nu"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Hovedregistrering"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tryk for at ændre ringetilstand"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ringetilstand"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"slå lyden fra"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå lyden til"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrer"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tryk på handlingstasten på dit tastatur"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Flot klaret!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Du har udført bevægelsen for at se alle apps"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturets baggrundslys"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d af %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Hjemmestyring"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index e40445a..8d13524 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Benachrichtigungen"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Unterhaltungen"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Alle lautlosen Benachrichtigungen löschen"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Benachrichtigungen durch „Bitte nicht stören“ pausiert"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Keine Benachrichtigungen}=1{Benachrichtigungen durch {mode} pausiert}=2{Benachrichtigungen durch {mode} und einen weiteren Modus pausiert}other{Benachrichtigungen durch {mode} und # weitere Modi pausiert}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Jetzt starten"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Erfassung von Kopfbewegungen"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Zum Ändern des Klingeltonmodus tippen"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"Klingeltonmodus"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"Stummschalten"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"Aufheben der Stummschaltung"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"Vibrieren lassen"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Drücke die Aktionstaste auf deiner Tastatur"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Perfekt!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Du hast das Tutorial für die Touch-Geste zum Aufrufen aller Apps abgeschlossen"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturbeleuchtung"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d von %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Smart-Home-Steuerung"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 43fa01a..b6de539 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Ειδοποιήσεις"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Συζητήσεις"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Διαγραφή όλων των ειδοποιήσεων σε σίγαση"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία \"Μην ενοχλείτε\""</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Δεν υπάρχουν ειδοποιήσεις}=1{Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία {mode}}=2{Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία {mode} και μία άλλη λειτουργία}other{Οι ειδοποιήσεις τέθηκαν σε παύση από τη λειτουργία {mode} και # άλλες λειτουργίες}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Έναρξη τώρα"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Παρακ. κίνησ. κεφαλής"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Πατήστε για να αλλάξετε τη λειτουργία ειδοποίησης ήχου"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"λειτουργία ειδοποίησης ήχου"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"σίγαση"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"κατάργηση σίγασης"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"δόνηση"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Πατήστε το πλήκτρο ενέργειας στο πληκτρολόγιό σας"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Μπράβο!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Ολοκληρώσατε την κίνηση για την προβολή όλων των εφαρμογών"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Οπίσθιος φωτισμός πληκτρολογίου"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Επίπεδο %1$d από %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Οικιακοί έλεγχοι"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index d32c95a..609e7af 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No notifications}=1{Notifications paused by {mode}}=2{Notifications paused by {mode} and one other mode}other{Notifications paused by {mode} and # other modes}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head tracking"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ringer mode"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"You completed the view all apps gesture"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 8a7420d..be4e81f 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -591,6 +591,7 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+ <string name="accessibility_notification_section_header_open_settings" msgid="6235202417954844004">"Open notifications settings"</string>
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No notifications}=1{Notifications paused by {mode}}=2{Notifications paused by {mode} and one other mode}other{Notifications paused by {mode} and # other modes}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
@@ -705,6 +706,7 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head Tracking"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ringer mode"</string>
+ <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>, tap to change ringer mode"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string>
@@ -1434,8 +1436,7 @@
<string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Action or Meta key icon"</string>
<string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus icon"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Customize"</string>
- <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
- <skip />
+ <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Reset"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Done"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
@@ -1477,6 +1478,7 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"You completed the view all apps gesture"</string>
+ <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Tutorial animation, click to pause and resume play."</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home Controls"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index d32c95a..609e7af 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No notifications}=1{Notifications paused by {mode}}=2{Notifications paused by {mode} and one other mode}other{Notifications paused by {mode} and # other modes}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head tracking"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ringer mode"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"You completed the view all apps gesture"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index d32c95a..609e7af 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Clear all silent notifications"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications paused by Do Not Disturb"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No notifications}=1{Notifications paused by {mode}}=2{Notifications paused by {mode} and one other mode}other{Notifications paused by {mode} and # other modes}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Head tracking"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ringer mode"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"You completed the view all apps gesture"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 711f771..177e690 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificaciones"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversaciones"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borrar todas las notificaciones silenciosas"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificaciones pausadas por el modo \"No interrumpir\""</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No hay notificaciones}=1{{mode} pausó las notificaciones}=2{{mode} y un modo más pausaron las notificaciones}many{{mode} y # de modos más pausaron las notificaciones}other{{mode} y # modos más pausaron las notificaciones}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Comenzar ahora"</string>
@@ -707,6 +709,7 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Monitoreo de cabeza"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Presiona para cambiar el modo de timbre"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"modo de timbre"</string>
+ <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>, presiona para cambiar el modo de timbre"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1482,6 +1485,7 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Presiona la tecla de acción en el teclado"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"¡Bien hecho!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Completaste el gesto para ver todas las apps"</string>
+ <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animación del instructivo. Haz clic para pausar y reanudar la reproducción."</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controles de la casa"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 4a94cdf..53289d1 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -306,7 +306,7 @@
<string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string>
<string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectado"</string>
<string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Compartir audio"</string>
- <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active" msgid="8680997711431098238">"Permite compartir audio"</string>
+ <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active" msgid="8680997711431098238">"Admite Compartir audio"</string>
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Guardado"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activar"</string>
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir una aplicación usando un widget, deberás verificar que eres tú. Además, ten en cuenta que cualquier persona podrá verlos, incluso aunque tu tablet esté bloqueada. Es posible que algunos widgets no estén pensados para la pantalla de bloqueo y no sea seguro añadirlos aquí."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Entendido"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgets"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Para añadir el acceso directo Widgets, asegúrate de que la opción Mostrar widgets en la pantalla de bloqueo esté habilitada en los ajustes."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Ajustes"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar de usuario"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificaciones"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversaciones"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borrar todas las notificaciones silenciosas"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificaciones pausadas por el modo No molestar"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{No hay notificaciones}=1{Notificaciones pausadas por {mode}}=2{Notificaciones pausadas por {mode} y un modo más}many{Notificaciones pausadas por {mode} y # modos más}other{Notificaciones pausadas por {mode} y # modos más}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Empezar ahora"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seguimiento de cabeza"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Toca para cambiar el modo de timbre"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"modo de timbre"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar las combinaciones de teclas"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"¿Eliminar combinación de teclas?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"¿Restablecer valores predeterminados?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pulsa una tecla para asignar una combinación de teclas"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Se eliminará tu combinación de teclas personalizada de forma permanente."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Se eliminarán todos tus accesos directos personalizados de forma permanente."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atajos de búsqueda"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hay resultados de búsqueda"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icono de contraer"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ajustes del teclado"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Establecer combinación de teclas"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Eliminar"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Sí, restablecer"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pulsa una tecla"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"La combinación de teclas ya se está usando. Prueba con otra tecla."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pulsa la tecla de acción de tu teclado"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"¡Muy bien!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Has completado el gesto para ver todas las aplicaciones"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controles de la casa"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 4027bbd..165f9c2 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Märguanded"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Vestlused"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Kustuta kõik hääletud märguanded"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Režiim Mitte segada peatas märguanded"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Märguandeid pole}=1{{mode} peatas märguanded}=2{{mode} ja veel üks režiim peatasid märguanded}other{{mode} ja veel # režiimi peatasid märguanded}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Alusta kohe"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Pea jälgimine"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Puudutage telefonihelina režiimi muutmiseks"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"telefonihelina režiim"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vaigistamine"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"vaigistuse tühistamine"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibreerimine"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Vajutage klaviatuuril toiminguklahvi"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Hästi tehtud!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Tegite kõigi rakenduste vaatamise liigutuse"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatuuri taustavalgustus"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Tase %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kodu juhtelemendid"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index a0ba1b7..46bbdc3 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Jakinarazpenak"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Elkarrizketak"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Garbitu soinurik gabeko jakinarazpen guztiak"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ez molestatzeko moduak pausatu egin ditu jakinarazpenak"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Ez dago jakinarazpenik}=1{Modu honek jakinarazpenak pausatu ditu: {mode}}=2{Modu honek eta beste modu batek jakinarazpenak pausatu dituzte: {mode}}other{Modu honek eta beste # moduk jakinarazpenak pausatu dituzte: {mode}}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Hasi"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Buruaren jarraipena"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Sakatu tonu-jotzailearen modua aldatzeko"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"tonu-jotzailearen modua"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desaktibatu audioa"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktibatu audioa"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"dardara"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Sakatu teklatuko ekintza-tekla"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bikain!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Osatu duzu aplikazio guztiak ikusteko keinua"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Teklatuaren hondoko argia"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d/%2$d maila"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Etxeko gailuen kontrola"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 7bd01bc..5e68a95c 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"اعلانها"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"مکالمهها"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"پاک کردن همه اعلانهای بیصدا"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"اعلانها توسط «مزاحم نشوید» موقتاً متوقف شدند"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{اعلانی موقتاً متوقف نشده است}=1{اعلانها را «{mode}» موقتاً متوقف کرده است}=2{اعلانها را «{mode}» و یک حالت دیگر موقتاً متوقف کرداند}one{اعلانها را «{mode}» و # حالت دیگر موقتاً متوقف کردهاند}other{اعلانها را «{mode}» و # حالت دیگر موقتاً متوقف کردهاند}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"اکنون شروع کنید"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ردیابی سر"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"برای تغییر حالت زنگ، تکضرب بزنید"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"حالت زنگ"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"صامت کردن"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"باصدا کردن"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"لرزش"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"دکمه کنش را روی صفحه لمسی فشار دهید"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"عالی بود!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"اشاره «مشاهده همه برنامهها» را تمام کردید"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"نور پسزمینه صفحهکلید"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"سطح %1$d از %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"کنترل خانه هوشمند"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index e617451..94b6364 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Jos haluat avata sovelluksen käyttämällä widgetiä, sinun täytyy vahvistaa henkilöllisyytesi. Muista myös, että widgetit näkyvät kaikille, vaikka tabletti olisi lukittuna. Jotkin widgetit on ehkä tarkoitettu lukitusnäytölle, ja niiden lisääminen tänne ei välttämättä ole turvallista."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Selvä"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgetit"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Jos haluat lisätä Widgetit-pikakuvakkeen, varmista, että \"Näytä widgetit lukitusnäytöllä\" on käytössä asetuksissa."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Asetukset"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Vaihda käyttäjää"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"alasvetovalikko"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Ilmoitukset"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Keskustelut"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Tyhjennä kaikki hiljaiset ilmoitukset"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Älä häiritse ‑tila keskeytti ilmoitukset"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Ei ilmoituksia}=1{{mode} keskeytti ilmoitukset}=2{{mode} ja yksi muu tila keskeytti ilmoitukset}other{{mode} ja # muuta tilaa keskeytti ilmoitukset}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Aloita nyt"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Pään seuranta"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Vaihda soittoäänen tilaa napauttamalla"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"Soittoäänen tila"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mykistä"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"poista mykistys"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"värinä"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pikanäppäimet"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pikanäppäimien muokkaaminen"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Poistetaanko pikanäppäin?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Palautetaanko oletusasetukset?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Määritä pikanäppäin painamalla näppäintä"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Oma pikanäppäin poistetaan pysyvästi."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Kaikki omat pikanäppäimet poistetaan pysyvästi."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pikahaut"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ei hakutuloksia"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tiivistyskuvake"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Näppäimistön asetukset"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Valitse pikanäppäin"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Poista"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Kyllä, nollaa"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Peru"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Paina näppäintä"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Näppäinyhdistelmä on jo käytössä. Kokeile toista näppäintä."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Paina näppäimistön toimintonäppäintä"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Hienoa!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Olet oppinut Näytä kaikki sovellukset ‑eleen."</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Näppämistön taustavalo"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Taso %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kodin ohjaus"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 6213dd5..ea9ee0b 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Effacer toutes les notifications silencieuses"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Les notifications sont suspendues par le mode Ne pas déranger"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Aucune notification}=1{Notifications suspendues par {mode}}=2{Notifications suspendues par {mode} et un autre mode}one{Notifications suspendues par {mode} et # autre mode}many{Notifications suspendues par {mode} et # d\'autres modes}other{Notifications suspendues par {mode} et # autres modes}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Suivi de la tête"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Touchez pour modifier le mode de sonnerie"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"mode de sonnerie"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"désactiver le son"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibration"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Appuyez sur la touche d\'action de votre clavier"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Félicitations!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Vous avez appris le geste pour afficher toutes les applis"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Domotique"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index d0931a6..bda70d9 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifications"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Effacer toutes les notifications silencieuses"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifications suspendues par le mode Ne pas déranger"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Aucune notification}=1{Notifications suspendues par le mode {mode}}=2{Notifications suspendues par le mode {mode} et un autre mode}one{Notifications suspendues par le mode {mode} et # autre mode}many{Notifications suspendues par le mode {mode} et # d\'autres modes}other{Notifications suspendues par le mode {mode} et # autres modes}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Suivi de la tête"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Appuyez pour changer le mode de la sonnerie"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"mode de sonnerie"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"couper le son"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"activer le vibreur"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Appuyez sur la touche d\'action de votre clavier"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bravo !"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Vous avez appris le geste pour afficher toutes les applis"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d sur %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Contrôle de la maison"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index a02206d..53c4417 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificacións"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Borrar todas as notificacións silenciadas"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"O modo Non molestar puxo en pausa as notificacións"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Non hai ningunha notificación}=1{Notificacións postas en pausa polo modo {mode}}=2{Notificacións postas en pausa polo modo {mode} e un máis}other{Notificacións postas en pausa polo modo {mode} e # máis}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seguimento da cabeza"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Toca para cambiar o modo de timbre"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"modo de timbre"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"activar o son"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Preme a tecla de acción do teclado"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Ben feito!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Completaches o titorial do xesto de ver todas as aplicacións"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación do teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controis domóticos"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 8cff7ff..8ff5717 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"વિજેટનો ઉપયોગ કરીને ઍપ ખોલવા માટે, તમારે એ ચકાસણી કરવાની જરૂર રહેશે કે આ તમે જ છો. તે ઉપરાંત, ધ્યાનમાં રાખો કે તમારું ટૅબ્લેટ લૉક કરેલું હોય તો પણ કોઈપણ વ્યક્તિ તેમને જોઈ શકે છે. અમુક વિજેટ કદાચ તમારી લૉક સ્ક્રીન માટે બનાવવામાં આવ્યા ન હોઈ શકે છે અને તેમને અહીં ઉમેરવાનું અસલામત હોઈ શકે છે."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"સમજાઈ ગયું"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"વિજેટ"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"વિજેટ\"નો શૉર્ટકટ ઉમેરવા માટે, ખાતરી કરો કે સેટિંગમાં \"લૉક સ્ક્રીન પર વિજેટ બતાવો\" સુવિધા ચાલુ કરેલી છે."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"સેટિંગ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"વપરાશકર્તા સ્વિચ કરો"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"પુલડાઉન મેનૂ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"આ સત્રમાંની તમામ ઍપ અને ડેટા કાઢી નાખવામાં આવશે."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"નોટિફિકેશન"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"વાતચીત"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"બધા સાઇલન્ટ નોટિફિકેશન સાફ કરો"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ખલેલ પાડશો નહીં દ્વારા થોભાવેલ નોટિફિકેશન"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{કોઈ નોટિફિકેશન નથી}=1{{mode} દ્વારા નોટિફિકેશન થોભાવવામાં આવ્યા}=2{{mode} અને અન્ય એક મોડ દ્વારા નોટિફિકેશન થોભાવવામાં આવ્યા}one{{mode} અને અન્ય # મોડ દ્વારા નોટિફિકેશન થોભાવવામાં આવ્યા}other{{mode} અને અન્ય # મોડ દ્વારા નોટિફિકેશન થોભાવવામાં આવ્યા}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"હવે શરૂ કરો"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"હૅડ ટ્રૅકિંગ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"રિંગર મોડ બદલવા માટે ટૅપ કરો"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"રિંગર મોડ"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"મ્યૂટ કરો"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"અનમ્યૂટ કરો"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"વાઇબ્રેટ"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"કીબોર્ડ શૉર્ટકટ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"કીબોર્ડ શૉર્ટકટને કસ્ટમાઇઝ કરો"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"શું શૉર્ટકટ કાઢી નાખીએ?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"પાછા ડિફૉલ્ટ પર રીસેટ કરીએ?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"શૉર્ટકટ સોંપવા માટે કી દબાવો"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"આ તમારા કસ્ટમ શૉર્ટકટને કાયમી રીતે ડિલીટ કરશે."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"આ તમારા બધા કસ્ટમ શૉર્ટકટને કાયમ માટે ડિલીટ કરશે."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"શૉર્ટકટ શોધો"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"કોઈ શોધ પરિણામો નથી"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\'નાનું કરો\'નું આઇકન"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"કીબોર્ડના સેટિંગ"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"શૉર્ટકટ સેટ કરો"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"કાઢી નાખો"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"હા, રીસેટ કરો"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"રદ કરો"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"કી દબાવો"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"કી સંયોજન પેહલેથી ઉપયોગમાં છે. અન્ય કી અજમાવી જુઓ."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"તમારા કીબોર્ડ પરની ઍક્શન કી દબાવો"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"વાહ!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"તમે \'બધી ઍપ જુઓ\' સંકેત પૂર્ણ કર્યો"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"કીબોર્ડની બૅકલાઇટ"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dમાંથી %1$d લેવલ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ઘરેલું સાધનોના નિયંત્રણો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 474014c..d2f6e5a 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाएं"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"बातचीत"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"बिना आवाज़ की सभी सूचनाएं हटाएं"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'परेशान न करें\' सुविधा के ज़रिए कुछ समय के लिए सूचनाएं दिखाना रोक दिया गया है"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{कोई सूचना नहीं है}=1{{mode} की वजह से सूचना नहीं दिख रही है}=2{{mode} और एक अन्य मोड की वजह से सूचना नहीं दिख रही है}one{{mode} और # अन्य मोड की वजह से सूचना नहीं दिख रही है}other{{mode} और # अन्य मोड के की वजह से सूचनाएं नहीं दिख रही है}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"अभी शुरू करें"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"हेड ट्रैकिंग चालू है"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"रिंगर मोड बदलने के लिए टैप करें"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"रिंगर मोड"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करें"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्यूट करें"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"वाइब्रेशन की सुविधा चालू करें"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"अपने कीबोर्ड पर ऐक्शन बटन दबाएं"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"बहुत खूब!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"अब आपको हाथ के जेस्चर का इस्तेमाल करके, सभी ऐप्लिकेशन देखने का तरीका पता चल गया है"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड की बैकलाइट"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d में से %1$d लेवल"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 35996ea1..e566e4e 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Da biste otvorili aplikaciju pomoću widgeta, trebate potvrditi da ste to vi. Također napominjemo da ih svatko može vidjeti, čak i ako je vaš tablet zaključan. Neki widgeti možda nisu namijenjeni za zaključani zaslon, pa ih možda nije sigurno dodati ovdje."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Shvaćam"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgeti"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Da biste dodali prečac Widgeti, provjerite je li u postavkama omogućena opcija Prikaži widgete na zaključanom zaslonu."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Postavke"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Promjena korisnika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući izbornik"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Izbrisat će se sve aplikacije i podaci u ovoj sesiji."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Obavijesti"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Razgovori"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Izbriši sve bešumne obavijesti"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Značajka Ne uznemiravaj pauzirala je Obavijesti"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nema obavijesti}=1{Obavijesti je pauzirao način {mode}}=2{Obavijesti su pauzirali način {mode} i još jedan način}one{Obavijesti su pauzirali način {mode} i još # način rada}few{Obavijesti su pauzirali način {mode} i još # načina rada}other{Obavijesti su pauzirali način {mode} i još # načina rada}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Pokreni"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Praćenje glave"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da biste promijenili način softvera zvona"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"način softvera zvona"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključivanje zvuka"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključivanje zvuka"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibriranje"</string>
@@ -859,7 +861,7 @@
<string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Prikazuju se prečaci za trenutačnu aplikaciju"</string>
<string name="group_system_access_notification_shade" msgid="1619028907006553677">"Prikaz obavijesti"</string>
<string name="group_system_full_screenshot" msgid="5742204844232667785">"Snimanje zaslona"</string>
- <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Prikaži prečace"</string>
+ <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Prikaz prečaca"</string>
<string name="group_system_go_back" msgid="2730322046244918816">"Natrag"</string>
<string name="group_system_access_home_screen" msgid="4130366993484706483">"Otvaranje početnog zaslona"</string>
<string name="group_system_overview_open_apps" msgid="5659958952937994104">"Prikaz nedavnih aplikacija"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tipkovni prečaci"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodba tipkovnih prečaca"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Želite li ukloniti prečac?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Želite li vratiti na zadano?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pritisnite tipku da biste dodijelili prečac"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Time će se vaš prilagođeni prečac trajno izbrisati."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Time će se trajno izbrisati svi vaši prilagođeni prečaci."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečaci za pretraživanje"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za sažimanje"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Postavke tipkovnice"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Postavite prečac"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Ukloni"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Da, vrati na zadano"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Odustani"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipku"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinacija tipki već se upotrebljava. Pokušajte s drugom tipkom."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite tipku za radnju na tipkovnici"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Izvrsno!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Napravili ste pokret za prikaz svih aplikacija"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tipkovnice"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Razina %1$d od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Upravljanje uređajima"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c807aee..0cbf0aa 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Értesítések"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Beszélgetések"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Az összes néma értesítés törlése"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ne zavarjanak funkcióval szüneteltetett értesítések"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nincs értesítés}=1{A(z) {mode} szüneteltette az értesítéseket}=2{A(z) {mode} és egy másik mód szüneteltette az értesítéseket}other{A(z) {mode} és # másik mód szüneteltette az értesítéseket}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Indítás most"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Fejkövetés"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Koppintson a csengés módjának módosításához"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"csengés módja"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"némítás"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"némítás feloldása"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"rezgés"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Nyomja meg a műveletbillentyűt az érintőpadon."</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Szép munka!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Teljesítette az összes alkalmazás megtekintésének kézmozdulatát."</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"A billentyűzet háttérvilágítása"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Fényerő: %2$d/%1$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Otthon vezérlése"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 5603aff..867e0da 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Ծանուցումներ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Զրույցներ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Ջնջել բոլոր անձայն ծանուցումները"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ծանուցումները չեն ցուցադրվի «Չանհանգստացնել» ռեժիմում"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Ծանուցումներ չկան}=1{Ծանուցումները դադարեցվել են «{mode}» ռեժիմի կողմից}=2{Ծանուցումները դադարեցվել են «{mode}» ու ևս մի ռեժիմի կողմից}one{Ծանուցումները դադարեցվել են «{mode}» ու ևս # ռեժիմի կողմից}other{Ծանուցումները դադարեցվել են «{mode}» ու ևս # ռեժիմի կողմից}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Սկսել հիմա"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Գլխի շարժումների հետագծում"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Հպեք՝ զանգակի ռեժիմը փոխելու համար"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"զանգակի ռեժիմ"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"անջատել ձայնը"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"միացնել ձայնը"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"միացնել թրթռոցը"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Սեղմեք գործողության ստեղնը ստեղնաշարի վրա"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Հիանալի՛ է"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Դուք սովորեցիք բոլոր հավելվածները դիտելու ժեստը"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Հետին լուսավորությամբ ստեղնաշար"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d՝ %2$d-ից"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Տան կառավարման տարրեր"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 3820ab7..06ecd11 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifikasi"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Percakapan"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Hapus semua notifikasi senyap"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifikasi dijeda oleh mode Jangan Ganggu"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Tidak ada notifikasi}=1{Notifikasi dijeda oleh {mode}}=2{Notifikasi dijeda oleh {mode} dan satu mode lainnya}other{Notifikasi dijeda oleh {mode} dan # mode lainnya}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Mulai sekarang"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Pelacakan Gerak Kepala"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Ketuk untuk mengubah mode pendering"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"mode pendering"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"Tanpa suara"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktifkan"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"getar"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tekan tombol tindakan di keyboard"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Oke!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Anda telah menyelesaikan gestur untuk melihat semua aplikasi"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Lampu latar keyboard"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Tingkat %1$d dari %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrol Rumah"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 931c3dc..4f6ff47 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Þú þarft að staðfesta að þetta sért þú til að geta opnað forrit með græju. Hafðu einnig í huga að hver sem er getur skoðað þær, jafnvel þótt spjaldtölvan sé læst. Sumar græjur eru hugsanlega ekki ætlaðar fyrir lásskjá og því gæti verið óöruggt að bæta þeim við hér."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ég skil"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Græjur"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Gakktu úr skugga um að kveikt sé á „Sýna græjur á lásskjá“ til að geta bætt flýtileiðinni „Græjur“ við."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Stillingar"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skipta um notanda"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Fellivalmynd"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Tilkynningar"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Samtöl"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Hreinsa allar þöglar tilkynningar"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Hlé gert á tilkynningum þar sem stillt er á „Ónáðið ekki“"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Engar tilkynningar}=1{Hlé gert á tilkynningum þar sem stillt er á {mode}}=2{Hlé gert á tilkynningum þar sem stillt er á {mode} og eina aðra stillingu}one{Hlé gert á tilkynningum þar sem stillt er á {mode} og # aðra stillingu}other{Hlé gert á tilkynningum þar sem stillt er á {mode} og # aðrar stillingar}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Byrja núna"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Rakning höfuðhreyfinga"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Ýta til að skipta um hringjarastillingu"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"hringistilling"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"þagga"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"hætta að þagga"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"titringur"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Flýtilyklar"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sérsníddu flýtilykla"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Fjarlægja flýtileið?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Endurstilla á sjálfgefið?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Ýttu á lykil til að stilla flýtileið"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Þetta eyðir sérsniðnu flýtileiðinni varanlega."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Þetta verður til þess að öllum sérsniðnu flýtileiðunum þínum verður eytt varanlega."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Leita að flýtileiðum"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Engar leitarniðurstöður"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Minnka tákn"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Stillingar lyklaborðs"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Stilltu flýtileið"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Fjarlægja"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Já, endurstilla"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Hætta við"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Ýttu á lykil"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Lyklasamsetningin er þegar í notkun. Prófaðu annan lykil."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Ýttu á aðgerðalykilinn á lyklaborðinu"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Vel gert!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Þú framkvæmdir bendinguna „Sjá öll forrit“"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Baklýsing lyklaborðs"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Stig %1$d af %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Heimastýringar"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 7c2fc4f..76e3360 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Per aprire un\'app utilizzando un widget, dovrai verificare la tua identità. Inoltre tieni presente che chiunque può vederlo, anche quando il tablet è bloccato. Alcuni widget potrebbero non essere stati progettati per la schermata di blocco e potrebbe non essere sicuro aggiungerli qui."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ok"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widget"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Per aggiungere la scorciatoia \"Widget\", assicurati che l\'opzione \"Mostra widget sulla schermata di blocco\" sia abilitata nelle impostazioni."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Impostazioni"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambio utente"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu a discesa"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifiche"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversazioni"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Cancella tutte le notifiche silenziose"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notifiche messe in pausa in base alla modalità Non disturbare"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nessuna notifica}=1{Notifica messa in pausa da {mode}}=2{Notifiche messe in pausa da {mode} e un\'altra modalità}many{Notifiche messe in pausa da {mode} e # di modalità}other{Notifiche messe in pausa da {mode} e altre # modalità}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Avvia adesso"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Rilev. movim. testa"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tocca per cambiare la modalità della suoneria"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"modalità suoneria"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenzia"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"riattiva l\'audio"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrazione"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Scorciatoie da tastiera"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizza scorciatoie da tastiera"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Rimuovere scorciatoia?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Vuoi ripristinare il valore predefinito?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Premi un tasto per assegnare una scorciatoia"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"La scorciatoia personalizzata verrà eliminata definitivamente."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Tutte le tue scorciatoie personalizzate verranno eliminate definitivamente."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Scorciatoie per la ricerca"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nessun risultato di ricerca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona Comprimi"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Impostazioni tastiera"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Imposta scorciatoia"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Rimuovi"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Sì, ripristina"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annulla"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Premi un tasto"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Combinazione di tasti già in uso. Prova con un altro tasto."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Premi il tasto azione sulla tastiera"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Ben fatto!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Hai completato il gesto Visualizza tutte le app."</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroilluminazione della tastiera"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Livello %1$d di %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controlli della casa"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index e481a77..3257e14 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"התראות"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"שיחות"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ניקוי כל ההתראות השקטות"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"התראות הושהו על ידי מצב \'נא לא להפריע\'"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{אין התראות}=1{ההתראות הושהו על ידי {mode}}=2{ההתראות הושהו על ידי {mode} ועל ידי מצב אחד נוסף}one{ההתראות הושהו על ידי {mode} ועל ידי # מצבים נוספים}other{ההתראות הושהו על ידי {mode} ועל ידי # מצבים נוספים}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"כן, אפשר להתחיל"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"מעקב ראש"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"יש להקיש כדי לשנות את מצב תוכנת הצלצול"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"מצב תוכנת הצלצול"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"השתקה"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ביטול ההשתקה"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"רטט"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"צריך להקיש על מקש הפעולה במקלדת"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"כל הכבוד!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"סיימת לתרגל את התנועה להצגת כל האפליקציות"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"התאורה האחורית במקלדת"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"רמה %1$d מתוך %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"שליטה במכשירים"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 1a2d022..13dd954 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ウィジェットを使用してアプリを起動するには、本人確認が必要です。タブレットがロックされた状態でも他のユーザーにウィジェットが表示されますので、注意してください。一部のウィジェットについてはロック画面での使用を想定していないため、ロック画面への追加は危険な場合があります。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ウィジェット"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"[ウィジェット] ショートカットを追加するには、設定で [ロック画面でのウィジェットの表示] が有効になっていることを確認してください。"</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"設定"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ユーザーを切り替える"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"プルダウン メニュー"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"このセッションでのアプリとデータはすべて削除されます。"</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"会話"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"サイレント通知がすべて消去されます"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"サイレント モードにより通知は一時停止中です"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{通知なし}=1{{mode} により通知は一時停止中です}=2{{mode} と他 1 個のモードにより通知は一時停止中です}other{{mode} と他 # 個のモードにより通知は一時停止中です}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"今すぐ開始"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ヘッド トラッキング"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"タップすると、着信音のモードを変更できます"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"着信音のモード"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ミュート"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ミュートを解除"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"バイブレーション"</string>
@@ -1426,20 +1428,17 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"キーボード ショートカット"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"キーボード ショートカットをカスタマイズする"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ショートカットを削除しますか?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"デフォルトにリセットしますか?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ショートカットを割り当てるキーを押してください"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"この操作を行うと、カスタム ショートカットが完全に削除されます。"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"この操作を行うと、すべてのカスタム ショートカットが完全に削除されます。"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"検索ショートカット"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"検索結果がありません"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"閉じるアイコン"</string>
<string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"アクションキーまたはメタキーのアイコン"</string>
<string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"プラスアイコン"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"カスタマイズ"</string>
- <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
- <skip />
+ <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"リセット"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"完了"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"開くアイコン"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"または"</string>
@@ -1449,8 +1448,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"キーボードの設定"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ショートカットの設定"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"削除"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"リセットする"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"キャンセル"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"キーを押してください"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"このキーの組み合わせはすでに使用されています。別のキーを試してください。"</string>
@@ -1482,6 +1480,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"キーボードのアクションキーを押します"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"完了です!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"「すべてのアプリを表示する」ジェスチャーを学習しました"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"キーボード バックライト"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"レベル %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ホーム コントロール"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index d7fe284..9390bd2 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"უნდა დაადასტუროთ თქვენი ვინაობა, რათა გახსნათ აპი ვიჯეტის გამოყენებით. გაითვალისწინეთ, რომ ნებისმიერს შეუძლია მათი ნახვა, მაშინაც კი, როცა ტაბლეტი დაბლოკილია. ზოგი ვიჯეტი შეიძლება არ იყოს გათვლილი თქვენი დაბლოკილი ეკრანისთვის და მათი აქ დამატება შეიძლება სახიფათო იყოს."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"გასაგებია"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ვიჯეტები"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"„ვიჯეტების“ მალსახმობის დასამატებლად დარწმუნდით, რომ პარამეტრებში ჩართულია „დაბლოკილ ეკრანზე ვიჯეტების ჩვენება“."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"პარამეტრები"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"მომხმარებლის გადართვა"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ჩამოშლადი მენიუ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ამ სესიის ყველა აპი და მონაცემი წაიშლება."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"შეტყობინებები"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"საუბრები"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ყველა ჩუმი შეტყობინების გასუფთავება"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"შეტყობინებები დაპაუზდა „არ შემაწუხოთ“ რეჟიმის მეშვეობით"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{შეტყობინებები არ არის}=1{შეტყობინებები შეჩერებულია {mode}-ის გამო}=2{შეტყობინებები შეჩერებულია {mode}-ის და ერთი სხვა რეჟიმის გამო}other{შეტყობინებები შეჩერებულია {mode}-ის და # სხვა რეჟიმის გამო}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"დაწყება ახლავე"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ხმის მიდევნებით"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"შეეხეთ მრეკავის რეჟიმის შესაცვლელად"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"მრეკავის რეჟიმი"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"დადუმება"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"დადუმების მოხსნა"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ვიბრაცია"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"კლავიატურის მალსახმობები"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"კლავიატურის მალსახმობების მორგება"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"გსურთ მალსახმობის წაშლა?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"გსურთ ნაგულისხმევზე გადაყენება?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"მალსახმობის მინიჭებისთვის დააჭირეთ კლავიშს"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ეს თქვენს მორგებულ მალსახმობებს სამუდამოდ წაშლის."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"ეს სამუდამოდ წაშლის თქვენს ყველა მორგებულ მალსახმობს."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ძიების მალსახმობები"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ძიების შედეგები არ არის"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ხატულის ჩაკეცვა"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"კლავიატურის პარამეტრები"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"მალსახმობის დაყენება"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"ამოშლა"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"დიახ, გადაყენდეს"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"გაუქმება"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"დააჭირეთ კლავიშს"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"კლავიშების კომბინაცია უკვე გამოიყენება. ცადეთ სხვა კლავიში."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"დააჭირეთ მოქმედების კლავიშს თქვენს კლავიატურაზე"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ყოჩაღ!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"თქვენ დაასრულეთ ყველა აპის ნახვის ჟესტი"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"კლავიატურის შენათება"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"დონე: %1$d %2$d-დან"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"სახლის კონტროლი"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 92269a2..672bb66 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Қолданбаны виджет көмегімен ашу үшін жеке басыңызды растауыңыз керек. Сондай-ақ басқалар оларды планшетіңіз құлыптаулы кезде де көре алатынын ескеріңіз. Кейбір виджеттер құлып экранына арналмаған болады, сондықтан оларды мұнда қосу қауіпсіз болмауы мүмкін."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түсінікті"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Виджеттер"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"Виджеттер\" таңбашасын қосу үшін параметрлерде \"Виджеттерді құлыптаулы экранда көрсету\" опциясының қосулы екенін тексеріңіз."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Параметрлер"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Пайдаланушыны ауыстыру"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ашылмалы мәзір"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданба мен дерек жойылады."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Хабарландырулар"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Әңгімелер"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Барлық үнсіз хабарландыруларды өшіру"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Хабарландырулар Мазаламау режимінде кідіртілді"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Хабарландырулар жоқ.}=1{Хабарландыруларды {mode} режимі кідіртті.}=2{Хабарландыруларды {mode} және тағы бір режим кідіртті.}other{Хабарландыруларды {mode} және тағы # режим кідіртті.}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Қазір бастау"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Бас қимылын қадағалау"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Қоңырау режимін өзгерту үшін түртіңіз."</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"қоңырау режимі"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"дыбысын өшіру"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"дыбысын қосу"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"дірілдету"</string>
@@ -1426,20 +1428,17 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Перне тіркесімдері"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Пернелер тіркесімін бейімдеу"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Жылдам пәрменді өшіру керек пе?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Әдепкі таңбашаларға қайтару керек пе?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Жылдам пәрменді тағайындау үшін пернені басыңыз."</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Арнаулы жылдам пәрменіңіз біржола жойылады."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Мұндайда барлық арнаулы таңбашалар біржола жойылады."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Іздеу жылдам пәрмендері"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Іздеу нәтижелері жоқ."</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жию белгішесі"</string>
<string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Әрекет немесе Meta пернесінің белгішесі"</string>
<string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Қосу белгішесі"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Бейімдеу"</string>
- <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
- <skip />
+ <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Бастапқы күйге қайтару"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Дайын"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Жаю белгішесі"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"немесе"</string>
@@ -1449,8 +1448,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Пернетақта параметрлері"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Жылдам пәрменді орнату"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Өшіру"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Иә, қайтару"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Бас тарту"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Пернені басыңыз"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Бұл пернелер тіркесімі қазір қолданыста. Басқа перне таңдаңыз."</string>
@@ -1482,6 +1480,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Пернетақтадағы әрекет пернесін басыңыз."</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Жарайсыз!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Барлық қолданбаны көру қимылын орындадыңыз."</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Пернетақта жарығы"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Деңгей: %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Үй басқару элементтері"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 13153c6..96a9ed4 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ដើម្បីបើកកម្មវិធីដោយប្រើធាតុក្រាហ្វិក អ្នកនឹងត្រូវផ្ទៀងផ្ទាត់ថាជាអ្នក។ ទន្ទឹមនឹងនេះ សូមចងចាំថា នរណាក៏អាចមើលធាតុក្រាហ្វិកបាន សូម្បីពេលថេប្លេតរបស់អ្នកជាប់សោក៏ដោយ។ ធាតុក្រាហ្វិកមួយចំនួនប្រហែលមិនត្រូវបានរចនាឡើងសម្រាប់អេក្រង់ចាក់សោរបស់អ្នកទេ និងមិនមានសុវត្ថិភាពឡើយ បើបញ្ចូលទៅទីនេះ។"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"យល់ហើយ"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ធាតុក្រាហ្វិក"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"ដើម្បីបញ្ចូលផ្លូវកាត់ \"ធាតុក្រាហ្វិក\" ត្រូវប្រាកដថា \"បង្ហាញធាតុក្រាហ្វិកនៅលើអេក្រង់ចាក់សោ\" ត្រូវបានបើកនៅក្នុងការកំណត់។"</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"ការកំណត់"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ប្ដូរអ្នកប្រើ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ម៉ឺនុយទាញចុះ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"កម្មវិធី និងទិន្នន័យទាំងអស់ក្នុងវគ្គនេះនឹងត្រូវលុប។"</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ការជូនដំណឹង"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ការសន្ទនា"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"សម្អាតការជូនដំណឹងស្ងាត់ទាំងអស់"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ការជូនដំណឹងបានផ្អាកដោយមុខងារកុំរំខាន"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{គ្មានការជូនដំណឹង}=1{ការជូនដំណឹងត្រូវបានផ្អាកដោយ {mode}}=2{ការជូនដំណឹងត្រូវបានផ្អាកដោយ {mode} និងមុខងារមួយផ្សេងទៀត}other{ការជូនដំណឹងត្រូវបានផ្អាកដោយ {mode} និងមុខងារ # ផ្សេងទៀត}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ចាប់ផ្ដើមឥឡូវ"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"រេតាមក្បាល"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ចុចដើម្បីប្ដូរមុខងាររោទ៍"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"មុខងារកម្មវិធីរោទ៍"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"បិទសំឡេង"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"បើកសំឡេង"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ញ័រ"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"ផ្លូវកាត់ក្ដារចុច"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ប្ដូរផ្លូវកាត់ក្ដារចុចតាមបំណង"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ដកផ្លូវកាត់ចេញឬ?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"កំណត់ឡើងវិញទៅលំនាំដើមឬ?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ចុចគ្រាប់ចុច ដើម្បីកំណត់ផ្លូវកាត់"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ការធ្វើបែបនេះនឹងលុបផ្លូវកាត់ផ្ទាល់ខ្លួនរបស់អ្នកជាអចិន្ត្រៃយ៍។"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"សកម្មភាពនេះនឹងលុបផ្លូវកាត់ផ្ទាល់ខ្លួនរបស់អ្នកទាំងអស់ជាអចិន្ត្រៃយ៍។"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ស្វែងរកផ្លូវកាត់"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"គ្មានលទ្ធផលស្វែងរកទេ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"រូបតំណាង \"បង្រួម\""</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ការកំណត់ក្ដារចុច"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"កំណត់ផ្លូវកាត់"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"ដកចេញ"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"បាទ/ចាស កំណត់ឡើងវិញ"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"បោះបង់"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ចុចគ្រាប់ចុច"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"កំពុងប្រើបន្សំគ្រាប់ចុចស្រាប់ហើយ។ សាកល្បងប្រើគ្រាប់ចុចផ្សេង។"</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ចុចគ្រាប់ចុចសកម្មភាពលើក្ដារចុចរបស់អ្នក"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ធ្វើបានល្អ!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"អ្នកបានបញ្ចប់ចលនាមើលកម្មវិធីទាំងអស់ហើយ"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ពន្លឺក្រោយក្ដារចុច"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"កម្រិតទី %1$d នៃ %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ការគ្រប់គ្រងផ្ទះ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index b83e957..89b8db2 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ವಿಜೆಟ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ಆ್ಯಪ್ ತೆರೆಯಲು, ಇದು ನೀವೇ ಎಂದು ನೀವು ದೃಢೀಕರಿಸಬೇಕಾಗುತ್ತದೆ. ಅಲ್ಲದೆ, ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಲಾಕ್ ಆಗಿದ್ದರೂ ಸಹ ಯಾರಾದರೂ ಅವುಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು ಎಂಬುದನ್ನು ನೆನಪಿನಲ್ಲಿಡಿ. ಕೆಲವು ವಿಜೆಟ್ಗಳು ನಿಮ್ಮ ಲಾಕ್ ಸ್ಕ್ರೀನ್ಗಾಗಿ ಉದ್ದೇಶಿಸದೇ ಇರಬಹುದು ಮತ್ತು ಇಲ್ಲಿ ಸೇರಿಸುವುದು ಸುರಕ್ಷಿತವಲ್ಲದಿರಬಹುದು."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ಅರ್ಥವಾಯಿತು"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ವಿಜೆಟ್ಗಳು"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"ವಿಜೆಟ್ಗಳು\" ಶಾರ್ಟ್ಕಟ್ ಸೇರಿಸಲು, ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ \"ಲಾಕ್ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ವಿಜೆಟ್ಗಳನ್ನು ತೋರಿಸಿ\" ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ಪುಲ್ಡೌನ್ ಮೆನು"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಶನ್ನಲ್ಲಿನ ಎಲ್ಲಾ ಆ್ಯಪ್ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ಅಧಿಸೂಚನೆಗಳು"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ಸಂಭಾಷಣೆಗಳು"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ಎಲ್ಲಾ ನಿಶ್ಶಬ್ಧ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸಿ"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಎನ್ನುವ ಮೂಲಕ ಅಧಿಸೂಚನೆಗಳನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{ಯಾವುದೇ ನೋಟಿಫಿಕೇಶನ್ಗಳು ಇಲ್ಲ}=1{ನೋಟಿಫಿಕೇಶನ್ಗಳನ್ನು {mode} ವಿರಾಮಗೊಳಿಸಿದೆ}=2{ನೋಟಿಫಿಕೇಶನ್ಗಳನ್ನು {mode} ಹಾಗೂ ಇತರ ಒಂದು ಮೋಡ್ ವಿರಾಮಗೊಳಿಸಿವೆ}one{ನೋಟಿಫಿಕೇಶನ್ಗಳನ್ನು {mode} ಹಾಗೂ ಇತರ # ಮೋಡ್ಗಳು ವಿರಾಮಗೊಳಿಸಿವೆ}other{ನೋಟಿಫಿಕೇಶನ್ಗಳನ್ನು {mode} ಹಾಗೂ ಇತರ # ಮೋಡ್ಗಳು ವಿರಾಮಗೊಳಿಸಿವೆ}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ಈಗ ಪ್ರಾರಂಭಿಸಿ"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ಹೆಡ್ ಟ್ರ್ಯಾಕಿಂಗ್"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ರಿಂಗರ್ ಮೋಡ್ ಬದಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ರಿಂಗರ್ ಮೋಡ್"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ವೈಬ್ರೇಟ್"</string>
@@ -1426,20 +1428,17 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್ಕಟ್ಗಳು"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ತೆಗೆದುಹಾಕಬೇಕೇ?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ಡೀಫಾಲ್ಟ್ಗೆ ರೀಸೆಟ್ ಮಾಡಬೇಕೆ?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ನಿಯೋಜಿಸಲು ಕೀಯನ್ನು ಒತ್ತಿರಿ"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ಇದು ನಿಮ್ಮ ಕಸ್ಟಮ್ ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ಅಳಿಸುತ್ತದೆ."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"ಇದು ನಿಮ್ಮ ಎಲ್ಲಾ ಕಸ್ಟಮ್ ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಶಾಶ್ವತವಾಗಿ ಅಳಿಸುತ್ತದೆ."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ಹುಡುಕಾಟದ ಶಾರ್ಟ್ಕಟ್ಗಳು"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ಯಾವುದೇ ಹುಡುಕಾಟ ಫಲಿತಾಂಶಗಳಿಲ್ಲ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ಕುಗ್ಗಿಸುವ ಐಕಾನ್"</string>
<string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"ಆ್ಯಕ್ಷನ್ ಅಥವಾ ಮೆಟಾ ಕೀ ಐಕಾನ್"</string>
<string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"ಪ್ಲಸ್ ಐಕಾನ್"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
- <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
- <skip />
+ <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"ರೀಸೆಟ್ ಮಾಡಿ"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"ಮುಗಿದಿದೆ"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ವಿಸ್ತೃತಗೊಳಿಸುವ ಐಕಾನ್"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ಅಥವಾ"</string>
@@ -1449,8 +1448,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"ಕೀಬೋರ್ಡ್ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ಶಾರ್ಟ್ಕಟ್ ಸೆಟ್ ಮಾಡಿ"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"ತೆಗೆದುಹಾಕಿ"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"ಹೌದು, ರೀಸೆಟ್ ಮಾಡಿ"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ರದ್ದುಮಾಡಿ"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"ಕೀ ಅನ್ನು ಒತ್ತಿರಿ"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"ಕೀ ಸಂಯೋಜನೆಯು ಈಗಾಗಲೇ ಬಳಕೆಯಲ್ಲಿದೆ. ಮತ್ತೊಂದು ಕೀ ಬಳಸಿ ನೋಡಿ."</string>
@@ -1482,6 +1480,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್ನಲ್ಲಿ ಆ್ಯಕ್ಷನ್ ಕೀಯನ್ನು ಒತ್ತಿ"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ಭೇಷ್!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ನೀವು ಎಲ್ಲಾ ಆ್ಯಪ್ಗಳ ಜೆಸ್ಚರ್ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ಕೀಬೋರ್ಡ್ ಬ್ಯಾಕ್ಲೈಟ್"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ರಲ್ಲಿ %1$d ಮಟ್ಟ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ಮನೆ ನಿಯಂತ್ರಣಗಳು"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 00b2450..276d708 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"위젯을 사용하여 앱을 열려면 본인 인증을 해야 합니다. 또한 태블릿이 잠겨 있더라도 누구나 볼 수 있다는 점을 유의해야 합니다. 일부 위젯은 잠금 화면에 적합하지 않고 여기에 추가하기에 안전하지 않을 수 있습니다."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"확인"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"위젯"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\'위젯\' 바로가기를 추가하려면 설정에서 \'잠금 화면에 위젯 표시\'가 사용 설정되어 있어야 합니다."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"설정"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"사용자 전환"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"풀다운 메뉴"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"알림"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"대화"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"무음 알림 모두 삭제"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"방해 금지 모드로 알림이 일시중지됨"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{알림 없음}=1{{mode} 모드로 인해 알림이 일시중지되었습니다.}=2{{mode} 및 다른 모드로 인해 알림이 일시중지되었습니다.}other{{mode} 및 다른 모드 #개로 인해 알림이 일시중지되었습니다.}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"시작하기"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"머리 추적"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"탭하여 벨소리 장치 모드 변경"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"벨소리 장치 모드"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"음소거"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"음소거 해제"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"진동"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"단축키"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"단축키 맞춤설정"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"바로가기를 제거하시겠습니까?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"기본값으로 재설정하시겠어요?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"키를 눌러 단축키 지정"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"맞춤 단축어가 영구적으로 삭제됩니다."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"모든 맞춤 바로가기가 완전히 삭제됩니다."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"검색 바로가기"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"검색 결과 없음"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"접기 아이콘"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"키보드 설정"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"단축키 설정"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"삭제"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"재설정"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"취소"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"키를 누르세요."</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"이미 사용 중인 키 조합입니다. 다른 키를 사용해 보세요."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"키보드의 작업 키를 누르세요."</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"잘하셨습니다"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"모든 앱 보기 동작을 완료했습니다."</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"키보드 백라이트"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d단계 중 %1$d단계"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"홈 컨트롤"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index a857f4e..ab20a7b 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Колдонмону виджет аркылуу ачуу үчүн өзүңүздү ырасташыңыз керек. Алар кулпуланган планшетиңизде да көрүнүп турат. Кээ бир виджеттерди кулпуланган экранда колдоно албайсыз, андыктан аларды ал жерге кошпой эле койгонуңуз оң."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Түшүндүм"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Виджеттер"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"Виджеттер\" ыкчам баскычын кошуу үчүн параметрлерге өтүп, \"Виджеттерди кулпуланган экранда көрсөтүү\" параметри иштетилгенин текшериңиз."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Параметрлер"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Колдонуучуну которуу"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ылдый түшүүчү меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана аларга байланыштуу нерселер өчүрүлөт."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Билдирмелер"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Сүйлөшүүлөр"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Бардык үнсүз билдирмелерди өчүрүү"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\"Тынчымды алба\" режиминде билдирмелер тындырылды"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Билдирмелер жок}=1{{mode} режими билдирмелерди тындырды}=2{{mode} жана дагы бир режим билдирмелерди тындырды}other{{mode} жана дагы # режим билдирмелерди тындырды}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Азыр баштоо"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Баштын кыймылына көз салуу"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Коңгуроо режимин өзгөртүү үчүн басыңыз"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"коңгуроо режими"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"үнсүз"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"үнүн чыгаруу"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"дирилдөө"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Ыкчам баскычтар"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Ыкчам баскычтарды ыңгайлаштыруу"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Ыкчам баскыч өчүрүлсүнбү?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Баштапкы абалга келтиресизби?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Ыкчам баскычты дайындоо үчүн баскычты басыңыз"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Ушуну менен жеке ыкчам баскычыңыз биротоло өчүрүлөт."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Ушуну менен жеке ыкчам баскычтарыңыздын баары биротоло өчүрүлөт."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Ыкчам баскычтарды издөө"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Эч нерсе табылган жок"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жыйыштыруу сүрөтчөсү"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Баскычтоп параметрлери"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ыкчам баскычты тууралоо"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Өчүрүү"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Ооба, баштапкы абалга келтирилсин"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancel"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Баскычты басыңыз"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ачкычтардын айкалышы колдонулууда. Башка ачкычты байкап көрүңүз."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Баскычтобуңуздагы аракет баскычын басыңыз"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Эң жакшы!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Бардык колдонмолорду көрүү жаңсоосун аткардыңыз"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Баскычтоптун жарыгы"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ичинен %1$d-деңгээл"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Үйдөгү түзмөктөрдү тескөө"</string>
diff --git a/packages/SystemUI/res/values-land/styles.xml b/packages/SystemUI/res/values-land/styles.xml
index 73812c9..ae0006f 100644
--- a/packages/SystemUI/res/values-land/styles.xml
+++ b/packages/SystemUI/res/values-land/styles.xml
@@ -43,21 +43,21 @@
<item name="android:layout_marginTop">6dp</item>
<item name="android:textSize">36dp</item>
<item name="android:focusable">true</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Subtitle">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:layout_marginTop">6dp</item>
<item name="android:textSize">18sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Description">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:layout_marginTop">6dp</item>
<item name="android:textSize">18sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 19b216d..a3a25e8 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ການແຈ້ງເຕືອນ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ການສົນທະນາ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ລຶບລ້າງການແຈ້ງເຕືອນແບບງຽບທັງໝົດ"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"ຢຸດການແຈ້ງເຕືອນໂດຍໂໝດຫ້າມລົບກວນແລ້ວ"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{ບໍ່ມີການແຈ້ງເຕືອນ}=1{{mode} ຢຸດການແຈ້ງເຕືອນໄວ້ຊົ່ວຄາວ}=2{{mode} ແລະ ອີກ 1 ໂໝດຢຸດການແຈ້ງເຕືອນໄວ້ຊົ່ວຄາວ}other{{mode} ແລະ ອີກ # ໂໝດຢຸດການແຈ້ງເຕືອນໄວ້ຊົ່ວຄາວ}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ເລີ່ມດຽວນີ້"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ການຕິດຕາມຫົວ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ແຕະເພື່ອປ່ຽນໂໝດຣິງເກີ"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ໂໝດຣິງເກີ"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ປິດສຽງ"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ເຊົາປິດສຽງ"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ສັ່ນເຕືອນ"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ກົດປຸ່ມຄຳສັ່ງຢູ່ແປ້ນພິມຂອງທ່ານ"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ດີຫຼາຍ!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ທ່ານເບິ່ງທ່າທາງຂອງແອັບທັງໝົດສຳເລັດແລ້ວ"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ໄຟປຸ່ມແປ້ນພິມ"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"ລະດັບທີ %1$d ຈາກ %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ການຄວບຄຸມເຮືອນ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 6d4c775..cba0db1 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Pranešimai"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Pokalbiai"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Išvalyti visus tylius pranešimus"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Pranešimai pristabdyti naudojant netrukdymo režimą"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nėra pranešimų}=1{Pranešimai pristabdyti naudojant režimą „{mode}“}=2{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar vieną režimą}one{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar # režimą}few{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar # režimus}many{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar # režimo}other{Pranešimai pristabdyti naudojant režimą „{mode}“ ir dar # režimų}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Pradėti dabar"</string>
@@ -707,6 +709,7 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Galvos stebėjimas"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Palieskite, kad pakeistumėte skambučio režimą"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"skambučio režimas"</string>
+ <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>, palieskite, kad pakeistumėte skambučio režimą"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"nutildyti"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"įjungti garsą"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibruoti"</string>
@@ -1482,6 +1485,7 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Paspauskite klaviatūros veiksmų klavišą"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Puikiai padirbėta!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Atlikote visų programų peržiūros gestą"</string>
+ <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Mokomoji animacija. Spustelėkite, kad pristabdytumėte ir tęstumėte atkūrimą."</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatūros foninis apšvietimas"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d lygis iš %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Namų sistemos valdymas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index d522946..7698008 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Paziņojumi"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Sarunas"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Notīrīt visus klusos paziņojumus"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Paziņojumi pārtraukti, izmantojot iestatījumu “Netraucēt”"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nav paziņojumu}=1{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” dēļ}=2{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” un vēl viena režīma dēļ}zero{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” un vēl # režīmu dēļ}one{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” un vēl # režīma dēļ}other{Paziņojumu rādīšana ir pārtraukta režīma “{mode}” un vēl # režīmu dēļ}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Sākt tūlīt"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seko galvai"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Pieskarieties, lai mainītu zvanītāja režīmu."</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"zvanītāja režīms"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izslēgt skaņu"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ieslēgt skaņu"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrēt"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tastatūrā nospiediet darbību taustiņu."</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Lieliski!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Jūs sekmīgi veicāt visu lietotņu skatīšanas žestu."</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastatūras fona apgaismojums"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Līmenis numur %1$d, kopā ir %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Mājas kontrolierīces"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index f991c1b..783e52e 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Известувања"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Разговори"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Избриши ги сите бесчујни известувања"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Известувањата се паузирани од „Не вознемирувај“"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Нема известувања}=1{Известувањата ги паузираше {mode}}=2{Известувањата ги паузираа {mode} и уште еден режим}one{Известувањата ги паузираа {mode} и уште # режим}other{Известувањата ги паузираа {mode} и уште # режими}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Започни сега"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Следење на главата"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Допрете за да го промените режимот на ѕвончето"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"режим на ѕвонче"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"исклучен звук"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"вклучен звук"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибрации"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Притиснете го копчето за дејство на тастатурата"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Браво!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Го завршивте движењето за прегледување на сите апликации"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Осветлување на тастатура"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Ниво %1$d од %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Контроли за домот"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 784c896..3134872 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"വിജറ്റ് ഉപയോഗിച്ച് ഒരു ആപ്പ് തുറക്കാൻ, ഇത് നിങ്ങൾ തന്നെയാണെന്ന് പരിശോധിച്ചുറപ്പിക്കേണ്ടതുണ്ട്. നിങ്ങളുടെ ടാബ്ലെറ്റ് ലോക്കായിരിക്കുമ്പോഴും എല്ലാവർക്കും അത് കാണാനാകുമെന്നതും ഓർക്കുക. ചില വിജറ്റുകൾ നിങ്ങളുടെ ലോക്ക് സ്ക്രീനിന് ഉള്ളതായിരിക്കില്ല, അവ ഇവിടെ ചേർക്കുന്നത് സുരക്ഷിതവുമായിരിക്കില്ല."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"മനസ്സിലായി"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"വിജറ്റുകൾ"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"വിജറ്റുകൾ\" കുറുക്കുവഴി ചേർക്കാൻ, ക്രമീകരണത്തിൽ \"ലോക്ക് സ്ക്രീനിൽ വിജറ്റുകൾ കാണിക്കുക\" പ്രവർത്തനക്ഷമമാക്കിയെന്ന് ഉറപ്പാക്കുക."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"ക്രമീകരണം"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ഉപയോക്താവ് മാറുക"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"പുൾഡൗൺ മെനു"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"അറിയിപ്പുകൾ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"സംഭാഷണങ്ങൾ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"എല്ലാ നിശബ്ദ അറിയിപ്പുകളും മായ്ക്കുക"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ശല്യപ്പെടുത്തരുത്\' വഴി അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തി"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{അറിയിപ്പുകൾ ഒന്നുമില്ല}=1{{mode}, അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തിയിരിക്കുന്നു}=2{{mode} എന്നതും മറ്റൊരു മോഡും, അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തിയിരിക്കുന്നു}other{{mode} എന്നതും മറ്റ് # മോഡുകളും, അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തിയിരിക്കുന്നു}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ഇപ്പോൾ ആരംഭിക്കുക"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ഹെഡ് ട്രാക്കിംഗ്"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"റിംഗർ മോഡ് മാറ്റാൻ ടാപ്പ് ചെയ്യുക"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"റിംഗർ മോഡ്"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"മ്യൂട്ട് ചെയ്യുക"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"അൺമ്യൂട്ട് ചെയ്യുക"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"വൈബ്രേറ്റ് ചെയ്യുക"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"കീബോഡ് കുറുക്കുവഴികൾ"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"കീബോർഡ് കുറുക്കുവഴികൾ ഇഷ്ടാനുസൃതമാക്കുക"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"കുറുക്കുവഴി നീക്കം ചെയ്യണോ?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ഡിഫോൾട്ടിലേക്ക് തിരികെ റീസെറ്റ് ചെയ്യണോ?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"കുറുക്കുവഴി അസൈൻ ചെയ്യാൻ കീ അമർത്തുക"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ഇത് നിങ്ങളുടെ ഇഷ്ടാനുസൃത കുറുക്കുവഴി ശാശ്വതമായി ഇല്ലാതാക്കും."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"നിങ്ങളുടെ എല്ലാ ഇഷ്ടാനുസൃത കുറുക്കുവഴികളും ശാശ്വതമായി ഇത് ഇല്ലാതാക്കും."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"തിരയൽ കുറുക്കുവഴികൾ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"തിരയൽ ഫലങ്ങളൊന്നുമില്ല"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ചുരുക്കൽ ഐക്കൺ"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"കീബോർഡ് ക്രമീകരണം"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"കുറുക്കുവഴി സജ്ജീകരിക്കുക"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"നീക്കം ചെയ്യുക"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"ഉവ്വ്, റീസെറ്റ് ചെയ്യുക"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"റദ്ദാക്കുക"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"കീ അമർത്തുക"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"കീ കോമ്പിനേഷൻ ഇതിനകം ഉപയോഗത്തിലുണ്ട്. മറ്റൊരു കീ പരീക്ഷിക്കുക."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"നിങ്ങളുടെ കീബോർഡിലെ ആക്ഷൻ കീ അമർത്തുക"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"അഭിനന്ദനങ്ങൾ!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"\'എല്ലാ ആപ്പുകളും കാണുക\' ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"കീബോഡ് ബാക്ക്ലൈറ്റ്"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-ൽ %1$d-ാമത്തെ ലെവൽ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ഹോം കൺട്രോളുകൾ"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 6e60b71..42182bf 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Мэдэгдлүүд"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Харилцан яриа"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Бүх чимээгүй мэдэгдлийг арилгах"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Бүү саад бол горимын түр зогсоосон мэдэгдэл"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Мэдэгдэл байхгүй}=1{Мэдэгдлийг {mode} түр зогсоосон}=2{Мэдэгдлийг {mode} болон өөр нэг горим түр зогсоосон}other{Мэдэгдлийг {mode} болон өөр # горим түр зогсоосон}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Одоо эхлүүлэх"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Толгой хянах"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Хонхны горимыг өөрчлөхийн тулд товшино уу"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"хонхны горим"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"дууг хаах"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"дууг нээх"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"чичрэх"</string>
@@ -1443,7 +1447,7 @@
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Болсон"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Дэлгэх дүрс тэмдэг"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"эсвэл"</string>
- <string name="shortcut_helper_key_combinations_and_conjunction" msgid="6138186504075880224">"нэмэх нь"</string>
+ <string name="shortcut_helper_key_combinations_and_conjunction" msgid="6138186504075880224">"болон"</string>
<string name="shortcut_helper_key_combinations_forward_slash" msgid="1238652537199346970">"урагшаа ташуу зураас"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Чирэх бариул"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Гарын тохиргоо"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Гар дээрх тусгай товчлуурыг дарна уу"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Сайн байна!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Та бүх аппыг харах зангааг гүйцэтгэлээ"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Гарын арын гэрэл"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-с %1$d-р түвшин"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Гэрийн удирдлага"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index c21a666..b108ccc 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -113,7 +113,7 @@
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एक अॅप रेकॉर्ड करा"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूर्ण स्क्रीन रेकॉर्ड करा"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"संपूर्ण स्क्रीन रेकॉर्ड करा: %s"</string>
- <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"तुम्ही तुमची पूर्ण स्क्रीन रेकॉर्ड करता, तेव्हा तुमच्या स्क्रीनवर दाखवलेली कोणतीही गोष्टी रेकॉर्ड केली जाते. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
+ <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"तुम्ही तुमची पूर्ण स्क्रीन रेकॉर्ड करता, तेव्हा तुमच्या स्क्रीनवर दाखवलेली कोणतीही गोष्ट रेकॉर्ड केली जाते. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"तुम्ही अॅप रेकॉर्ड करता, तेव्हा त्या अॅपमध्ये दाखवलेली किंवा प्ले केलेली कोणतीही गोष्ट रेकॉर्ड केली जाते. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रीन रेकॉर्ड करा"</string>
<string name="screenrecord_app_selector_title" msgid="3854492366333954736">"रेकॉर्ड करण्यासाठी अॅप निवडा"</string>
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"विजेट वापरून अॅप उघडण्यासाठी, तुम्हाला हे तुम्हीच असल्याची पडताळणी करावी लागेल. तसेच, लक्षात ठेवा, तुमचा टॅबलेट लॉक असतानादेखील कोणीही ती पाहू शकते. काही विजेट कदाचित तुमच्या लॉक स्क्रीनसाठी नाहीत आणि ती इथे जोडणे असुरक्षित असू शकते."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"समजले"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"विजेट"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"विजेट\" शॉर्टकट जोडण्यासाठी, सेटिंग्जमध्ये \"लॉक स्क्रीनवर विजेट दाखवा\" सुरू असल्याची खात्री करा."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"सेटिंग्ज"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"वापरकर्ता स्विच करा"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेनू"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अॅप्स आणि डेटा हटवला जाईल."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचना"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"संभाषणे"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"सर्व सायलंट सूचना साफ करा"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"व्यत्यय आणून नकाद्वारे सूचना थांबवल्या"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{कोणतेही नोटिफिकेशन नाही}=1{{mode} द्वारे नोटिफिकेशन थांबवली आहेत}=2{{mode} द्वारे आणि आणखी एका मोडद्वारे नोटिफिकेशन थांबवली आहेत}other{{mode} द्वारे आणि आणखी # मोडद्वारे नोटिफिकेशन थांबवली आहेत}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"आता सुरू करा"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"हेड ट्रॅकिंग"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"रिंगर मोड बदलण्यासाठी टॅप करा"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"रिंगर मोड"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करा"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"म्यूट काढून टाका"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"व्हायब्रेट करा"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"कीबोर्ड शॉर्टकट कस्टमाइझ करा"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"शॉर्टकट काढून टाकायचा आहे का?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"डीफॉल्टवर पुन्हा रीसेट करायचे आहे का?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"शॉर्टकट असाइन करण्यासाठी की प्रेस करा"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"यामुळे तुमचा कस्टम शॉर्टकट कायमचा हटवला जाईल."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"हे तुमचे सर्व कस्टम शॉर्टकट कायमचे हटवेल."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"शोधण्यासाठी शॉर्टकट"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कोणतेही शोध परिणाम नाहीत"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"कोलॅप्स करा आयकन"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"कीबोर्ड सेटिंग्ज"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"शॉर्टकट सेट करा"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"काढून टाका"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"होय, रीसेट करा"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"रद्द करा"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"की प्रेस करा"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"की कॉम्बिनेशन आधीपासून वापरले जात आहे. दुसरी की वापरून पहा."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"तुमच्या कीबोर्डवर अॅक्शन की प्रेस करा"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"खूप छान!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"तुम्ही ॲप्स पाहण्याचे जेश्चर पूर्ण केले आहे"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड बॅकलाइट"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d पैकी %1$d पातळी"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 62f85a5..6b9d6d6 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Untuk membuka apl menggunakan widget, anda perlu mengesahkan identiti anda. Selain itu, perlu diingat bahawa sesiapa sahaja boleh melihat widget tersebut, walaupun semasa tablet anda dikunci. Sesetengah widget mungkin tidak sesuai untuk skrin kunci anda dan mungkin tidak selamat untuk ditambahkan di sini."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widget"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Untuk menambahkan pintasan \"Widget\", pastikan \"Tunjukkan widget pada skrin kunci\" didayakan dalam tetapan."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Tetapan"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Tukar pengguna"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu tarik turun"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Pemberitahuan"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Perbualan"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Kosongkan semua pemberitahuan senyap"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Pemberitahuan dijeda oleh Jangan Ganggu"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Tiada pemberitahuan}=1{Pemberitahuan dijeda oleh {mode}}=2{Pemberitahuan dijeda oleh {mode} dan satu lagi mod yang lain}other{Pemberitahuan dijeda oleh {mode} dan # mod yang lain}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Mulakan sekarang"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Penjejakan Kepala"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Ketik untuk menukar mod pendering"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"mod pendering"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"redam"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"nyahredam"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"getar"</string>
@@ -1426,20 +1428,17 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan papan kekunci"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sesuaikan pintasan papan kekunci"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Alih keluar pintasan?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Tetapkan kembali kepada lalai?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Tekan kekunci untuk menetapkan pintasan"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Tindakan ini akan memadamkan pintasan tersuai anda secara kekal."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Tindakan ini akan memadamkan semua pintasan tersuai anda secara kekal."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pintasan carian"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Tiada hasil carian"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kuncupkan ikon"</string>
<string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon kekunci tindakan atau Meta"</string>
<string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikon tambah"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Sesuaikan"</string>
- <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
- <skip />
+ <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Tetapkan semula"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Selesai"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Kembangkan ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"atau"</string>
@@ -1449,8 +1448,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Tetapan Papan Kekunci"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tetapkan pintasan"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Alih keluar"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Ya, tetapkan semula"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Batal"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tekan kekunci"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Gabungan kekunci sudah digunakan. Cuba kekunci lain."</string>
@@ -1482,6 +1480,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tekan kekunci tindakan pada papan kekunci anda"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Syabas!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Anda telah melengkapkan gerak isyarat lihat semua apl"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Cahaya latar papan kekunci"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Tahap %1$d daripada %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kawalan Rumah"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 393f2f2..50f75ee 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"အကြောင်းကြားချက်များ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"စကားဝိုင်းများ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"အသံတိတ် အကြောင်းကြားချက်များအားလုံးကို ရှင်းလင်းရန်"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"အကြောင်းကြားချက်များကို \'မနှောင့်ယှက်ရ\' က ခေတ္တရပ်ထားသည်"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{အကြောင်းကြားချက် မရှိပါ}=1{{mode} က ခဏရပ်ထားသော အကြောင်းကြားချက်များ}=2{{mode} နှင့် အခြားမုဒ်တစ်ခုက ခဏရပ်ထားသော အကြောင်းကြားချက်များ}other{{mode} နှင့် အခြားမုဒ် # ခုက ခဏရပ်ထားသော အကြောင်းကြားချက်များ}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ယခု စတင်ပါ"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ခေါင်းလှုပ်ရှားမှု"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ဖုန်းခေါ်သံမုဒ်သို့ ပြောင်းရန် တို့ပါ"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"အသံမြည်မုဒ်"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"အသံပိတ်ရန်"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"အသံဖွင့်ရန်"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"တုန်ခါမှု"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ကီးဘုတ်တွင် လုပ်ဆောင်ချက်ကီး နှိပ်ပါ"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"အလွန်ကောင်းပါသည်။"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"အက်ပ်အားလုံးကို ကြည့်ခြင်းလက်ဟန် သင်ခန်းစာပြီးပါပြီ"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ကီးဘုတ်နောက်မီး"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"အဆင့် %2$d အနက် %1$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"အိမ်ထိန်းချုပ်မှုများ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 7454d63..f84353f 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Varsler"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Samtaler"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Fjern alle lydløse varsler"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Varsler er satt på pause av «Ikke forstyrr»"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Ingen varsler}=1{Varsler er satt på pause av {mode}}=2{Varsler er satt på pause av {mode} og én modus til}other{Varsler er satt på pause av {mode} og # moduser til}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Start nå"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Hodesporing"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Trykk for å endre ringemodus"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"modus for ringeprogrammet"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"kutt lyden"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå på lyden"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrer"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Trykk på handlingstasten på tastaturet"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bra!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Du har fullført bevegelsen for å se alle apper"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Bakgrunnslys for tastatur"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Hjemkontroller"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 9b8af93..8fd8367 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाहरू"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"वार्तालापहरू"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"सबै मौन सूचनाहरू हटाउनुहोस्"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"बाधा नपुऱ्याउनुहोस् नामक मोडमार्फत पज पारिएका सूचनाहरू"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{कुनै पनि नोटिफिकेसन छैन}=1{{mode} ले गर्दा नोटिफिकेसनहरू पज गरिएका छन्}=2{{mode} र अन्य एक मोडले गर्दा नोटिफिकेसनहरू पज गरिएका छन्}other{{mode} र अन्य # वटा मोडले गर्दा नोटिफिकेसनहरू पज गरिएका छन्}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"अहिले न"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"हेड ट्र्याकिङ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"रिङ्गर मोड बदल्न ट्याप गर्नुहोस्"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"घण्टी बजाउने मोड"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्युट गर्नुहोस्"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्युट गर्नुहोस्"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"कम्पन गर्नुहोस्"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"आफ्नो किबोर्डमा भएको एक्सन की थिच्नुहोस्"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"स्याबास!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"तपाईंले जेस्चर प्रयोग गरी सबै एपहरू हेर्ने तरिका सिक्नुभएको छ"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"किबोर्ड ब्याकलाइट"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d मध्ये %1$d औँ स्तर"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"होम कन्ट्रोलहरू"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 12f4156..d03b5fb 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Als je een app wilt openen met een widget, moet je verifiëren dat jij het bent. Houd er ook rekening mee dat iedereen ze kan bekijken, ook als je tablet vergrendeld is. Bepaalde widgets zijn misschien niet bedoeld voor je vergrendelscherm en kunnen hier niet veilig worden toegevoegd."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgets"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Als je de snelkoppeling Widgets wilt toevoegen, zorg je dat Widgets tonen op het vergrendelingsscherm aanstaat in de instellingen."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Instellingen"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Gebruiker wijzigen"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pull-downmenu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Meldingen"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Gesprekken"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Alle stille meldingen wissen"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Meldingen onderbroken door \'Niet storen\'"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Geen meldingen}=1{Meldingen onderbroken door {mode}}=2{Meldingen onderbroken door {mode} en 1 andere modus}other{Meldingen onderbroken door {mode} en # andere modi}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Nu starten"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Hoofdtracking"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tik om de beltoonmodus te wijzigen"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"beltoonmodus"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"geluid uit"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"geluid aanzetten"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"trillen"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Sneltoetsen"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sneltoetsen aanpassen"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Sneltoets verwijderen?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Resetten naar standaard?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Druk op de toets om de sneltoets toe te wijzen"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Hiermee wordt je aangepaste sneltoets definitief verwijderd."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Hiermee worden al je aangepaste snelkoppelingen definitief verwijderd."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sneltoetsen zoeken"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Geen zoekresultaten"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icoon voor samenvouwen"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Toetsenbordinstellingen"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Sneltoets instellen"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Verwijderen"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Ja, resetten"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Annuleren"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Druk op een toets"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Toetsencombinatie is al in gebruik. Probeer een andere toets."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Druk op de actietoets op het toetsenbord"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Goed gedaan!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Je weet nu hoe je het gebaar Alle apps bekijken maakt"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Achtergrondverlichting van toetsenbord"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d van %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Bediening voor in huis"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 28d8cfc..91900e7 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ସମସ୍ତ ନୀରବ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଖାଲି କରନ୍ତୁ"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ବିକଳ୍ପ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତି ପଜ୍ ହୋଇଛି"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ}=1{{mode} ଦ୍ୱାରା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବିରତ କରାଯାଇଛି}=2{{mode} ଏବଂ ଅନ୍ୟ ଏକ ମୋଡ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବିରତ କରାଯାଇଛି}other{{mode} ଏବଂ ଅନ୍ୟ # ମୋଡ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବିରତ କରାଯାଇଛି}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ହେଡ ଟ୍ରାକିଂ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ରିଙ୍ଗର୍ ମୋଡ୍ ବଦଳାଇବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ରିଂଗର ମୋଡ"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ମ୍ୟୁଟ"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ଅନ୍-ମ୍ୟୁଟ୍ କରନ୍ତୁ"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ଭାଇବ୍ରେଟ୍"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ଆପଣଙ୍କର କୀବୋର୍ଡରେ ଆକ୍ସନ କୀ\'କୁ ଦବାନ୍ତୁ"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ବହୁତ ବଢ଼ିଆ!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ଆପଣ ସମସ୍ତ ଆପ୍ସ ଜେଶ୍ଚରକୁ ଭ୍ୟୁ କରିବା ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"କୀବୋର୍ଡ ବେକଲାଇଟ"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dରୁ %1$d ନମ୍ବର ଲେଭେଲ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ହୋମ କଣ୍ଟ୍ରୋଲ୍ସ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 9df55d6..ba51bf2 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ਸੂਚਨਾਵਾਂ"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"ਗੱਲਾਂਬਾਤਾਂ"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ਸਾਰੀਆਂ ਸ਼ਾਂਤ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{ਕੋਈ ਸੂਚਨਾ ਨਹੀਂ ਹੈ}=1{{mode} ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ}=2{{mode} ਅਤੇ ਇੱਕ ਹੋਰ ਮੋਡ ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ}other{{mode} ਅਤੇ # ਹੋਰ ਮੋਡਾਂ ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ਹੈੱਡ ਟਰੈਕਿੰਗ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ਰਿੰਗਰ ਮੋਡ ਨੂੰ ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ਰਿੰਗਰ ਮੋਡ"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ਮਿਊਟ ਕਰੋ"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ਅਣਮਿਊਟ ਕਰੋ"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ਥਰਥਰਾਹਟ"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ਆਪਣੇ ਕੀ-ਬੋਰਡ \'ਤੇ ਕਾਰਵਾਈ ਕੁੰਜੀ ਨੂੰ ਦਬਾਓ"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ਬਹੁਤ ਵਧੀਆ!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ਤੁਸੀਂ \'ਸਾਰੀਆਂ ਐਪਾਂ ਦੇਖੋ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ ਹੈ"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ਕੀ-ਬੋਰਡ ਬੈਕਲਾਈਟ"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ਵਿੱਚੋਂ %1$d ਪੱਧਰ"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ਹੋਮ ਕੰਟਰੋਲ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 9edb183e..6785668 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Aby otworzyć aplikację za pomocą widżetu, musisz potwierdzić swoją tożsamość. Pamiętaj też, że każdy będzie mógł wyświetlić widżety nawet wtedy, gdy tablet będzie zablokowany. Niektóre widżety mogą nie być przeznaczone do umieszczenia na ekranie blokady i ich dodanie w tym miejscu może być niebezpieczne."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widżety"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Aby dodać skrót „Widżety”, upewnij się, że opcja „Pokaż widżety na ekranie blokady” jest włączona w ustawieniach."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Ustawienia"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Przełącz użytkownika"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Powiadomienia"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Rozmowy"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Usuń wszystkie ciche powiadomienia"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Powiadomienia wstrzymane przez tryb Nie przeszkadzać"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Brak powiadomień}=1{Powiadomienia są wstrzymane przez tryb {mode}}=2{Powiadomienia są wstrzymane przez tryb {mode} i 1 inny tryb}few{Powiadomienia są wstrzymane przez tryb {mode} i # inne tryby}many{Powiadomienia są wstrzymane przez tryb {mode} i # innych trybów}other{Powiadomienia są wstrzymane przez tryb {mode} i # innego trybu}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Rozpocznij teraz"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Śledzenie głowy"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Kliknij, aby zmienić tryb dzwonka"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"tryb dzwonka"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"wycisz"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"wyłącz wyciszenie"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"włącz wibracje"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Skróty klawiszowe"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Dostosuj skróty klawiszowe"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Usunąć skrót?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Zresetować do ustawień domyślnych?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Naciśnij klawisz, aby przypisać skrót"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Spowoduje to trwałe usunięcie skrótu niestandardowego."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Spowoduje to trwałe usunięcie wszystkich skrótów niestandardowych."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Skróty do wyszukiwania"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Brak wyników wyszukiwania"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zwijania"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Ustawienia klawiatury"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Ustaw skrót"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Usuń"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Tak, zresetuj"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Anuluj"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Naciśnij klawisz"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinacja klawiszy jest już używana. Użyj innego klawisza."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Naciśnij klawisz działania na klawiaturze"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Brawo!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Znasz już gest wyświetlania wszystkich aplikacji"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podświetlenie klawiatury"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Poziom %1$d z %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Sterowanie domem"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 3871f7a..9515227 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -306,7 +306,7 @@
<string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string>
<string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectado"</string>
<string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Compartilhamento de áudio"</string>
- <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active" msgid="8680997711431098238">"Compatível com compartilhamento de áudio"</string>
+ <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active" msgid="8680997711431098238">"Aceita compartilhamento de áudio"</string>
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvo"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string>
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Apagar todas as notificações silenciosas"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações pausadas pelo modo \"Não perturbe\""</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Sem notificações}=1{Notificações pausadas pelo modo {mode}}=2{Notificações pausadas por {mode} e mais um modo}one{Notificações pausadas por {mode} e mais # modo}many{Notificações pausadas por {mode} e mais # de modos}other{Notificações pausadas por {mode} e mais # modos}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Rastreamento de cabeça"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Toque para mudar o modo da campainha"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"modo da campainha"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar o som"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ativar o som"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1438,8 +1442,7 @@
<string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícone da tecla de ação"</string>
<string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ícone de adição"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
- <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
- <skip />
+ <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Redefinir"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
@@ -1482,6 +1485,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pressione a tecla de ação no teclado"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Muito bem!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Você concluiu o gesto para ver todos os apps"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz de fundo do teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Automação residencial"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index c0e65c7..40df4c0 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir uma app através de um widget, vai ter de validar a sua identidade. Além disso, tenha em atenção que qualquer pessoa pode ver os widgets, mesmo quando o tablet estiver bloqueado. Alguns widgets podem não se destinar ao ecrã de bloqueio e pode ser inseguro adicioná-los aqui."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Widgets"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Para adicionar o atalho \"Widgets\", certifique-se de que a opção \"Mostrar widgets no ecrã de bloqueio\" está ativada nas definições."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Definições"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mudar utilizador"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pendente"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Limpar todas as notificações silenciosas"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações colocadas em pausa pelo modo Não incomodar."</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Sem notificações}=1{Notificações pausadas pelo modo {mode}}=2{Notificações pausadas pelo modo {mode} e mais um modo}many{Notificações pausadas pelo modo {mode} e mais # modos}other{Notificações pausadas pelo modo {mode} e mais # modos}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Começar agora"</string>
@@ -707,6 +707,7 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Posição da cabeça"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Toque para alterar o modo de campainha"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"modo de som"</string>
+ <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>, toque para alterar o modo de som"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar som"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"reativar som"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1426,20 +1427,17 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos de teclado"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalize os atalhos de teclado"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Remover atalho?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Repor para a predefinição?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Prima a tecla para atribuir o atalho"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Esta ação elimina o atalho personalizado permanentemente."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Esta ação elimina todos os seus atalhos personalizados permanentemente."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pesquisar atalhos"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado da pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone de reduzir"</string>
<string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícone da tecla Meta ou de ação"</string>
<string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ícone de mais"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
- <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
- <skip />
+ <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Repor"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone de expandir"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
@@ -1449,8 +1447,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Definições do teclado"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Configurar atalho"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Remover"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Sim, repor"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Cancelar"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Prima a tecla"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"A combinação de teclas já está a ser usada. Experimente outra tecla."</string>
@@ -1482,6 +1479,7 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Prima a tecla de ação no teclado"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Muito bem!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Concluiu o gesto para ver todas as apps"</string>
+ <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animação do tutorial, clique para pausar e retomar a reprodução."</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz do teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Controlos domésticos"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 3871f7a..9515227 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -306,7 +306,7 @@
<string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string>
<string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectado"</string>
<string name="quick_settings_bluetooth_device_audio_sharing" msgid="1496358082943301670">"Compartilhamento de áudio"</string>
- <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active" msgid="8680997711431098238">"Compatível com compartilhamento de áudio"</string>
+ <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active" msgid="8680997711431098238">"Aceita compartilhamento de áudio"</string>
<string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvo"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"desconectar"</string>
<string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"ativar"</string>
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificações"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Apagar todas as notificações silenciosas"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificações pausadas pelo modo \"Não perturbe\""</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Sem notificações}=1{Notificações pausadas pelo modo {mode}}=2{Notificações pausadas por {mode} e mais um modo}one{Notificações pausadas por {mode} e mais # modo}many{Notificações pausadas por {mode} e mais # de modos}other{Notificações pausadas por {mode} e mais # modos}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Rastreamento de cabeça"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Toque para mudar o modo da campainha"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"modo da campainha"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar o som"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ativar o som"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string>
@@ -1438,8 +1442,7 @@
<string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ícone da tecla de ação"</string>
<string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ícone de adição"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Personalizar"</string>
- <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
- <skip />
+ <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Redefinir"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Concluir"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
@@ -1482,6 +1485,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pressione a tecla de ação no teclado"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Muito bem!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Você concluiu o gesto para ver todos os apps"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz de fundo do teclado"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Automação residencial"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 5911c40..3b5cd89 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificări"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Conversații"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Șterge toate notificările silențioase"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Notificări întrerupte prin „Nu deranja”"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Nicio notificare}=1{Notificările au fost întrerupte de {mode}}=2{Notificările au fost întrerupte de {mode} și de un alt mod}few{Notificările au fost întrerupte de {mode} și de alte # moduri}other{Notificările au fost întrerupte de {mode} și de alte # de moduri}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Începe acum"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Urmărirea mișcărilor capului"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Atinge pentru a schimba modul soneriei"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"modul sonerie"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"dezactivează sunetul"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"activează sunetul"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrații"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Apasă tasta de acțiuni de pe tastatură"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Felicitări!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Ai finalizat gestul pentru afișarea tuturor aplicațiilor"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Iluminarea din spate a tastaturii"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivelul %1$d din %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Comenzi pentru locuință"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 95c4ee3..b026787 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Чтобы открыть приложение, используя виджет, вам нужно будет подтвердить свою личность. Обратите внимание, что виджеты видны всем, даже если планшет заблокирован. Некоторые виджеты не предназначены для использования на заблокированном экране. Добавлять их туда может быть небезопасно."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"ОК"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Виджеты"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Чтобы создать ярлык \"Виджеты\", убедитесь, что в настройках включена функция \"Показывать виджеты на заблокированном экране\"."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Настройки"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Сменить пользователя."</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"раскрывающееся меню"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Все приложения и данные этого профиля будут удалены."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Уведомления"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Разговоры"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Отклонить все беззвучные уведомления"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"В режиме \"Не беспокоить\" уведомления заблокированы"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Уведомлений нет}=1{Режим \"{mode}\" приостанавливает уведомления}=2{Режим \"{mode}\" и ещё один режим приостанавливают уведомления}one{Режим \"{mode}\" и ещё # режим приостанавливают уведомления}few{Режим \"{mode}\" и ещё # режима приостанавливают уведомления}many{Режим \"{mode}\" и ещё # режимов приостанавливают уведомления}other{Режим \"{mode}\" и ещё # режима приостанавливают уведомления}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Начать"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Динамичное"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Нажмите, чтобы изменить режим звонка."</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"режим звонка"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"отключить звук"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"включить звук"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"включить вибрацию"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Быстрые клавиши"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Как настроить быстрые клавиши"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Удалить сочетание клавиш?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Сбросить настройки?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Нажмите клавишу, чтобы назначить сочетание клавиш."</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Настроенное сочетание будет безвозвратно удалено."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Все пользовательские ярлыки будут безвозвратно удалены."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Найти быстрые клавиши"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ничего не найдено"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Свернуть\""</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Настройки клавиатуры"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Задать сочетание клавиш"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Удалить"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Сбросить"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Отмена"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Нажмите клавишу"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Это сочетание клавиш уже используется. Попробуйте другое."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Нажмите клавишу действия на клавиатуре."</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Блестяще!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Вы выполнили жест для просмотра всех приложений."</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Подсветка клавиатуры"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Уровень %1$d из %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Управление домом"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 36879d6..a496c7c 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"දැනුම් දීම්"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"සංවාද"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"සියලු නිහඬ දැනුම්දීම් හිස් කරන්න"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"බාධා නොකරන්න මගින් විරාම කරන ලද දැනුම්දීම්"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{දැනුම්දීම් නැත}=1{{mode} මගින් දැනුම්දීම් විරාම කරන ලදි}=2{{mode} සහ තව එක ප්රකාරයක් මගින් දැනුම්දීම් විරාම කරන ලදි}one{{mode} සහ තව ප්රකාර #ක් මගින් දැනුම්දීම් විරාම කරන ලදි}other{{mode} සහ තව ප්රකාර #ක් මගින් දැනුම්දීම් විරාම කරන ලදි}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"දැන් අරඹන්න"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"හිස ලුහුබැඳීම"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"නාදකය වෙනස් කිරීමට තට්ටු කරන්න"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"හඬ නඟන ආකාරය"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"නිහඬ කරන්න"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"නිශ්ශබ්දතාවය ඉවත් කරන්න"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"කම්පනය"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ඔබේ යතුරු පුවරුවේ ක්රියාකාරී යතුර ඔබන්න"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"හොඳින් කළා!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ඔබ සියලු යෙදුම් ඉංගිත බැලීම සම්පූර්ණ කර ඇත"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"යතුරු පුවරු පසු ආලෝකය"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dන් %1$d වැනි මට්ටම"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"නිවෙස් පාලන"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index c972c18..0c4880d 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ak chcete otvoriť aplikáciu pomocou miniaplikácie, budete musieť overiť svoju totožnosť. Pamätajte, že si miniaplikáciu môže pozrieť ktokoľvek, aj keď máte tablet uzamknutý. Niektoré miniaplikácie možno nie sú určené pre uzamknutú obrazovku a ich pridanie tu môže byť nebezpečné."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Dobre"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Miniaplikácie"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Ak chcete pridať odkaz Miniaplikácie, uistite sa, že v nastaveniach je zapnutá možnosť Zobrazovať miniaplikácie na uzamknutej obrazovke."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Nastavenia"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Prepnutie používateľa"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbaľovacia ponuka"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Upozornenia"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzácie"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Vymazať všetky tiché upozornenia"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Upozornenia sú pozastavené režimom bez vyrušení"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Žiadne upozornenia}=1{Upozornenia boli pozastavené režimom {mode}}=2{Upozornenia boli pozastavené režimom {mode} a jedným ďalším}few{Upozornenia boli pozastavené režimom {mode} a # ďalšími}many{Notifications paused by {mode} and # other modes}other{Upozornenia boli pozastavené režimom {mode} a # ďalšími}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Spustiť"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Sledovanie hlavy"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Režim zvonenia zmeníte klepnutím"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"režim zvonenia"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnite zvuk"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnite zvuk"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"zapnite vibrovanie"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové skratky"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prispôsobenie klávesových skratiek"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Chcete skratku odstrániť?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Chcete resetovať na predvolené nastavenie?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Stlačením klávesa priraďte skratku"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Týmto natrvalo odstránite vlastnú skratku."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Týmto natrvalo odstránite všetky vlastné odkazy."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prehľadávať skratky"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žiadne výsledky vyhľadávania"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zbalenia"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavenia klávesnice"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastaviť skratku"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Odstrániť"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Áno, resetovať"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Zrušiť"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Stlačte kláves"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinácia klávesov sa už používa. Skúste iný kláves."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Stlačte na klávesnici akčný kláves"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Dobre!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Použili ste gesto na zobrazenie všetkých aplikácií."</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvietenie klávesnice"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. úroveň z %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ovládanie domácnosti"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 914df72..dbeed9d 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Če želite aplikacijo odpreti s pripomočkom, morate potrditi, da ste to vi. Upoštevajte tudi, da si jih lahko ogledajo vsi, tudi ko je tablični računalnik zaklenjen. Nekateri pripomočki morda niso predvideni za uporabo na zaklenjenem zaslonu, zato jih tukaj morda ni varno dodati."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Razumem"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Pripomočki"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Če želite dodati bližnjico »Pripomočki«, v nastavitvah omogočite možnost »Prikaz pripomočkov na zaklenjenem zaslonu«."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Nastavitve"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Preklop med uporabniki"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"spustni meni"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Obvestila"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Pogovori"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Brisanje vseh tihih obvestil"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Prikazovanje obvestil je začasno zaustavljeno z načinom »ne moti«"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Ni obvestil}=1{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode}}=2{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še enim drugim načinom}one{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še # drugim načinom}two{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še # drugima načinoma}few{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še # drugimi načini}other{Prikazovanje obvestil je začasno zaustavljeno z načinom {mode} in še # drugimi načini}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Začni zdaj"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Spremljanje glave"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Dotaknite se, če želite spremeniti način zvonjenja."</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"način zvonjenja"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izklop zvoka"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"vklop zvoka"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibriranje"</string>
@@ -1426,20 +1428,17 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Bližnjične tipke"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagajanje bližnjičnih tipk"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Želite odstraniti bližnjico?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Želite ponastaviti na privzete bližnjice?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pritisnite tipko za dodelitev bližnjice"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"S tem boste trajno izbrisali bližnjico po meri."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"S tem boste trajno izbrisali vse bližnjice po meri."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Iskanje po bližnjicah"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ni rezultatov iskanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za strnitev"</string>
<string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona tipke za dejanje ali metapodatke"</string>
<string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Ikona znaka plus"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Prilagodi"</string>
- <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
- <skip />
+ <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Ponastavi"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Končano"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za razširitev"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ali"</string>
@@ -1449,8 +1448,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Nastavitve tipkovnice"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Nastavite bližnjico"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Odstrani"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Da, ponastavi"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Prekliči"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pritisnite tipko"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinacija tipk je že v uporabi. Poskusite z drugo tipko."</string>
@@ -1482,6 +1480,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite tipko za dejanja na tipkovnici"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Odlično!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Izvedli ste potezo za ogled vseh aplikacij"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Osvetlitev tipkovnice"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Stopnja %1$d od %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrolniki za dom"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 6a597f7..743aad0 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Njoftimet"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Bisedat"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Pastro të gjitha njoftimet në heshtje"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Njoftimet janë vendosur në pauzë nga modaliteti \"Mos shqetëso\""</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Asnjë njoftim}=1{Njoftimet u vendosën në pauzë nga {mode}}=2{Njoftimet u vendosën në pauzë nga {mode} dhe një modalitet tjetër}other{Njoftimet u vendosën në pauzë nga {mode} dhe # modalitete të tjera}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Fillo tani"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Ndjekja e lëvizjeve të kokës"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Trokit për të ndryshuar modalitetin e ziles"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"modaliteti i ziles"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"çaktivizo audion"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktivizo audion"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"lësho dridhje"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Shtyp tastin e veprimit në tastierë"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Shumë mirë!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Përfundove gjestin për shikimin e të gjitha aplikacioneve"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Drita e sfondit e tastierës"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveli: %1$d nga %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrollet e shtëpisë"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 560f4d7..9a15268 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Да бисте отворили апликацију која користи виџет, треба да потврдите да сте то ви. Имајте у виду да свако може да га види, чак и када је таблет закључан. Неки виџети можда нису намењени за закључани екран и можда није безбедно да их тамо додате."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Важи"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Виџети"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Да бисте додали пречицу Виџети, уверите се да је у подешавањима омогућено Приказуј виџете на закључаном екрану."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Подешавања"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Замени корисника"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падајући мени"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Обавештења"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Конверзације"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Обришите сва нечујна обавештења"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Обавештења су паузирана режимом Не узнемиравај"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Нема обавештења}=1{Обавештења је паузирао {mode}}=2{Обавештења су паузирали {mode} и још један режим}one{Обавештења су паузирали {mode} и још # режим}few{Обавештења су паузирали {mode} и још # режима}other{Обавештења су паузирали {mode} и још # режима}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Започни"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Праћење главе"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Додирните да бисте променили режим звона"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"режим звона"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"искључите звук"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"укључите звук"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибрација"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Тастерске пречице"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Прилагодите тастерске пречице"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Желите да уклоните пречицу?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Желите да ресетујете на подразумевано?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Притисните тастер да бисте доделили пречицу"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Овим ћете трајно избрисати прилагођену пречицу."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Тиме ћете трајно избрисати све прилагођене пречице."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Претражите пречице"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нема резултата претраге"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за скупљање"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Подешавања тастатуре"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Подеси пречицу"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Уклони"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Да, ресетуј"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Откажи"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Притисните тастер"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Комбинација тастера се већ користи. Пробајте са другим тастером."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Притисните тастер радњи на тастатури"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Одлично!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Довршили сте покрет за приказивање свих апликација."</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Позадинско осветљење тастатуре"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. ниво од %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Контроле за дом"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 2996033..c8fee61 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Aviseringar"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Konversationer"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Rensa alla ljudlösa aviseringar"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Aviseringar har pausats via Stör ej"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Inga aviseringar}=1{Aviseringar har pausats av {mode}}=2{Aviseringar har pausats av {mode} och ett annat läge}other{Aviseringar har pausats av {mode} och # andra lägen}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Starta nu"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Huvudspårning"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Tryck för att ändra ringsignalens läge"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ringsignalläge"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"stänga av ljudet"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå på ljudet"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibration"</string>
@@ -1438,8 +1442,7 @@
<string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon för åtgärdstangent"</string>
<string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plusikon"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Anpassa"</string>
- <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
- <skip />
+ <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Återställ"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Klar"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikonen Utöka"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
@@ -1482,6 +1485,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tryck på åtgärdstangenten på tangentbordet"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bra gjort!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Du är klar med rörelsen för att se alla apparna."</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Bakgrundsbelysning för tangentbord"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Hemstyrning"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 7084bbf..44bac92 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Arifa"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Mazungumzo"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Futa arifa zote zisizo na sauti"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Kipengele cha Usinisumbue kimesitisha arifa"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Hakuna arifa}=1{Arifa zimesitishwa na {mode}}=2{Arifa zimesitishwa na {mode} na hali nyingine moja}other{Arifa zimesitishwa na {mode} na hali nyingine #}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Anza sasa"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Ufuatilizi wa Kichwa"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Gusa ili ubadilishe hali ya programu inayotoa milio ya simu"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"hali ya programu inayotoa milio ya simu"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"zima sauti"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"washa sauti"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"tetema"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Bonyeza kitufe cha vitendo kwenye kibodi yako"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Vizuri sana!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Umekamilisha mafunzo ya mguso wa kuangalia programu zote"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Mwanga chini ya kibodi"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Kiwango cha %1$d kati ya %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Dhibiti Vifaa Nyumbani"</string>
diff --git a/packages/SystemUI/res/values-sw600dp-land/styles.xml b/packages/SystemUI/res/values-sw600dp-land/styles.xml
index cde1a1373..45698f7 100644
--- a/packages/SystemUI/res/values-sw600dp-land/styles.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/styles.xml
@@ -22,20 +22,20 @@
<item name="android:layout_marginTop">16dp</item>
<item name="android:textSize">36sp</item>
<item name="android:focusable">true</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Subtitle">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:layout_marginTop">16dp</item>
<item name="android:textSize">18sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Description">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:layout_marginTop">16dp</item>
<item name="android:textSize">18sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp-port/styles.xml b/packages/SystemUI/res/values-sw600dp-port/styles.xml
index 85e7af6..8b3e6fd 100644
--- a/packages/SystemUI/res/values-sw600dp-port/styles.xml
+++ b/packages/SystemUI/res/values-sw600dp-port/styles.xml
@@ -30,7 +30,7 @@
<item name="android:layout_marginTop">24dp</item>
<item name="android:textSize">36sp</item>
<item name="android:focusable">true</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
</resources>
diff --git a/packages/SystemUI/res/values-sw720dp-land/styles.xml b/packages/SystemUI/res/values-sw720dp-land/styles.xml
index e75173d..451a9a9 100644
--- a/packages/SystemUI/res/values-sw720dp-land/styles.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/styles.xml
@@ -22,21 +22,21 @@
<item name="android:layout_marginTop">16dp</item>
<item name="android:textSize">36sp</item>
<item name="android:focusable">true</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Subtitle">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:layout_marginTop">16dp</item>
<item name="android:textSize">18sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Description">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:layout_marginTop">16dp</item>
<item name="android:textSize">18sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
</resources>
diff --git a/packages/SystemUI/res/values-sw720dp-port/styles.xml b/packages/SystemUI/res/values-sw720dp-port/styles.xml
index 85e7af6..8b3e6fd 100644
--- a/packages/SystemUI/res/values-sw720dp-port/styles.xml
+++ b/packages/SystemUI/res/values-sw720dp-port/styles.xml
@@ -30,7 +30,7 @@
<item name="android:layout_marginTop">24dp</item>
<item name="android:textSize">36sp</item>
<item name="android:focusable">true</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 959e2e6..4c65095 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"அறிவிப்புகள்"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"உரையாடல்கள்"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"சைலன்ட் அறிவிப்புகள் அனைத்தையும் அழிக்கும்"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தின் மூலம் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{அறிவிப்புகள் இல்லை}=1{{mode} பயன்முறையால் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன}=2{{mode} மற்றும் வேறொரு பயன்முறையால் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன}other{{mode} மற்றும் வேறு # பயன்முறைகளால் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"இப்போது தொடங்கு"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ஹெட் டிராக்கிங்"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"ரிங்கர் பயன்முறையை மாற்ற தட்டவும்"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ரிங்கர் பயன்முறை"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ஒலியடக்கும்"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ஒலி இயக்கும்"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"அதிர்வுறும்"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"உங்கள் கீபோர்டில் ஆக்ஷன் பட்டனை அழுத்தவும்"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"அருமை!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"அனைத்து ஆப்ஸையும் பார்ப்பதற்கான சைகை பயிற்சியை நிறைவுசெய்துவிட்டீர்கள்"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"கீபோர்டு பேக்லைட்"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"நிலை, %2$d இல் %1$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ஹோம் கன்ட்ரோல்கள்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index a66821b..ebed1877 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"విడ్జెట్ను ఉపయోగించి యాప్ను తెరవడానికి, ఇది మీరేనని వెరిఫై చేయాల్సి ఉంటుంది. అలాగే, మీ టాబ్లెట్ లాక్ చేసి ఉన్నప్పటికీ, ఎవరైనా వాటిని చూడగలరని గుర్తుంచుకోండి. కొన్ని విడ్జెట్లు మీ లాక్ స్క్రీన్కు తగినవి కాకపోవచ్చు, వాటిని ఇక్కడ జోడించడం సురక్షితం కాకపోవచ్చు."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"అర్థమైంది"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"విడ్జెట్లు"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"విడ్జెట్ల\" షార్ట్కట్ను జోడించడానికి, సెట్టింగ్లలో \"లాక్ స్క్రీన్లో విడ్జెట్లను చూపండి\" అనే ఆప్షన్ను ఎనేబుల్ చేసినట్లు నిర్ధారించుకోండి."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"సెట్టింగ్లు"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"వినియోగదారుని మార్చు"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"పుల్డౌన్ మెనూ"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్లోని అన్ని యాప్లు మరియు డేటా తొలగించబడతాయి."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"నోటిఫికేషన్లు"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"సంభాషణలు"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"అన్ని నిశ్శబ్ద నోటిఫికేషన్లను క్లియర్ చేస్తుంది"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"అంతరాయం కలిగించవద్దు ద్వారా నోటిఫికేషన్లు పాజ్ చేయబడ్డాయి"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{నోటిఫికేషన్లు ఏవీ లేవు}=1{{mode} ద్వారా నోటిఫికేషన్లు పాజ్ చేయబడ్డాయి}=2{నోటిఫికేషన్లు, {mode}, మరో ఒక మోడ్ ద్వారా పాజ్ చేయబడ్డాయి}other{నోటిఫికేషన్లు, {mode}, మరో # మోడ్ల ద్వారా పాజ్ చేయబడ్డాయి}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ఇప్పుడే ప్రారంభించండి"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"హెడ్ ట్రాకింగ్"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"రింగర్ మోడ్ను మార్చడానికి ట్యాప్ చేయండి"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"రింగర్ మోడ్"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"మ్యూట్ చేయి"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"అన్మ్యూట్ చేయి"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"వైబ్రేట్"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"కీబోర్డ్ షార్ట్కట్లు"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"కీబోర్డ్ షార్ట్కట్లను అనుకూలంగా మార్చండి"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"షార్ట్కట్ను తీసివేయాలా?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"తిరిగి ఆటోమేటిక్ సెట్టింగ్కు రీసెట్ చేయాలా?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"షార్ట్కట్ను కేటాయించడానికి కీని నొక్కండి"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"ఇది మీ అనుకూల షార్ట్కట్ను శాశ్వతంగా తొలగిస్తుంది."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"ఇది మీ అనుకూల షార్ట్కట్లన్నింటిని శాశ్వతంగా తొలగిస్తుంది."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"షార్ట్కట్లను వెతకండి"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"సెర్చ్ ఫలితాలు ఏవీ లేవు"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"కుదించండి చిహ్నం"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"కీబోర్డ్ సెట్టింగ్లు"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"షార్ట్కట్ను సెట్ చేయండి"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"తీసివేయండి"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"అవును, రీసెట్ చేయాలి"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"రద్దు చేయండి"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"కీని నొక్కండి"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"కీ కాంబినేషన్ ఇప్పటికే వినియోగంలో ఉంది. వేరొక కీని ట్రై చేయండి."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"మీ కీబోర్డ్లో యాక్షన్ కీని నొక్కండి"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"చక్కగా చేశారు!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"అన్ని యాప్లను చూడడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్ను మీరు పూర్తి చేశారు"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"కీబోర్డ్ బ్యాక్లైట్"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dలో %1$dవ స్థాయి"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"హోమ్ కంట్రోల్స్"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 5ead29f..fe13888 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"หากต้องการเปิดแอปโดยใช้วิดเจ็ต คุณจะต้องยืนยันตัวตนของคุณ นอกจากนี้ โปรดทราบว่าผู้อื่นจะดูวิดเจ็ตเหล่านี้ได้แม้ว่าแท็บเล็ตจะล็อกอยู่ก็ตาม วิดเจ็ตบางอย่างอาจไม่ได้มีไว้สำหรับหน้าจอล็อกของคุณ และอาจไม่ปลอดภัยที่จะเพิ่มที่นี่"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"รับทราบ"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"วิดเจ็ต"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"หากต้องการเพิ่มทางลัด \"วิดเจ็ต\" โปรดตรวจสอบว่าได้เปิดใช้ \"แสดงวิดเจ็ตในหน้าจอล็อก\" แล้วในการตั้งค่า"</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"การตั้งค่า"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"สลับผู้ใช้"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"เมนูแบบเลื่อนลง"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"การแจ้งเตือน"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"การสนทนา"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ล้างการแจ้งเตือนแบบไม่มีเสียงทั้งหมด"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"หยุดการแจ้งเตือนชั่วคราวโดย \"ห้ามรบกวน\""</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{ไม่มีการแจ้งเตือน}=1{หยุดการแจ้งเตือนชั่วคราวโดย {mode}}=2{หยุดการแจ้งเตือนชั่วคราวโดย {mode} และโหมดอื่นอีก 1 โหมด}other{หยุดการแจ้งเตือนชั่วคราวโดย {mode} และโหมดอื่นอีก # โหมด}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"เริ่มเลย"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"การติดตามการเคลื่อนไหวของศีรษะ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"แตะเพื่อเปลี่ยนโหมดเสียงเรียกเข้า"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"โหมดเสียงเรียกเข้า"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ปิดเสียง"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"เปิดเสียง"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"สั่น"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"แป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ปรับแต่งแป้นพิมพ์ลัด"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"นำแป้นพิมพ์ลัดออกใช่ไหม"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"รีเซ็ตกลับเป็นค่าเริ่มต้นไหม"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"กดแป้นเพื่อกำหนดแป้นพิมพ์ลัด"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"การดำเนินการนี้จะลบแป้นพิมพ์ลัดที่กำหนดเองอย่างถาวร"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"การดำเนินการนี้จะลบทางลัดที่กำหนดเองทั้งหมดอย่างถาวร"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ค้นหาแป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ไม่พบผลการค้นหา"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ไอคอนยุบ"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"การตั้งค่าแป้นพิมพ์"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"ตั้งค่าแป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"นำออก"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"ใช่ รีเซ็ต"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"ยกเลิก"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"กดแป้น"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"มีการใช้แป้นที่กดร่วมกันนี้แล้ว โปรดลองใช้แป้นอื่น"</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"กดปุ่มดำเนินการบนแป้นพิมพ์"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ยอดเยี่ยม"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"คุณทำท่าทางสัมผัสเพื่อดูแอปทั้งหมดสำเร็จแล้ว"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ไฟแบ็กไลต์ของแป้นพิมพ์"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"ระดับที่ %1$d จาก %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ระบบควบคุมอุปกรณ์สมาร์ทโฮม"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 76375a3..9d79424 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para magbukas ng app gamit ang isang widget, kakailanganin mong i-verify na ikaw iyan. Bukod pa rito, tandaang puwedeng tingnan ng kahit na sino ang mga ito, kahit na naka-lock ang iyong tablet. Posibleng hindi para sa iyong lock screen ang ilang widget at posibleng hindi ligtas ang mga ito na idagdag dito."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Mga Widget"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"Para idagdag ang shortcut na \"Mga Widget,\" tiyaking naka-enable ang \"Ipakita ang mga widget sa lock screen\" sa mga setting."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Mga Setting"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Magpalit ng user"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Mga Notification"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Mga Pag-uusap"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"I-clear ang lahat ng silent na notification"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Mga notification na na-pause ng Huwag Istorbohin"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Walang notification}=1{Na-pause ng {mode} ang mga notification}=2{Na-pause ng {mode} at isa pang mode ang mga notification}one{Na-pause ng {mode} at # pang mode ang mga notification}other{Na-pause ng {mode} at # pang mode ang mga notification}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Magsimula ngayon"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Pag-track ng Ulo"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"I-tap para baguhin ang ringer mode"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"ringer mode"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"i-mute"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"i-unmute"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"i-vibrate"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Mga keyboard shortcut"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"I-customize ang mga keyboard shortcut"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Alisin ang shortcut?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"I-reset pabalik sa default?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pindutin ang key para magtalaga ng shortcut"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Permanente nitong ide-delete ang iyong custom na shortcut."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Permanente nitong ide-delete ang lahat ng iyong custom na shortcut."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Mga shortcut ng paghahanap"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Walang resulta ng paghahanap"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"I-collapse ang icon"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Mga Setting ng Keyboard"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Magtakda ng shortcut"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Alisin"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Oo, i-reset"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Kanselahin"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Pindutin ang key"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ginagamit na ang kumbinasyon ng key. Sumubok ng ibang key."</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pindutin ang action key sa iyong keyboard"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Magaling!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Nakumpleto mo ang galaw sa pag-view ng lahat ng app"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Backlight ng keyboard"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d sa %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Mga Home Control"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index e1484e3..046d973 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirimler"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Görüşmeler"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Sessiz bildirimlerin tümünü temizle"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bildirimler, Rahatsız Etmeyin özelliği tarafından duraklatıldı"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Bildirim yok}=1{Bildirimler {mode} tarafından duraklatıldı}=2{Bildirimler, {mode} ve bir diğer mod tarafından duraklatıldı}other{Bildirimler, {mode} ve # diğer mod tarafından duraklatıldı}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Şimdi başlat"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Baş Takibi"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Telefon zili modunu değiştirmek için dokunun"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"telefon zili modu"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"sesi kapat"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"sesi aç"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"titreşim"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Klavyenizde eylem tuşuna basın"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Tebrikler!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Tüm uygulamaları görüntüleme hareketini tamamladınız"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klavye aydınlatması"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Seviye %1$d / %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Ev Kontrolleri"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index e4cc156..a414824 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Сповіщення"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Розмови"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Очистити всі беззвучні сповіщення"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Режим \"Не турбувати\" призупинив сповіщення"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Немає сповіщень}=1{Режим \"{mode}\" призупинив надсилання сповіщень}=2{\"{mode}\" і ще один режим призупинили надсилання сповіщень}one{\"{mode}\" і ще # режим призупинили надсилання сповіщень}few{\"{mode}\" і ще # режими призупинили надсилання сповіщень}many{\"{mode}\" і ще # режимів призупинили надсилання сповіщень}other{\"{mode}\" і ще # режиму призупинили надсилання сповіщень}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Почати зараз"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Відстеження рухів голови"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Торкніться, щоб змінити режим дзвінка"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"режим дзвінка"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"вимкнути звук"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"увімкнути звук"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"увімкнути вібросигнал"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Натисніть клавішу дії на клавіатурі"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Чудово!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Ви виконали жест для перегляду всіх додатків"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Підсвічування клавіатури"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Рівень %1$d з %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Автоматизація дому"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index def8806..2980b2f 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"ویجیٹ کے ذریعے ایپ کھولنے کے لیے آپ کو تصدیق کرنی ہوگی کہ یہ آپ ہی ہیں۔ نیز، ذہن میں رکھیں کہ کوئی بھی انہیں دیکھ سکتا ہے، یہاں تک کہ جب آپ کا ٹیبلیٹ مقفل ہو۔ ہو سکتا ہے کچھ ویجٹس آپ کی لاک اسکرین کے لیے نہ بنائے گئے ہوں اور یہاں شامل کرنا غیر محفوظ ہو سکتا ہے۔"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"سمجھ آ گئی"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ویجیٹس"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"\"ویجیٹس\" شارٹ کٹ شامل کرنے کے لیے، یقینی بنائیں کہ \"مقفل اسکرین پر ویجیٹس دکھائیں\" ترتیبات میں فعال ہے۔"</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"ترتیبات"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"صارف سوئچ کریں"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"پل ڈاؤن مینیو"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"اس سیشن میں موجود سبھی ایپس اور ڈیٹا کو حذف کر دیا جائے گا۔"</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"اطلاعات"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"گفتگوئیں"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"سبھی خاموش اطلاعات کو صاف کریں"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ڈسٹرب نہ کریں\' کے ذریعے اطلاعات کو موقوف کیا گیا"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{کوئی اطلاع نہیں ہے}=1{{mode} کی طرف سے اطلاعات کو روک دیا گیا ہے}=2{{mode} اور ایک دوسرے موڈ کے ذریعہ اطلاعات کو روک دیا گیا ہے}other{{mode} اور # دیگر طریقوں کے ذریعے اطلاعات کو روک دیا گیا ہے}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"ابھی شروع کریں"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"سر کی ٹریکنگ"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"رنگر وضع تبدیل کرنے کیلئے تھپتھپائیں"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"رنگر موڈ"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"خاموش کریں"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"غیر خاموش کریں"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"وائبریٹ"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"کی بورڈ شارٹ کٹس"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"کی بورڈ شارٹ کٹس کو حسب ضرورت بنائیں"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"شارٹ کٹ ہٹائیں؟"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ڈیفالٹ پر واپس ری سیٹ کریں؟"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"شارٹ کٹ تفویض کرنے کے لیے کلید کو دبائیں"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"یہ آپ کا حسب ضرورت شارٹ کٹ مستقل طور پر حذف کر دے گا۔"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"یہ آپ کے تمام حسب ضرورت شارٹ کٹس کو مستقل طور پر حذف کر دے گا۔"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"تلاش کے شارٹ کٹس"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"تلاش کا کوئی نتیجہ نہیں ہے"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"آئیکن سکیڑیں"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"کی بورڈ کی ترتیبات"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"شارٹ کٹ سیٹ کریں"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"ہٹائیں"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"ہاں، ری سیٹ کریں"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"منسوخ کریں"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"کلید کو دبائیں"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"کلیدی مجموعہ پہلے سے استعمال میں ہے۔ دوسری کلید آزمائیں۔"</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"اپنے کی بورڈ پر ایکشن کلید دبائیں"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"بہت خوب!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"آپ نے سبھی ایپس دیکھیں کا اشارہ مکمل کر لیا ہے"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"کی بورڈ بیک لائٹ"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d میں سے %1$d کا لیول"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"ہوم کنٹرولز"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 9dab9e1..9057926 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Ilovani vidjet orqali ochish uchun shaxsingizni tasdiqlashingiz kerak. Shuningdek, planshet qulflanganda ham bu axborotlar hammaga koʻrinishini unutmang. Ayrim vidjetlar ekran qulfiga moslanmagan va ularni bu yerda chiqarish xavfli boʻlishi mumkin."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"Vidjetlar"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"“Vidjetlar” yorligʻini qoʻshish uchun sozlamalarda “Vidjetlarni ekran qulfida chiqarish” yoqilganini tekshiring."</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"Sozlamalar"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Foydalanuvchini almashtirish"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"tortib tushiriladigan menyu"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Bildirishnomalar"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Suhbatlar"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Barcha sokin bildirishnomalarni tozalash"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bezovta qilinmasin rejimida bildirishnomalar pauza qilinadi"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Bildirishnomalar yoʻq}=1{{mode} rejimi bildirishnomalarni pauza qilgan}=2{{mode} va yana bitta boshqa rejim bildirishnomalarni pauza qilgan}other{{mode} va # ta boshqa rejim bildirishnomalarni pauza qilgan}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Boshlash"</string>
@@ -707,6 +707,7 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Boshni kuzatish"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Jiringlagich rejimini oʻzgartirish uchun bosing"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"jiringlagich rejimi"</string>
+ <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>, jiringlagich rejimini oʻzgartirish uchun bosing"</string>
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ovozsiz qilish"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ovozni yoqish"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"tebranish"</string>
@@ -1426,20 +1427,17 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tezkor tugmalar"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tezkor tugmalarni moslash"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Tezkor tugma olib tashlansinmi?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Asliga qaytarilsinmi?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Tezkor tugma sozlash uchun tugmani bosing"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Bunda maxsus tezkor tugma butunlay oʻchirib tashlanadi."</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Bunda barcha maxsus yorliqlaringiz butunlay oʻchirib tashlanadi."</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tezkor tugmalar qidiruvi"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hech narsa topilmadi"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Yigʻish belgisi"</string>
<string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Amal bajarish uchun Meta tugmasi belgisi"</string>
<string name="shortcut_helper_content_description_plus_icon" msgid="6152683734278299020">"Plus belgisi"</string>
<string name="shortcut_helper_customize_button_text" msgid="3124983502748069338">"Moslash"</string>
- <!-- no translation found for shortcut_helper_reset_button_text (2548243844050633472) -->
- <skip />
+ <string name="shortcut_helper_reset_button_text" msgid="2548243844050633472">"Tiklash"</string>
<string name="shortcut_helper_done_button_text" msgid="7249905942125386191">"Tayyor"</string>
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Yoyish belgisi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"yoki"</string>
@@ -1449,8 +1447,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Klaviatura sozlamalari"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"Tezkor tugma sozlash"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"Olib tashlash"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"Ha, asliga qaytarilsin"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"Bekor qilish"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"Tugmani bosing"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Bu tugmalar birikmasi band. Boshqasini ishlating."</string>
@@ -1482,6 +1479,7 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Klaviaturadagi amal tugmasini bosing"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Barakalla!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Hamma ilovalarni koʻrish ishorasini tugalladingiz"</string>
+ <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Qoʻllanma animatsiyasi, pauza qilish va ijroni davom ettirish uchun bosing."</string>
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatura orqa yoritkichi"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Daraja: %1$d / %2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Uy boshqaruvi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index c709a31..6c7c5f6 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Thông báo"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Cuộc trò chuyện"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Xóa tất cả thông báo im lặng"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Chế độ Không làm phiền đã tạm dừng thông báo"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Không có thông báo}=1{{mode} đã tạm dừng thông báo}=2{{mode} và một chế độ khác đã tạm dừng thông báo}other{{mode} và # chế độ khác đã tạm dừng thông báo}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Bắt đầu ngay"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Theo dõi chuyển động của đầu"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Nhấn để thay đổi chế độ chuông"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"chế độ chuông"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"tắt tiếng"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"bật tiếng"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"rung"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Nhấn phím hành động trên bàn phím"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Rất tốt!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Bạn đã hoàn tất cử chỉ xem tất cả các ứng dụng"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Đèn nền bàn phím"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Độ sáng %1$d/%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Điều khiển nhà"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index a106507..d37fe90 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -529,10 +529,8 @@
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"若要使用微件打开应用,您需要验证是您本人在操作。另外请注意,任何人都可以查看此类微件,即使您的平板电脑已锁定。有些微件可能不适合显示在锁定的屏幕中,因此添加到这里可能不安全。"</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"知道了"</string>
<string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"微件"</string>
- <!-- no translation found for glanceable_hub_lockscreen_affordance_disabled_text (599170482297578735) -->
- <skip />
- <!-- no translation found for glanceable_hub_lockscreen_affordance_action_button_label (7636151133344609375) -->
- <skip />
+ <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"如要添加“微件”快捷方式,请确保已在设置中启用“在锁屏状态下显示微件”。"</string>
+ <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"设置"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切换用户"</string>
<string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉菜单"</string>
<string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"此会话中的所有应用和数据都将被删除。"</string>
@@ -593,6 +591,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"对话"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有静音通知"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"勿扰模式暂停的通知"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{无通知}=1{{mode}暂停了通知}=2{{mode}和另外 1 种模式暂停了通知}other{{mode}和另外 # 种模式暂停了通知}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"立即开始"</string>
@@ -707,6 +707,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"头部跟踪"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"点按即可更改振铃器模式"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"响铃模式"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"静音"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消静音"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"振动"</string>
@@ -1426,12 +1428,10 @@
<string name="shortcut_helper_title" msgid="8567500639300970049">"键盘快捷键"</string>
<string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自定义键盘快捷键"</string>
<string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"要移除快捷键吗?"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_dialog_title (8131184731313717780) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"要重置为默认快捷方式吗?"</string>
<string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"按下按键即可指定快捷键"</string>
<string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"此操作会永久删除您的自定义快捷键。"</string>
- <!-- no translation found for shortcut_customize_mode_reset_shortcut_description (2081849715634358684) -->
- <skip />
+ <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"此操作会永久删除您的所有自定义快捷方式。"</string>
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜索快捷键"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"无搜索结果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收起图标"</string>
@@ -1449,8 +1449,7 @@
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"键盘设置"</string>
<string name="shortcut_helper_customize_dialog_set_shortcut_button_label" msgid="4754492225010429382">"设置快捷键"</string>
<string name="shortcut_helper_customize_dialog_remove_button_label" msgid="6546386970440176552">"移除"</string>
- <!-- no translation found for shortcut_helper_customize_dialog_reset_button_label (7645535254306312685) -->
- <skip />
+ <string name="shortcut_helper_customize_dialog_reset_button_label" msgid="7645535254306312685">"是,重置"</string>
<string name="shortcut_helper_customize_dialog_cancel_button_label" msgid="5595546460431741178">"取消"</string>
<string name="shortcut_helper_add_shortcut_dialog_placeholder" msgid="9154297849458741995">"按下按键"</string>
<string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"按键组合已被使用,请尝试使用其他按键。"</string>
@@ -1482,6 +1481,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"按键盘上的快捷操作按键"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"非常棒!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"您已完成“查看所有应用”手势教程"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"键盘背光"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 级,共 %2$d 级"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"家居控制"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index afbd411..9b16360 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"對話"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有靜音通知"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"「請勿騷擾」模式已將通知暫停"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{沒有通知}=1{{mode}已暫停通知}=2{{mode}和另外一個模式已暫停通知}other{{mode}和另外 # 個模式已暫停通知}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"頭部追蹤"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"輕按即可變更響鈴模式"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"響鈴模式"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"靜音"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消靜音"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"震動"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"按下鍵盤上的快捷操作鍵"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"做得好!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"你已完成「查看所有應用程式」手勢的教學課程"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"智能家居"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 03d70e1..49111ea 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"對話"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有靜音通知"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"「零打擾」模式已將通知設為暫停"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{沒有通知}=1{「{mode}」模式已將通知設為暫停}=2{「{mode}」和另一個模式已將通知設為暫停}other{「{mode}」和另外 # 個模式已將通知設為暫停}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"頭部追蹤"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"輕觸即可變更鈴聲模式"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"鈴聲模式"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"靜音"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消靜音"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"震動"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"按下鍵盤上的快捷操作鍵"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"非常好!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"你已完成「查看所有應用程式」手勢教學課程"</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"居家控制"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index b39c3e9..9d4f70c 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -593,6 +593,8 @@
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Izaziso"</string>
<string name="notification_section_header_conversations" msgid="821834744538345661">"Izingxoxo"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Sula zonke izaziso ezithulile"</string>
+ <!-- no translation found for accessibility_notification_section_header_open_settings (6235202417954844004) -->
+ <skip />
<string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Izaziso zimiswe okwesikhashana ukungaphazamisi"</string>
<string name="modes_suppressing_shade_text" msgid="6037581130837903239">"{count,plural,offset:1 =0{Azikho izaziso}=1{Izaziso zimiswe okwesikhashana yi-{mode}}=2{Izaziso zimiswe okwesikhashana yi-{mode} nelinye imodi elilodwa}one{Izaziso zimiswe okwesikhashana yi-{mode} kanye namanye amamodi angu-#}other{Izaziso zimiswe okwesikhashana yi-{mode} kanye namanye amamodi angu-#}}"</string>
<string name="media_projection_action_text" msgid="3634906766918186440">"Qala manje"</string>
@@ -707,6 +709,8 @@
<string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Ukulandelela Ikhanda"</string>
<string name="volume_ringer_change" msgid="3574969197796055532">"Thepha ukuze ushintshe imodi yokukhala"</string>
<string name="volume_ringer_mode" msgid="6867838048430807128">"imodi yokukhala"</string>
+ <!-- no translation found for volume_ringer_drawer_closed_content_description (4737792429808781745) -->
+ <skip />
<string name="volume_ringer_hint_mute" msgid="4263821214125126614">"thulisa"</string>
<string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"susa ukuthula"</string>
<string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"dlidliza"</string>
@@ -1482,6 +1486,8 @@
<string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Cindezela inkinobho yokufinyelela kukhibhodi yakho"</string>
<string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Wenze kahle!"</string>
<string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Uqedele ukunyakazisa kokubuka onke ama-app."</string>
+ <!-- no translation found for tutorial_animation_content_description (2698816574982370184) -->
+ <skip />
<string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Ilambu lekhibhodi"</string>
<string name="keyboard_backlight_value" msgid="7336398765584393538">"Ileveli %1$d ka-%2$d"</string>
<string name="home_controls_dream_label" msgid="6567105701292324257">"Izilawuli Zasekhaya"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index a375264..28df2e2 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -124,7 +124,7 @@
<!-- Keyboard shortcuts colors -->
<color name="ksh_application_group_color">#fff44336</color>
<color name="ksh_key_item_color">@*android:color/system_on_surface_variant_light</color>
- <color name="ksh_key_item_background">?androidprv:attr/materialColorSurfaceContainerHighest</color>
+ <color name="ksh_key_item_background">@androidprv:color/materialColorSurfaceContainerHighest</color>
<color name="instant_apps_color">#ff4d5a64</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index df7adc0..5894f29 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1224,6 +1224,9 @@
<dimen name="min_window_blur_radius">1px</dimen>
<dimen name="max_window_blur_radius">23px</dimen>
+ <!-- Blur radius behind Notification Shade -->
+ <dimen name="max_shade_window_blur_radius">60dp</dimen>
+
<!-- How much into a DisplayCutout's bounds we can go, on each side -->
<dimen name="display_cutout_margin_consumption">0px</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 658f2c2..05c13f2 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1342,6 +1342,8 @@
<string name="glanceable_hub_lockscreen_affordance_disabled_text">To add the \"Widgets\" shortcut, make sure \"Show widgets on lock screen\" is enabled in settings.</string>
<!-- Label for a button used to open Settings in order to enable showing widgets on the lock screen. [CHAR LIMIT=NONE] -->
<string name="glanceable_hub_lockscreen_affordance_action_button_label">Settings</string>
+ <!-- Content description for a "show screensaver" button on glanceable hub. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_glanceable_hub_to_dream_button">Show screensaver button</string>
<!-- Related to user switcher --><skip/>
@@ -2280,11 +2282,11 @@
<!-- User visible title for the multitasking keyboard shortcuts list. [CHAR LIMIT=70] -->
<string name="keyboard_shortcut_group_system_multitasking">Multitasking</string>
<!-- User visible title for the keyboard shortcut that enters split screen with current app on the right [CHAR LIMIT=70] -->
- <string name="system_multitasking_rhs">Use split screen with current app on the right</string>
+ <string name="system_multitasking_rhs">Use split screen with app on the right</string>
<!-- User visible title for the keyboard shortcut that enters split screen with current app on the left [CHAR LIMIT=70] -->
- <string name="system_multitasking_lhs">Use split screen with current app on the left</string>
+ <string name="system_multitasking_lhs">Use split screen with app on the left</string>
<!-- User visible title for the keyboard shortcut that switches from split screen to full screen [CHAR LIMIT=70] -->
- <string name="system_multitasking_full_screen">Switch from split screen to full screen</string>
+ <string name="system_multitasking_full_screen">Switch to full screen</string>
<!-- User visible title for the keyboard shortcut that switches to app on right or below while using split screen [CHAR LIMIT=70] -->
<string name="system_multitasking_splitscreen_focus_rhs">Switch to app on right or below while using split screen</string>
<!-- User visible title for the keyboard shortcut that switches to app on left or above while using split screen [CHAR LIMIT=70] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 9aa7137..b47aa2c 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -151,7 +151,7 @@
<style name="TextAppearance.QS.UserSwitcher">
<item name="android:textSize">@dimen/qs_tile_text_size</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
</style>
<!-- This is hard coded to be sans-serif-condensed to match the icons -->
@@ -208,42 +208,42 @@
<item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
<item name="android:gravity">@integer/biometric_dialog_text_gravity</item>
<item name="android:maxLines">1</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
<item name="android:ellipsize">end</item>
</style>
<style name="TextAppearance.AuthCredential.Title" parent="TextAppearance.Material3.HeadlineSmall" >
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthCredential.Subtitle" parent="TextAppearance.Material3.BodyMedium" >
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthCredential.Description" parent="TextAppearance.Material3.BodyMedium" >
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthCredential.VerticalListContentViewDescription" parent="TextAppearance.Material3.TitleSmall">
<item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthCredential.ContentViewWithButtonDescription" parent="TextAppearance.AuthCredential.Description" />
<style name="TextAppearance.AuthCredential.ContentViewListItem" parent="TextAppearance.Material3.BodySmall">
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
<item name="android:paddingTop">@dimen/biometric_prompt_content_list_item_padding_top</item>
<item name="android:breakStrategy">high_quality</item>
</style>
<style name="TextAppearance.AuthCredential.Indicator" parent="TextAppearance.Material3.BodyMedium">
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:marqueeRepeatLimit">marquee_forever</item>
<item name="android:singleLine">true</item>
<item name="android:ellipsize">marquee</item>
@@ -269,21 +269,21 @@
<item name="android:layout_marginTop">24dp</item>
<item name="android:textSize">36dp</item>
<item name="android:focusable">true</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Subtitle">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:layout_marginTop">20dp</item>
<item name="android:textSize">18sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Description">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:layout_marginTop">20dp</item>
<item name="android:textSize">18sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.AuthNonBioCredential.Error">
@@ -352,7 +352,7 @@
</style>
<style name="AuthNonCredentialPanelStyle">
- <item name="android:background">?androidprv:attr/materialColorSurfaceBright</item>
+ <item name="android:background">@androidprv:color/materialColorSurfaceBright</item>
</style>
<style name="AuthCredentialPanelStyle" parent="AuthNonCredentialPanelStyle">
@@ -383,13 +383,13 @@
<item name="android:minWidth">48dp</item>
<item name="android:paddingLeft">0dp</item>
<item name="android:paddingRight">12dp</item>
- <item name="android:textColor">?androidprv:attr/materialColorPrimary</item>
+ <item name="android:textColor">@androidprv:color/materialColorPrimary</item>
</style>
<style name="AuthCredentialNegativeButtonStyle" parent="TextAppearance.Material3.LabelLarge">
<item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
<item name="android:background">@color/transparent</item>
- <item name="android:textColor">?androidprv:attr/materialColorPrimary</item>
+ <item name="android:textColor">@androidprv:color/materialColorPrimary</item>
</style>
<style name="DeviceManagementDialogTitle">
@@ -411,7 +411,7 @@
</style>
<style name="KeyboardShortcutHelper.BottomSheet.DragHandle" parent="Widget.Material3.BottomSheet.DragHandle">
- <item name="tint">?androidprv:attr/materialColorOutlineVariant</item>
+ <item name="tint">@androidprv:color/materialColorOutlineVariant</item>
</style>
<style name="KeyboardShortcutHelper.BottomSheetDialogAnimation">
@@ -510,23 +510,23 @@
<item name="android:windowIsFloating">true</item>
<item name="android:homeAsUpIndicator">@drawable/ic_arrow_back</item>
- <item name="surfaceBright">?androidprv:attr/materialColorSurfaceBright</item>
+ <item name="surfaceBright">@androidprv:color/materialColorSurfaceBright</item>
<item name="android:colorBackground">?attr/surfaceBright</item>
- <item name="scHigh">?androidprv:attr/materialColorSurfaceContainerHigh</item>
- <item name="primary">?androidprv:attr/materialColorPrimary</item>
- <item name="tertiary">?androidprv:attr/materialColorTertiary</item>
- <item name="onSurface">?androidprv:attr/materialColorOnSurface</item>
- <item name="onSurfaceVariant">?androidprv:attr/materialColorOnSurfaceVariant</item>
- <item name="outline">?androidprv:attr/materialColorOutline</item>
+ <item name="scHigh">@androidprv:color/materialColorSurfaceContainerHigh</item>
+ <item name="primary">@androidprv:color/materialColorPrimary</item>
+ <item name="tertiary">@androidprv:color/materialColorTertiary</item>
+ <item name="onSurface">@androidprv:color/materialColorOnSurface</item>
+ <item name="onSurfaceVariant">@androidprv:color/materialColorOnSurfaceVariant</item>
+ <item name="outline">@androidprv:color/materialColorOutline</item>
- <item name="shadeActive">?androidprv:attr/customColorShadeActive</item>
- <item name="onShadeActive">?androidprv:attr/customColorOnShadeActive</item>
- <item name="onShadeActiveVariant">?androidprv:attr/customColorOnShadeActiveVariant</item>
- <item name="shadeInactive">?androidprv:attr/customColorShadeInactive</item>
- <item name="onShadeInactive">?androidprv:attr/customColorOnShadeInactive</item>
- <item name="onShadeInactiveVariant">?androidprv:attr/customColorOnShadeInactiveVariant</item>
- <item name="shadeDisabled">?androidprv:attr/customColorShadeDisabled</item>
- <item name="underSurface">?androidprv:attr/customColorUnderSurface</item>
+ <item name="shadeActive">@androidprv:color/customColorShadeActive</item>
+ <item name="onShadeActive">@androidprv:color/customColorOnShadeActive</item>
+ <item name="onShadeActiveVariant">@androidprv:color/customColorOnShadeActiveVariant</item>
+ <item name="shadeInactive">@androidprv:color/customColorShadeInactive</item>
+ <item name="onShadeInactive">@androidprv:color/customColorOnShadeInactive</item>
+ <item name="onShadeInactiveVariant">@androidprv:color/customColorOnShadeInactiveVariant</item>
+ <item name="shadeDisabled">@androidprv:color/customColorShadeDisabled</item>
+ <item name="underSurface">@androidprv:color/customColorUnderSurface</item>
<item name="android:itemTextAppearance">@style/Control.MenuItem</item>
</style>
@@ -588,7 +588,7 @@
<item name="android:buttonBarPositiveButtonStyle">@style/Widget.Dialog.Button</item>
<item name="android:buttonBarNegativeButtonStyle">@style/Widget.Dialog.Button.BorderButton</item>
<item name="android:buttonBarNeutralButtonStyle">@style/Widget.Dialog.Button.BorderButton</item>
- <item name="android:colorBackground">?androidprv:attr/materialColorSurfaceBright</item>
+ <item name="android:colorBackground">@androidprv:color/materialColorSurfaceBright</item>
<item name="android:alertDialogStyle">@style/ScrollableAlertDialogStyle</item>
<item name="android:buttonBarStyle">@style/ButtonBarStyle</item>
<item name="android:buttonBarButtonStyle">@style/Widget.Dialog.Button.Large</item>
@@ -744,34 +744,34 @@
<style name="TextAppearance.NotificationImportanceChannel">
<item name="android:textSize">@dimen/notification_importance_channel_text</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:textSize">@dimen/notification_importance_channel_text</item>
</style>
<style name="TextAppearance.NotificationImportanceChannelGroup">
<item name="android:textSize">@dimen/notification_importance_channel_group_text</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:textSize">@dimen/notification_importance_channel_group_text</item>
</style>
<style name="TextAppearance.NotificationImportanceApp">
<item name="android:textSize">@dimen/notification_importance_channel_group_text</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
<item name="android:textSize">@dimen/notification_importance_channel_group_text</item>
</style>
<style name="TextAppearance.NotificationImportanceHeader">
<item name="android:textSize">@dimen/notification_importance_header_text</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.NotificationImportanceDetail">
<item name="android:textSize">@dimen/notification_importance_description_text</item>
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
<item name="android:gravity">center</item>
</style>
@@ -785,7 +785,7 @@
<style
name="TextAppearance.NotificationSectionHeaderLabel"
parent="@android:style/Widget.DeviceDefault.Button.Borderless">
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">14sp</item>
<item name="android:minWidth">0dp</item>
@@ -794,7 +794,7 @@
<style
name="TextAppearance.NotificationSectionHeaderButton"
parent="@android:style/Widget.DeviceDefault.Button.Borderless">
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">14sp</item>
<item name="android:minWidth">0dp</item>
@@ -803,7 +803,7 @@
<style
name="TextAppearance.NotificationFooterButton"
parent="@android:style/Widget.DeviceDefault.Button.Borderless">
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">14sp</item>
<item name="android:minWidth">0dp</item>
@@ -812,8 +812,8 @@
<style
name="TextAppearance.NotificationFooterButtonRedesign"
parent="@android:style/Widget.DeviceDefault.Button.Borderless">
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
- <item name="android:drawableTint">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
+ <item name="android:drawableTint">@androidprv:color/materialColorOnSurface</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">16sp</item>
<item name="android:minWidth">0dp</item>
@@ -1009,12 +1009,12 @@
</style>
<style name="LongScreenshotActivity" parent="@android:style/Theme.DeviceDefault.DayNight">
- <item name="android:colorBackground">?androidprv:attr/materialColorSurfaceContainer</item>
+ <item name="android:colorBackground">@androidprv:color/materialColorSurfaceContainer</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowLightStatusBar">true</item>
<item name="android:windowLightNavigationBar">true</item>
- <item name="android:statusBarColor">?androidprv:attr/materialColorSurfaceContainer</item>
- <item name="android:navigationBarColor">?androidprv:attr/materialColorSurfaceContainerHighest</item>
+ <item name="android:statusBarColor">@androidprv:color/materialColorSurfaceContainer</item>
+ <item name="android:navigationBarColor">@androidprv:color/materialColorSurfaceContainerHighest</item>
<item name="android:windowActivityTransitions">true</item>
</style>
@@ -1092,7 +1092,7 @@
<style name="Theme.VolumePanel.Popup" parent="@style/Theme.SystemUI.Dialog">
<item name="android:dialogCornerRadius">44dp</item>
- <item name="android:colorBackground">?androidprv:attr/materialColorSurfaceContainerHigh
+ <item name="android:colorBackground">@androidprv:color/materialColorSurfaceContainerHigh
</item>
</style>
@@ -1303,7 +1303,7 @@
</style>
<style name="TextAppearance.Dialog.Title" parent="@android:style/TextAppearance.DeviceDefault.Large">
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:textSize">@dimen/dialog_title_text_size</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:lineHeight">32sp</item>
@@ -1313,7 +1313,7 @@
</style>
<style name="TextAppearance.Dialog.Body" parent="@android:style/TextAppearance.DeviceDefault.Medium">
- <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
<item name="android:textSize">14sp</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:lineHeight">20sp</item>
@@ -1408,7 +1408,7 @@
<style name="InternetDialog.NetworkTitle.Active">
<item name="android:textAppearance">@style/TextAppearance.InternetDialog.Active</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnPrimaryContainer</item>
</style>
<style name="InternetDialog.NetworkSummary">
@@ -1421,27 +1421,27 @@
<style name="InternetDialog.NetworkSummary.Active">
<item name="android:textAppearance">@style/TextAppearance.InternetDialog.Secondary.Active
</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnPrimaryContainer</item>
</style>
<style name="TextAppearance.InternetDialog">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:textSize">16sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:textDirection">locale</item>
</style>
<style name="TextAppearance.InternetDialog.Secondary">
<item name="android:textSize">14sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
</style>
<style name="TextAppearance.InternetDialog.Active">
- <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnPrimaryContainer</item>
</style>
<style name="TextAppearance.InternetDialog.Secondary.Active">
- <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnPrimaryContainer</item>
</style>
<style name="FgsManagerDialogTitle">
@@ -1478,18 +1478,18 @@
<item name="android:orientation">horizontal</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<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>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.BluetoothTileDialog.Active">
- <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnPrimaryContainer</item>
</style>
<style name="BluetoothTileDialog.AudioSharingButton" parent="Widget.Dialog.Button">
@@ -1686,7 +1686,7 @@
<style name="ShortCutButton" parent="@android:style/Widget.Material.Button">
<item name="android:background">@drawable/shortcut_button_colored</item>
<item name="android:textSize">16sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
<item name="android:layout_marginEnd">12dp</item>
<item name="android:paddingLeft">24dp</item>
<item name="android:paddingRight">24dp</item>
@@ -1712,18 +1712,18 @@
parent="@android:style/TextAppearance.DeviceDefault.Medium">
<item name="android:textSize">14sp</item>
<item name="android:lineHeight">20sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="TextAppearance.PrivacyDialog.Item.Summary"
parent="@android:style/TextAppearance.DeviceDefault.Small">
<item name="android:textSize">14sp</item>
<item name="android:lineHeight">20sp</item>
- <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurfaceVariant</item>
</style>
<style name="Theme.PrivacyDialog" parent="@style/Theme.SystemUI.Dialog">
- <item name="android:colorBackground">?androidprv:attr/materialColorSurfaceContainer</item>
+ <item name="android:colorBackground">@androidprv:color/materialColorSurfaceContainer</item>
</style>
<style name="Theme.SystemUI.Dialog.StickyKeys" parent="@style/Theme.SystemUI.Dialog">
diff --git a/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt b/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
index 495367b..842efa3 100644
--- a/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
+++ b/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
@@ -25,7 +25,6 @@
import android.util.AttributeSet
import android.view.View
import com.android.app.animation.Interpolators
-import com.android.settingslib.Utils
import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.TITLE
/** Displays security messages for the keyguard bouncer. */
@@ -71,12 +70,12 @@
}
override fun onThemeChanged() {
- mDefaultColorState = getColorInStyle() ?: Utils.getColorAttr(context, TITLE)
+ mDefaultColorState = getColorInStyle() ?: ColorStateList.valueOf(context.getColor(TITLE))
super.onThemeChanged()
}
override fun reloadColor() {
- mDefaultColorState = getColorInStyle() ?: Utils.getColorAttr(context, TITLE)
+ mDefaultColorState = getColorInStyle() ?: ColorStateList.valueOf(context.getColor(TITLE))
super.reloadColor()
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index fcaccd2..36afe1e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -346,8 +346,8 @@
setPadding(getPaddingLeft(), getPaddingTop() + getResources().getDimensionPixelSize(
R.dimen.keyguard_security_container_padding_top), getPaddingRight(),
getPaddingBottom());
- setBackgroundColor(Utils.getColorAttrDefaultColor(getContext(),
- com.android.internal.R.attr.materialColorSurfaceDim));
+ setBackgroundColor(
+ getContext().getColor(com.android.internal.R.color.materialColorSurfaceDim));
}
void onResume(SecurityMode securityMode, boolean faceAuthEnabled) {
@@ -814,8 +814,8 @@
void reloadColors() {
mViewMode.reloadColors();
- setBackgroundColor(Utils.getColorAttrDefaultColor(getContext(),
- com.android.internal.R.attr.materialColorSurfaceDim));
+ setBackgroundColor(getContext().getColor(
+ com.android.internal.R.color.materialColorSurfaceDim));
}
/** Handles density or font scale changes. */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
index 392abf2..0942353 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
@@ -20,7 +20,6 @@
import android.util.AttributeSet
import android.widget.ImageView
import androidx.core.graphics.drawable.DrawableCompat
-import com.android.settingslib.Utils
import com.android.systemui.res.R
import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.EMERGENCY_BUTTON
@@ -45,7 +44,7 @@
override fun reloadColors() {
super.reloadColors()
- val imageColor = Utils.getColorAttrDefaultColor(context, EMERGENCY_BUTTON)
+ val imageColor = context.getColor(EMERGENCY_BUTTON)
simImageView?.let {
val wrappedDrawable = DrawableCompat.wrap(it.drawable)
DrawableCompat.setTint(wrappedDrawable, imageColor)
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
index e773416..aed1c10 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
@@ -15,21 +15,17 @@
*/
package com.android.keyguard;
-import static com.android.settingslib.Utils.getColorAttrDefaultColor;
import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BACKGROUND;
import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BACKGROUND_PRESSED;
import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BUTTON;
import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_KEY;
import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_PRESSED;
-import static com.android.systemui.util.ColorUtilKt.getPrivateAttrColorIfUnset;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
-import android.annotation.SuppressLint;
import android.content.Context;
-import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.view.ContextThemeWrapper;
@@ -126,18 +122,15 @@
int[] customAttrs = {android.R.attr.colorControlNormal};
ContextThemeWrapper ctw = new ContextThemeWrapper(context, mStyle);
- @SuppressLint("ResourceType") TypedArray a = ctw.obtainStyledAttributes(customAttrs);
- mNormalBackgroundColor = getPrivateAttrColorIfUnset(ctw, a, 0, 0,
- NUM_PAD_BACKGROUND);
- a.recycle();
+ mNormalBackgroundColor = ctw.getColor(NUM_PAD_BACKGROUND);
- mPressedBackgroundColor = getColorAttrDefaultColor(context, NUM_PAD_BACKGROUND_PRESSED);
- mTextColorPressed = getColorAttrDefaultColor(context, NUM_PAD_PRESSED);
+ mPressedBackgroundColor = context.getColor(NUM_PAD_BACKGROUND_PRESSED);
+ mTextColorPressed = context.getColor(NUM_PAD_PRESSED);
mBackground.setColor(mNormalBackgroundColor);
mTextColorPrimary = isNumPadKey
- ? getColorAttrDefaultColor(context, NUM_PAD_KEY)
- : getColorAttrDefaultColor(context, NUM_PAD_BUTTON);
+ ? context.getColor(NUM_PAD_KEY)
+ : context.getColor(NUM_PAD_BUTTON);
createAnimators();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index a81c1b0..d7799bf 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -30,7 +30,6 @@
import androidx.annotation.Nullable;
-import com.android.settingslib.Utils;
import com.android.systemui.res.R;
/**
@@ -101,7 +100,7 @@
if (mAnimator != null) mAnimator.reloadColors(getContext());
int textColorResId = mIsTransparentMode ? NUM_PAD_KEY : NUM_PAD_BUTTON;
- int imageColor = Utils.getColorAttrDefaultColor(getContext(), textColorResId);
+ int imageColor = getContext().getColor(textColorResId);
((VectorDrawable) getDrawable()).setTintList(ColorStateList.valueOf(imageColor));
}
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index ebde8a3..e8a702f 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -155,8 +155,7 @@
* Reload colors from resources.
**/
public void reloadColors() {
- int textColor = Utils.getColorAttr(getContext(), NUM_PAD_KEY)
- .getDefaultColor();
+ int textColor = getContext().getColor(NUM_PAD_KEY);
int klondikeColor = Utils.getColorAttr(getContext(), android.R.attr.textColorSecondary)
.getDefaultColor();
mDigitText.setTextColor(textColor);
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
index 5e9eed9..bac9dac 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
@@ -28,7 +28,6 @@
import androidx.core.graphics.drawable.DrawableCompat;
-import com.android.settingslib.Utils;
import com.android.systemui.res.R;
/**
@@ -39,8 +38,7 @@
private int mPinLength;
private int mDotDiameter;
- private int mColor = Utils.getColorAttr(getContext(), PIN_SHAPES)
- .getDefaultColor();
+ private int mColor = getContext().getColor(PIN_SHAPES);
private int mPosition = 0;
private static final int DEFAULT_PIN_LENGTH = 6;
private PinShapeAdapter mPinShapeAdapter;
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
index ee70de3..26a774e 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
@@ -39,7 +39,6 @@
import androidx.core.graphics.drawable.DrawableCompat;
import com.android.app.animation.Interpolators;
-import com.android.settingslib.Utils;
import com.android.systemui.res.R;
/**
@@ -49,7 +48,7 @@
public class PinShapeNonHintingView extends LinearLayout implements PinShapeInput {
private static final int RESET_STAGGER_DELAY = 40;
private static final int RESET_MAX_DELAY = 200;
- private int mColor = Utils.getColorAttr(getContext(), PIN_SHAPES).getDefaultColor();
+ private int mColor = getContext().getColor(PIN_SHAPES);
private int mPosition = 0;
private boolean mIsAnimatingReset = false;
private final PinShapeAdapter mPinShapeAdapter;
diff --git a/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags b/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
index 08236b7..ca5424b 100644
--- a/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
+++ b/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.systemui;
diff --git a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
index 3abcb13..11ce168 100644
--- a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
@@ -32,7 +32,6 @@
import androidx.core.graphics.ColorUtils
import com.android.app.animation.Interpolators
import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.settingslib.Utils
import com.android.systemui.biometrics.AuthController
import com.android.systemui.log.ScreenDecorationsLogger
import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -60,8 +59,8 @@
private val rimRect = RectF()
private var cameraProtectionColor = Color.BLACK
- var faceScanningAnimColor = Utils.getColorAttrDefaultColor(context,
- com.android.internal.R.attr.materialColorPrimaryFixed)
+ var faceScanningAnimColor =
+ context.getColor(com.android.internal.R.color.materialColorPrimaryFixed)
private var cameraProtectionAnimator: ValueAnimator? = null
var hideOverlayRunnable: Runnable? = null
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 ad12229..56435df 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
@@ -52,7 +52,6 @@
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-import com.android.settingslib.Utils;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -472,8 +471,8 @@
view.setContentDescription(item.getToolName());
icon.setImageDrawable(item.getToolIcon());
if (item.isCustomIcon()) {
- icon.getDrawable().mutate().setTint(Utils.getColorAttr(context,
- com.android.internal.R.attr.materialColorOnPrimaryContainer).getDefaultColor());
+ icon.getDrawable().mutate().setTint(context.getColor(
+ com.android.internal.R.color.materialColorOnPrimaryContainer));
}
text.setText(item.getToolName());
Intent intent = item.getToolIntent();
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 e47e4b2..7e1d538 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java
@@ -27,7 +27,6 @@
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
-import com.android.settingslib.Utils;
import com.android.systemui.bluetooth.qsdialog.DeviceItem;
import com.android.systemui.res.R;
@@ -131,10 +130,9 @@
}
// tint different color in different state for bad color contrast problem
- int tintColor = item.isActive() ? Utils.getColorAttr(mContext,
- com.android.internal.R.attr.materialColorOnPrimaryContainer).getDefaultColor()
- : Utils.getColorAttr(mContext,
- com.android.internal.R.attr.materialColorOnSurface).getDefaultColor();
+ int tintColor = item.isActive() ? mContext.getColor(
+ com.android.internal.R.color.materialColorOnPrimaryContainer)
+ : mContext.getColor(com.android.internal.R.color.materialColorOnSurface);
Pair<Drawable, String> iconPair = item.getIconWithDescription();
if (iconPair != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesSpinnerAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesSpinnerAdapter.java
index 28d742c..fda4f03 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesSpinnerAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesSpinnerAdapter.java
@@ -64,9 +64,9 @@
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();
+ int tintColor = mContext.getColor(
+ isSelected ? com.android.internal.R.color.materialColorOnPrimaryContainer
+ : com.android.internal.R.color.materialColorOnSurface);
text.setTextColor(tintColor);
}
return view;
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/statusbar/ui/AmbientStatusBarView.java b/packages/SystemUI/src/com/android/systemui/ambient/statusbar/ui/AmbientStatusBarView.java
index d4e74d3..9e1b09c 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/statusbar/ui/AmbientStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/ambient/statusbar/ui/AmbientStatusBarView.java
@@ -162,11 +162,12 @@
void showIcon(@StatusIconType int iconType, boolean show, @Nullable String contentDescription) {
View icon = mStatusIcons.get(iconType);
- if (icon == null) {
- return;
- }
+ if (icon == null) return;
+
if (show && contentDescription != null) {
icon.setContentDescription(contentDescription);
+ icon.setFocusable(true);
+ icon.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
}
icon.setVisibility(show ? View.VISIBLE : View.GONE);
mSystemStatusViewGroup.setVisibility(areAnyStatusIconsVisible() ? View.VISIBLE : View.GONE);
@@ -174,9 +175,12 @@
void setExtraStatusBarItemViews(List<View> views) {
removeAllExtraStatusBarItemViews();
- views.forEach(view -> mExtraSystemStatusViewGroup.addView(view));
+ views.forEach(view -> {
+ view.setFocusable(true);
+ view.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+ mExtraSystemStatusViewGroup.addView(view);
+ });
}
-
private View fetchStatusIconForResId(int resId) {
final View statusIcon = findViewById(resId);
return Objects.requireNonNull(statusIcon);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt
index 0ad83ec..38b1d7d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt
@@ -37,7 +37,6 @@
import android.widget.LinearLayout
import android.widget.Space
import android.widget.TextView
-import com.android.settingslib.Utils
import com.android.systemui.biometrics.Utils.ellipsize
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
@@ -294,7 +293,7 @@
resources.getDimensionPixelSize(R.dimen.biometric_prompt_content_list_item_bullet_gap_width)
private fun getListItemBulletColor(context: Context): Int =
- Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.materialColorOnSurface)
+ context.getColor(com.android.internal.R.color.materialColorOnSurface)
private fun <T : View> T.width(function: (Int) -> Unit) {
if (width == 0)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt
index c2a4ee3..5557161 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt
@@ -164,21 +164,12 @@
showIndicatorForDeviceEntry: Boolean ->
val callbacks = mutableListOf<LottieCallback>()
if (showIndicatorForDeviceEntry) {
- val indicatorColor =
- com.android.settingslib.Utils.getColorAttrDefaultColor(
- applicationContext,
- com.android.internal.R.attr.materialColorPrimaryFixed
- )
- val outerRimColor =
- com.android.settingslib.Utils.getColorAttrDefaultColor(
- applicationContext,
- com.android.internal.R.attr.materialColorPrimaryFixedDim
- )
- val chevronFill =
- com.android.settingslib.Utils.getColorAttrDefaultColor(
- applicationContext,
- com.android.internal.R.attr.materialColorOnPrimaryFixed
- )
+ val indicatorColor = applicationContext.getColor(
+ com.android.internal.R.color.materialColorPrimaryFixed)
+ val outerRimColor = applicationContext.getColor(
+ com.android.internal.R.color.materialColorPrimaryFixedDim)
+ val chevronFill = applicationContext.getColor(
+ com.android.internal.R.color.materialColorOnPrimaryFixed)
callbacks.add(LottieCallback(KeyPath(".blue600", "**"), indicatorColor))
callbacks.add(LottieCallback(KeyPath(".blue400", "**"), outerRimColor))
callbacks.add(LottieCallback(KeyPath(".black", "**"), chevronFill))
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 d7a0fc9..9cfb5be 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt
@@ -405,13 +405,10 @@
}
// updating icon colors
- val tintColor =
- com.android.settingslib.Utils.getColorAttr(
- context,
- if (item.isActive) InternalR.attr.materialColorOnPrimaryContainer
- else InternalR.attr.materialColorOnSurface,
- )
- .defaultColor
+ val tintColor = context.getColor(
+ if (item.isActive) InternalR.color.materialColorOnPrimaryContainer
+ else InternalR.color.materialColorOnSurface
+ )
// update icons
iconView.apply {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/shared/constants/KeyguardBouncerConstants.kt b/packages/SystemUI/src/com/android/systemui/bouncer/shared/constants/KeyguardBouncerConstants.kt
index 9f17811..a286d16 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/shared/constants/KeyguardBouncerConstants.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/shared/constants/KeyguardBouncerConstants.kt
@@ -33,13 +33,15 @@
const val DEFAULT_PIN_LENGTH = 6
object ColorId {
- const val TITLE = com.android.internal.R.attr.materialColorOnSurface
- const val PIN_SHAPES = com.android.internal.R.attr.materialColorOnSurfaceVariant
- const val NUM_PAD_BACKGROUND = com.android.internal.R.attr.materialColorSurfaceContainerHigh
- const val NUM_PAD_BACKGROUND_PRESSED = com.android.internal.R.attr.materialColorPrimaryFixed
- const val NUM_PAD_PRESSED = com.android.internal.R.attr.materialColorOnPrimaryFixed
- const val NUM_PAD_KEY = com.android.internal.R.attr.materialColorOnSurface
- const val NUM_PAD_BUTTON = com.android.internal.R.attr.materialColorOnSecondaryFixed
- const val EMERGENCY_BUTTON = com.android.internal.R.attr.materialColorTertiaryFixed
+ const val TITLE = com.android.internal.R.color.materialColorOnSurface
+ const val PIN_SHAPES = com.android.internal.R.color.materialColorOnSurfaceVariant
+ const val NUM_PAD_BACKGROUND =
+ com.android.internal.R.color.materialColorSurfaceContainerHigh
+ const val NUM_PAD_BACKGROUND_PRESSED =
+ com.android.internal.R.color.materialColorPrimaryFixed
+ const val NUM_PAD_PRESSED = com.android.internal.R.color.materialColorOnPrimaryFixed
+ const val NUM_PAD_KEY = com.android.internal.R.color.materialColorOnSurface
+ const val NUM_PAD_BUTTON = com.android.internal.R.color.materialColorOnSecondaryFixed
+ const val EMERGENCY_BUTTON = com.android.internal.R.color.materialColorTertiaryFixed
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
index b2d02ed..a31e61f 100644
--- a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
@@ -107,6 +107,7 @@
activityOptions.setDisallowEnterPictureInPictureWhileLaunching(true)
activityOptions.rotationAnimationHint =
WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS
+ intent.collectExtraIntentKeys()
try {
activityTaskManager.startActivityAsUser(
null,
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt b/packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt
index 074b64e..69f4f6d 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt
@@ -74,3 +74,12 @@
/** Returns `true` if the tap gesture should be rejected */
fun isFalseTap(@Penalty penalty: Int): Boolean = manager.isFalseTap(penalty)
}
+
+inline fun FalsingInteractor.runIfNotFalseTap(
+ penalty: Int = FalsingManager.LOW_PENALTY,
+ action: () -> Unit,
+) {
+ if (!isFalseTap(penalty)) {
+ action()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt
index d235c95..d53a737 100644
--- a/packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/Color.kt
@@ -18,6 +18,7 @@
import android.annotation.AttrRes
import android.annotation.ColorInt
+import android.annotation.ColorRes
/**
* Models a color that can be either a specific [Color.Loaded] value or a resolvable theme
@@ -28,4 +29,6 @@
data class Loaded(@ColorInt val color: Int) : Color
data class Attribute(@AttrRes val attribute: Int) : Color
+
+ data class Resource(@ColorRes val colorRes: Int) : Color
}
diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt
index 0869351..6a6c3eb 100644
--- a/packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt
@@ -16,10 +16,10 @@
package com.android.systemui.common.shared.model
-import androidx.annotation.AttrRes
+import androidx.annotation.ColorRes
/** Models an icon with a specific tint. */
data class TintedIcon(
val icon: Icon,
- @AttrRes val tint: Int?,
+ @ColorRes val tint: Int?,
)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
index d648b9c..5644e6b 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
@@ -23,7 +23,6 @@
import com.android.compose.animation.scene.TransitionKey
import com.android.internal.logging.UiEventLogger
import com.android.systemui.CoreStartable
-import com.android.systemui.Flags.communalHubOnMobile
import com.android.systemui.Flags.communalSceneKtfRefactor
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
@@ -218,7 +217,8 @@
newScene = CommunalScenes.Blank,
loggingReason = "hub timeout",
transitionKey =
- if (communalHubOnMobile()) CommunalTransitionKeys.SimpleFade
+ if (communalSettingsInteractor.isV2FlagEnabled())
+ CommunalTransitionKeys.SimpleFade
else null,
)
uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_TIMEOUT)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index f9b30c6..ea42869 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -27,6 +27,7 @@
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.TransitionKey
+import com.android.systemui.Flags.communalResponsiveGrid
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.communal.data.repository.CommunalMediaRepository
import com.android.systemui.communal.data.repository.CommunalSmartspaceRepository
@@ -535,7 +536,9 @@
// Order by creation time descending.
ongoingContent.sortByDescending { it.createdTimestampMillis }
// Resize the items.
- ongoingContent.resizeItems()
+ if (!communalResponsiveGrid()) {
+ ongoingContent.resizeItems()
+ }
// Return the sorted and resized items.
ongoingContent
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
index 0cdbad4..862b05b 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
@@ -63,24 +63,41 @@
.logDiffsForTable(
tableLogBuffer = tableLogBuffer,
columnPrefix = "disabledReason",
- initialValue = CommunalEnabledState()
+ initialValue = CommunalEnabledState(),
)
.map { model -> model.enabled }
// Start this eagerly since the value is accessed synchronously in many places.
.stateIn(scope = bgScope, started = SharingStarted.Eagerly, initialValue = false)
/**
- * Returns true if both the communal trunk-stable flag and resource flag are enabled.
+ * Returns true if any glanceable hub functionality should be enabled via configs and flags.
*
- * The trunk-stable flag is controlled by server rollout and is on all devices. The resource
- * flag is enabled via resource overlay only on products we want the hub to be present on.
+ * This should be used for preventing basic glanceable hub functionality from running on devices
+ * that don't need it.
*
* If this is false, then the hub is definitely not available on the device. If this is true,
* refer to [isCommunalEnabled] which takes into account other factors that can change at
* runtime.
+ *
+ * If the glanceable_hub_v2 flag is enabled, checks the config_glanceableHubEnabled Android
+ * config boolean. Otherwise, checks the old config_communalServiceEnabled config and
+ * communal_hub flag.
*/
fun isCommunalFlagEnabled(): Boolean = repository.getFlagEnabled()
+ /**
+ * Returns true if the Android config config_glanceableHubEnabled and the glanceable_hub_v2 flag
+ * are enabled.
+ *
+ * This should be used to flag off new glanceable hub or dream behavior that should launch
+ * together with the new hub experience that brings the hub to mobile.
+ *
+ * The trunk-stable flag is controlled by server rollout and is on all devices. The Android
+ * config flag is enabled via resource overlay only on products we want the hub to be present
+ * on.
+ */
+ fun isV2FlagEnabled(): Boolean = repository.getV2FlagEnabled()
+
/** The type of background to use for the hub. Used to experiment with different backgrounds */
val communalBackground: Flow<CommunalBackgroundType> =
userInteractor.selectedUserInfo
@@ -120,6 +137,6 @@
.stateIn(
scope = bgScope,
started = SharingStarted.WhileSubscribed(),
- initialValue = null
+ initialValue = null,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt
index da613f5..c0456d5 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt
@@ -110,6 +110,11 @@
get() = fixedHalfOrResponsiveSize()
}
+ /** An empty spacer to reserve space in the grid. */
+ data class Spacer(override val size: CommunalContentSize) : CommunalContentModel {
+ override val key: String = KEY.spacer()
+ }
+
/** A CTA tile in the glanceable hub view mode which can be dismissed. */
class CtaTileInViewMode : CommunalContentModel {
override val key: String = KEY.CTA_TILE_IN_VIEW_MODE_KEY
@@ -171,6 +176,10 @@
fun umo(): String {
return "umo"
}
+
+ fun spacer(): String {
+ return "spacer_${UUID.randomUUID()}"
+ }
}
}
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 a339af3..5ecf2e6b 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
@@ -195,7 +195,7 @@
open fun onDismissCtaTile() {}
/** Called as the user starts dragging a widget to reorder. */
- open fun onReorderWidgetStart(draggingItemKey: String) {}
+ open fun onReorderWidgetStart() {}
/** Called as the user finishes dragging a widget to reorder. */
open fun onReorderWidgetEnd() {}
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 52bf000..736ed5c 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
@@ -164,8 +164,9 @@
)
}
- override fun onReorderWidgetStart(draggingItemKey: String) {
- setSelectedKey(draggingItemKey)
+ override fun onReorderWidgetStart() {
+ // Clear selection status
+ setSelectedKey(null)
_reorderingWidgets.value = true
uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_REORDER_WIDGET_START)
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModel.kt
new file mode 100644
index 0000000..7d5b196
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModel.kt
@@ -0,0 +1,78 @@
+/*
+ * 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.communal.ui.viewmodel
+
+import android.annotation.SuppressLint
+import android.app.DreamManager
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.statusbar.policy.BatteryController
+import com.android.systemui.util.kotlin.isDevicePluggedIn
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.receiveAsFlow
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+class CommunalToDreamButtonViewModel
+@AssistedInject
+constructor(
+ @Background private val backgroundContext: CoroutineContext,
+ batteryController: BatteryController,
+ private val dreamManager: DreamManager,
+) : ExclusiveActivatable() {
+
+ private val _requests = Channel<Unit>(Channel.BUFFERED)
+
+ /** Whether we should show a button on hub to switch to dream. */
+ @SuppressLint("MissingPermission")
+ val shouldShowDreamButtonOnHub =
+ batteryController
+ .isDevicePluggedIn()
+ .distinctUntilChanged()
+ .map { isPluggedIn -> isPluggedIn && dreamManager.canStartDreaming(true) }
+ .flowOn(backgroundContext)
+
+ /** Handle a tap on the "show dream" button. */
+ fun onShowDreamButtonTap() {
+ _requests.trySend(Unit)
+ }
+
+ @SuppressLint("MissingPermission")
+ override suspend fun onActivated(): Nothing = coroutineScope {
+ launch {
+ _requests.receiveAsFlow().collectLatest {
+ withContext(backgroundContext) { dreamManager.startDream() }
+ }
+ }
+
+ awaitCancellation()
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(): CommunalToDreamButtonViewModel
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index 9cd6465..eb7420f 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -90,7 +90,7 @@
private val keyguardIndicationController: KeyguardIndicationController,
communalSceneInteractor: CommunalSceneInteractor,
private val communalInteractor: CommunalInteractor,
- communalSettingsInteractor: CommunalSettingsInteractor,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
tutorialInteractor: CommunalTutorialInteractor,
private val shadeInteractor: ShadeInteractor,
@Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost,
@@ -372,6 +372,9 @@
val communalBackground: Flow<CommunalBackgroundType> =
communalSettingsInteractor.communalBackground
+ /** See [CommunalSettingsInteractor.isV2FlagEnabled] */
+ fun v2FlagEnabled(): Boolean = communalSettingsInteractor.isV2FlagEnabled()
+
companion object {
const val POPUP_AUTO_HIDE_TIMEOUT_MS = 12000L
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt b/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
index 4217744..481acc9 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
@@ -18,7 +18,6 @@
import android.content.Context
import android.graphics.Color
-import com.android.settingslib.Utils
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -54,9 +53,6 @@
private fun loadBackgroundColor(): Color =
Color.valueOf(
- Utils.getColorAttrDefaultColor(
- context,
- com.android.internal.R.attr.materialColorPrimary
- )
+ context.getColor(com.android.internal.R.color.materialColorPrimary)
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/ResizeUtils.kt b/packages/SystemUI/src/com/android/systemui/communal/util/ResizeUtils.kt
new file mode 100644
index 0000000..36cc1c0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/util/ResizeUtils.kt
@@ -0,0 +1,71 @@
+/*
+ * 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.communal.util
+
+import com.android.systemui.communal.domain.model.CommunalContentModel
+import com.android.systemui.communal.shared.model.CommunalContentSize
+
+object ResizeUtils {
+ /**
+ * Resizes ongoing items such that we don't mix regular content with ongoing content.
+ *
+ * NOTE: This is *NOT* a pure function, as it modifies items in the input list.
+ *
+ * Assumptions:
+ * 1. Ongoing content is always at the start of the list.
+ * 2. The maximum size of ongoing content is 2 rows.
+ */
+ fun resizeOngoingItems(
+ list: List<CommunalContentModel>,
+ numRows: Int,
+ ): List<CommunalContentModel> {
+ val finalizedList = mutableListOf<CommunalContentModel>()
+ val numOngoing = list.count { it is CommunalContentModel.Ongoing }
+ // Calculate the number of extra rows we have if each ongoing item were to take up a single
+ // row. This is the number of rows we have to distribute across items.
+ var extraRows =
+ if (numOngoing % numRows == 0) {
+ 0
+ } else {
+ numRows - (numOngoing % numRows)
+ }
+ var remainingRows = numRows
+
+ for (item in list) {
+ if (item is CommunalContentModel.Ongoing) {
+ if (remainingRows == 0) {
+ // Start a new column.
+ remainingRows = numRows
+ }
+ val newSize = if (extraRows > 0 && remainingRows > 1) 2 else 1
+ item.size = CommunalContentSize.Responsive(newSize)
+ finalizedList.add(item)
+ extraRows -= (newSize - 1)
+ remainingRows -= newSize
+ } else {
+ if (numOngoing > 0 && remainingRows > 0) {
+ finalizedList.add(
+ CommunalContentModel.Spacer(CommunalContentSize.Responsive(remainingRows))
+ )
+ }
+ remainingRows = -1
+ finalizedList.add(item)
+ }
+ }
+ return finalizedList
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.kt
index e76fd47..c425bee 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.kt
@@ -25,7 +25,7 @@
import android.os.RemoteException
import android.service.dreams.IDreamManager
import android.util.Log
-import com.android.systemui.Flags
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.dagger.qualifiers.SystemUser
import com.android.systemui.dreams.dagger.DreamModule
import com.android.systemui.log.LogBuffer
@@ -48,6 +48,7 @@
@SystemUser monitor: Monitor,
private val packageManager: PackageManager,
private val dreamManager: IDreamManager,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
@DreamLog private val logBuffer: LogBuffer,
) : ConditionalCoreStartable(monitor) {
private var currentRegisteredState = false
@@ -90,7 +91,7 @@
}
if (
- Flags.communalHubOnMobile() &&
+ communalSettingsInteractor.isV2FlagEnabled() &&
packageManager.getComponentEnabledSetting(overlayServiceComponent) ==
PackageManager.COMPONENT_ENABLED_STATE_ENABLED
) {
@@ -111,7 +112,7 @@
}
// Enable for hub on mobile
- if (Flags.communalHubOnMobile()) {
+ if (communalSettingsInteractor.isV2FlagEnabled()) {
// Not available on TV or auto
if (
packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) ||
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index aee3a45..571b37f 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -18,7 +18,6 @@
import static android.service.dreams.Flags.dreamWakeRedirect;
-import static com.android.systemui.Flags.communalHubOnMobile;
import static com.android.systemui.Flags.glanceableHubAllowKeyguardWhenDreaming;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_WINDOW_TITLE;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_TOUCH_INSET_MANAGER;
@@ -60,6 +59,7 @@
import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent;
import com.android.systemui.ambient.touch.scrim.ScrimManager;
import com.android.systemui.communal.domain.interactor.CommunalInteractor;
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor;
import com.android.systemui.communal.shared.log.CommunalUiEvent;
import com.android.systemui.communal.shared.model.CommunalScenes;
import com.android.systemui.communal.shared.model.CommunalTransitionKeys;
@@ -171,6 +171,7 @@
private final SceneInteractor mSceneInteractor;
private final CommunalInteractor mCommunalInteractor;
+ private final CommunalSettingsInteractor mCommunalSettingsInteractor;
private boolean mCommunalAvailable;
@@ -383,6 +384,7 @@
KeyguardUpdateMonitor keyguardUpdateMonitor,
ScrimManager scrimManager,
CommunalInteractor communalInteractor,
+ CommunalSettingsInteractor communalSettingsInteractor,
SceneInteractor sceneInteractor,
SystemDialogsCloser systemDialogsCloser,
UiEventLogger uiEventLogger,
@@ -411,6 +413,7 @@
mDreamOverlayCallbackController = dreamOverlayCallbackController;
mWindowTitle = windowTitle;
mCommunalInteractor = communalInteractor;
+ mCommunalSettingsInteractor = communalSettingsInteractor;
mSceneInteractor = sceneInteractor;
mSystemDialogsCloser = systemDialogsCloser;
mGestureInteractor = gestureInteractor;
@@ -488,7 +491,7 @@
final ArrayList<TouchHandler> touchHandlers = new ArrayList<>(
List.of(dreamComplicationComponent.getHideComplicationTouchHandler()));
- if (!communalHubOnMobile()) {
+ if (!mCommunalSettingsInteractor.isV2FlagEnabled()) {
// Do not add the communal touch handler for glanceable hub v2 since there is no dream
// to hub swipe gesture.
touchHandlers.add(dreamOverlayComponent.getCommunalTouchHandler());
@@ -575,7 +578,8 @@
} else {
mCommunalInteractor.changeScene(CommunalScenes.Communal,
"dream wake requested",
- communalHubOnMobile() ? CommunalTransitionKeys.INSTANCE.getSimpleFade() : null);
+ mCommunalSettingsInteractor.isV2FlagEnabled()
+ ? CommunalTransitionKeys.INSTANCE.getSimpleFade() : null);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt
index 7242770..e264635 100644
--- a/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractor.kt
@@ -21,6 +21,9 @@
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.contextualeducation.GestureType
import com.android.systemui.contextualeducation.GestureType.ALL_APPS
+import com.android.systemui.contextualeducation.GestureType.BACK
+import com.android.systemui.contextualeducation.GestureType.HOME
+import com.android.systemui.contextualeducation.GestureType.OVERVIEW
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.education.ContextualEducationMetricsLogger
@@ -37,6 +40,7 @@
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import java.time.Clock
+import java.time.Instant
import javax.inject.Inject
import kotlin.time.Duration
import kotlin.time.Duration.Companion.days
@@ -48,6 +52,7 @@
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.merge
@@ -71,6 +76,8 @@
const val TAG = "KeyboardTouchpadEduInteractor"
const val MAX_SIGNAL_COUNT: Int = 2
const val MAX_EDUCATION_SHOW_COUNT: Int = 2
+ const val MAX_TOAST_PER_USAGE_SESSION: Int = 2
+
val usageSessionDuration =
getDurationForConfig("persist.contextual_edu.usage_session_sec", 3.days)
val minIntervalBetweenEdu =
@@ -110,6 +117,16 @@
awaitClose { overviewProxyService.removeCallback(listener) }
}
+ private val gestureModelMap: Flow<Map<GestureType, GestureEduModel>> =
+ combine(
+ contextualEducationInteractor.backGestureModelFlow,
+ contextualEducationInteractor.homeGestureModelFlow,
+ contextualEducationInteractor.overviewGestureModelFlow,
+ contextualEducationInteractor.allAppsGestureModelFlow,
+ ) { back, home, overview, allApps ->
+ mapOf(BACK to back, HOME to home, OVERVIEW to overview, ALL_APPS to allApps)
+ }
+
@OptIn(ExperimentalCoroutinesApi::class)
override fun start() {
backgroundScope.launch {
@@ -211,7 +228,11 @@
private suspend fun incrementSignalCount(gestureType: GestureType) {
val targetDevice = getTargetDevice(gestureType)
- if (isTargetDeviceConnected(targetDevice) && hasInitialDelayElapsed(targetDevice)) {
+ if (
+ isTargetDeviceConnected(targetDevice) &&
+ hasInitialDelayElapsed(targetDevice) &&
+ isMinIntervalForToastEduElapsed(gestureType)
+ ) {
contextualEducationInteractor.incrementSignalCount(gestureType)
}
}
@@ -223,6 +244,28 @@
}
}
+ private suspend fun isMinIntervalForToastEduElapsed(gestureType: GestureType): Boolean {
+ val gestureModelMap = gestureModelMap.first()
+ // Only perform checking if the next edu is toast (i.e. no education is shown yet)
+ if (gestureModelMap[gestureType]?.educationShownCount != 0) {
+ return true
+ }
+
+ val wasLastEduToast = { gesture: GestureEduModel -> gesture.educationShownCount == 1 }
+ val toastEduTimesInCurrentSession: List<Instant> =
+ gestureModelMap.values
+ .filter { wasLastEduToast(it) }
+ .mapNotNull { it.lastEducationTime }
+ .filter { it >= clock.instant().minusSeconds(usageSessionDuration.inWholeSeconds) }
+
+ return if (toastEduTimesInCurrentSession.size >= MAX_TOAST_PER_USAGE_SESSION) {
+ val lastToastTime: Instant? = toastEduTimesInCurrentSession.maxOrNull()
+ clock.instant().isAfter(lastToastTime?.plusSeconds(usageSessionDuration.inWholeSeconds))
+ } else {
+ true
+ }
+ }
+
/**
* Keyboard shortcut education would be provided for All Apps. Touchpad gesture education would
* be provided for the rest of the gesture types (i.e. Home, Overview, Back). This method maps
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
index 1e9be09..246f657 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
@@ -17,7 +17,6 @@
package com.android.systemui.keyboard.backlight.ui.view
-import android.annotation.AttrRes
import android.annotation.ColorInt
import android.app.Dialog
import android.content.Context
@@ -38,7 +37,6 @@
import android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
import androidx.annotation.IdRes
import androidx.core.view.setPadding
-import com.android.settingslib.Utils
import com.android.systemui.res.R
class KeyboardBacklightDialog(
@@ -80,25 +78,25 @@
@ColorInt
private val filledRectangleColor =
- getColorFromStyle(com.android.internal.R.attr.materialColorPrimary)
+ context.getColor(com.android.internal.R.color.materialColorPrimary)
@ColorInt
private val emptyRectangleColor =
- getColorFromStyle(com.android.internal.R.attr.materialColorOutlineVariant)
+ context.getColor(com.android.internal.R.color.materialColorOutlineVariant)
@ColorInt
private val backgroundColor =
- getColorFromStyle(com.android.internal.R.attr.materialColorSurfaceBright)
+ context.getColor(com.android.internal.R.color.materialColorSurfaceBright)
@ColorInt
private val defaultIconColor =
- getColorFromStyle(com.android.internal.R.attr.materialColorOnPrimary)
+ context.getColor(com.android.internal.R.color.materialColorOnPrimary)
@ColorInt
private val defaultIconBackgroundColor =
- getColorFromStyle(com.android.internal.R.attr.materialColorPrimary)
+ context.getColor(com.android.internal.R.color.materialColorPrimary)
@ColorInt
private val dimmedIconColor =
- getColorFromStyle(com.android.internal.R.attr.materialColorOnSurface)
+ context.getColor(com.android.internal.R.color.materialColorOnSurface)
@ColorInt
private val dimmedIconBackgroundColor =
- getColorFromStyle(com.android.internal.R.attr.materialColorSurfaceDim)
+ context.getColor(com.android.internal.R.color.materialColorSurfaceDim)
private val levelContentDescription = context.getString(R.string.keyboard_backlight_value)
@@ -153,11 +151,6 @@
}
}
- @ColorInt
- fun getColorFromStyle(@AttrRes colorId: Int): Int {
- return Utils.getColorAttrDefaultColor(context, colorId)
- }
-
fun updateState(current: Int, max: Int, forceRefresh: Boolean = false) {
if (maxLevel != max || forceRefresh) {
maxLevel = max
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/InternalShortcutModels.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/InternalShortcutModels.kt
index 8c393e2..3020e5d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/InternalShortcutModels.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/InternalShortcutModels.kt
@@ -21,6 +21,7 @@
import android.view.KeyboardShortcutGroup
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutCategoriesUtils
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
/**
* Internal Keyboard Shortcut models to use with [ShortcutCategoriesUtils.fetchShortcutCategory]
@@ -55,3 +56,8 @@
val icon: Icon? = null,
val isCustomShortcut: Boolean = false,
)
+
+data class InternalGroupsSource(
+ val groups: List<InternalKeyboardShortcutGroup>,
+ val type: ShortcutCategoryType,
+)
\ No newline at end of file
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 4af3786..8afec04 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
@@ -16,10 +16,8 @@
package com.android.systemui.keyboard.shortcut.data.repository
-import android.content.Context
import android.hardware.input.InputGestureData
import android.hardware.input.InputGestureData.Builder
-import android.hardware.input.InputGestureData.KeyTrigger
import android.hardware.input.InputGestureData.createKeyTrigger
import android.hardware.input.InputManager
import android.hardware.input.KeyGestureEvent.KeyGestureType
@@ -30,11 +28,8 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyboard.shared.model.ShortcutCustomizationRequestResult
-import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup
-import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutInfo
import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
-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.ShortcutHelperState.Active
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
@@ -57,8 +52,7 @@
@Background private val backgroundScope: CoroutineScope,
@Background private val bgCoroutineContext: CoroutineContext,
private val shortcutCategoriesUtils: ShortcutCategoriesUtils,
- private val context: Context,
- private val inputGestureMaps: InputGestureMaps,
+ private val inputGestureDataAdapter: InputGestureDataAdapter,
private val customInputGesturesRepository: CustomInputGesturesRepository,
private val inputManager: InputManager
) : ShortcutCategoriesRepository {
@@ -116,7 +110,7 @@
if (inputDevice == null) {
emptyList()
} else {
- val sources = toInternalGroupSources(inputGestures)
+ val sources = inputGestureDataAdapter.toInternalGroupSources(inputGestures)
val supportedKeyCodes =
shortcutCategoriesUtils.fetchSupportedKeyCodes(
inputDevice.id,
@@ -216,7 +210,8 @@
return null
}
- return inputGestureMaps.shortcutLabelToKeyGestureTypeMap[shortcutBeingCustomized.label]
+ return inputGestureDataAdapter
+ .getKeyGestureTypeFromShortcutLabel(shortcutBeingCustomized.label)
}
@KeyGestureType
@@ -232,7 +227,8 @@
return null
}
- return inputGestureMaps.shortcutLabelToKeyGestureTypeMap[shortcutBeingCustomized.label]
+ return inputGestureDataAdapter
+ .getKeyGestureTypeFromShortcutLabel(shortcutBeingCustomized.label)
}
private fun Builder.addTriggerFromSelectedKeyCombination(): Builder {
@@ -261,70 +257,6 @@
return _shortcutBeingCustomized.value
}
- private fun toInternalGroupSources(
- inputGestures: List<InputGestureData>
- ): List<InternalGroupsSource> {
- val ungroupedInternalGroupSources =
- inputGestures.mapNotNull { gestureData ->
- val keyTrigger = gestureData.trigger as KeyTrigger
- val keyGestureType = gestureData.action.keyGestureType()
- fetchGroupLabelByGestureType(keyGestureType)?.let { groupLabel ->
- toInternalKeyboardShortcutInfo(keyGestureType, keyTrigger)?.let {
- internalKeyboardShortcutInfo ->
- val group =
- InternalKeyboardShortcutGroup(
- label = groupLabel,
- items = listOf(internalKeyboardShortcutInfo),
- )
-
- fetchShortcutCategoryTypeByGestureType(keyGestureType)?.let {
- InternalGroupsSource(groups = listOf(group), type = it)
- }
- }
- }
- }
-
- return ungroupedInternalGroupSources
- }
-
- private fun toInternalKeyboardShortcutInfo(
- keyGestureType: Int,
- keyTrigger: KeyTrigger,
- ): InternalKeyboardShortcutInfo? {
- fetchShortcutInfoLabelByGestureType(keyGestureType)?.let {
- return InternalKeyboardShortcutInfo(
- label = it,
- keycode = keyTrigger.keycode,
- modifiers = keyTrigger.modifierState,
- isCustomShortcut = true,
- )
- }
- return null
- }
-
- private fun fetchGroupLabelByGestureType(@KeyGestureType keyGestureType: Int): String? {
- inputGestureMaps.gestureToInternalKeyboardShortcutGroupLabelResIdMap[keyGestureType]?.let {
- return context.getString(it)
- } ?: return null
- }
-
- private fun fetchShortcutInfoLabelByGestureType(@KeyGestureType keyGestureType: Int): String? {
- inputGestureMaps.gestureToInternalKeyboardShortcutInfoLabelResIdMap[keyGestureType]?.let {
- return context.getString(it)
- } ?: return null
- }
-
- private fun fetchShortcutCategoryTypeByGestureType(
- @KeyGestureType keyGestureType: Int
- ): ShortcutCategoryType? {
- return inputGestureMaps.gestureToShortcutCategoryTypeMap[keyGestureType]
- }
-
- private data class InternalGroupsSource(
- val groups: List<InternalKeyboardShortcutGroup>,
- val type: ShortcutCategoryType,
- )
-
private companion object {
private const val TAG = "CustomShortcutCategoriesRepository"
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureDataAdapter.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureDataAdapter.kt
new file mode 100644
index 0000000..df7101e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureDataAdapter.kt
@@ -0,0 +1,267 @@
+/*
+ * 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.data.repository
+
+import android.annotation.SuppressLint
+import android.app.role.RoleManager
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.content.Intent.ACTION_MAIN
+import android.content.Intent.CATEGORY_LAUNCHER
+import android.content.pm.ActivityInfo
+import android.content.pm.PackageManager.MATCH_DEFAULT_ONLY
+import android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE
+import android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+import android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
+import android.content.pm.PackageManager.NameNotFoundException
+import android.graphics.drawable.Icon
+import android.hardware.input.AppLaunchData
+import android.hardware.input.AppLaunchData.CategoryData
+import android.hardware.input.AppLaunchData.ComponentData
+import android.hardware.input.AppLaunchData.RoleData
+import android.hardware.input.InputGestureData
+import android.hardware.input.InputGestureData.KeyTrigger
+import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION
+import android.hardware.input.KeyGestureEvent.KeyGestureType
+import android.util.Log
+import com.android.internal.app.ResolverActivity
+import com.android.systemui.keyboard.shortcut.data.model.InternalGroupsSource
+import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutGroup
+import com.android.systemui.keyboard.shortcut.data.model.InternalKeyboardShortcutInfo
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.res.R
+import com.android.systemui.settings.UserTracker
+import javax.inject.Inject
+
+
+class InputGestureDataAdapter
+@Inject
+constructor(
+ private val userTracker: UserTracker,
+ private val inputGestureMaps: InputGestureMaps,
+ private val context: Context
+) {
+ private val userContext: Context
+ get() = userTracker.createCurrentUserContext(userTracker.userContext)
+
+ fun toInternalGroupSources(
+ inputGestures: List<InputGestureData>
+ ): List<InternalGroupsSource> {
+ val ungroupedInternalGroupSources =
+ inputGestures.mapNotNull { gestureData ->
+ val keyTrigger = gestureData.trigger as KeyTrigger
+ val keyGestureType = gestureData.action.keyGestureType()
+ val appLaunchData: AppLaunchData? = gestureData.action.appLaunchData()
+ fetchGroupLabelByGestureType(keyGestureType)?.let { groupLabel ->
+ toInternalKeyboardShortcutInfo(
+ keyGestureType,
+ keyTrigger,
+ appLaunchData
+ )?.let { internalKeyboardShortcutInfo ->
+ val group =
+ InternalKeyboardShortcutGroup(
+ label = groupLabel,
+ items = listOf(internalKeyboardShortcutInfo),
+ )
+
+ fetchShortcutCategoryTypeByGestureType(keyGestureType)?.let {
+ InternalGroupsSource(groups = listOf(group), type = it)
+ }
+ }
+ }
+ }
+
+ return ungroupedInternalGroupSources
+ }
+
+ fun getKeyGestureTypeFromShortcutLabel(label: String): Int? {
+ return inputGestureMaps.shortcutLabelToKeyGestureTypeMap[label]
+ }
+
+ private fun toInternalKeyboardShortcutInfo(
+ keyGestureType: Int,
+ keyTrigger: KeyTrigger,
+ appLaunchData: AppLaunchData?,
+ ): InternalKeyboardShortcutInfo? {
+ fetchShortcutLabelByGestureType(keyGestureType, appLaunchData)?.let {
+ return InternalKeyboardShortcutInfo(
+ label = it,
+ keycode = keyTrigger.keycode,
+ modifiers = keyTrigger.modifierState,
+ isCustomShortcut = true,
+ icon = appLaunchData?.let { fetchShortcutIconByAppLaunchData(appLaunchData) }
+ )
+ }
+ return null
+ }
+
+ @SuppressLint("QueryPermissionsNeeded")
+ private fun fetchShortcutIconByAppLaunchData(
+ appLaunchData: AppLaunchData
+ ): Icon? {
+ val intent = fetchIntentFromAppLaunchData(appLaunchData) ?: return null
+ val resolvedActivity = resolveSingleMatchingActivityFrom(intent)
+
+ return if (resolvedActivity == null) {
+ null
+ } else {
+ Icon.createWithResource(context, resolvedActivity.iconResource)
+ }
+ }
+
+ private fun fetchGroupLabelByGestureType(@KeyGestureType keyGestureType: Int): String? {
+ inputGestureMaps.gestureToInternalKeyboardShortcutGroupLabelResIdMap[keyGestureType]?.let {
+ return context.getString(it)
+ } ?: return null
+ }
+
+ private fun fetchShortcutLabelByGestureType(
+ @KeyGestureType keyGestureType: Int,
+ appLaunchData: AppLaunchData?
+ ): String? {
+ inputGestureMaps.gestureToInternalKeyboardShortcutInfoLabelResIdMap[keyGestureType]?.let {
+ return context.getString(it)
+ }
+
+ if (keyGestureType == KEY_GESTURE_TYPE_LAUNCH_APPLICATION) {
+ return fetchShortcutLabelByAppLaunchData(appLaunchData!!)
+ }
+
+ return null
+ }
+
+ private fun fetchShortcutLabelByAppLaunchData(appLaunchData: AppLaunchData): String? {
+ val intent = fetchIntentFromAppLaunchData(appLaunchData) ?: return null
+ val resolvedActivity = resolveSingleMatchingActivityFrom(intent)
+
+ return if (resolvedActivity == null) {
+ getIntentCategoryLabel(intent.selector?.categories?.iterator()?.next())
+ } else resolvedActivity.loadLabel(userContext.packageManager).toString()
+
+ }
+
+ @SuppressLint("QueryPermissionsNeeded")
+ private fun resolveSingleMatchingActivityFrom(intent: Intent): ActivityInfo? {
+ val packageManager = userContext.packageManager
+ val resolvedActivity = intent.resolveActivityInfo(
+ packageManager,
+ /* flags= */ MATCH_DEFAULT_ONLY
+ ) ?: return null
+
+ val matchesMultipleActivities =
+ ResolverActivity::class.qualifiedName.equals(resolvedActivity.name)
+
+ return if (matchesMultipleActivities) {
+ return null
+ } else resolvedActivity
+ }
+
+ private fun getIntentCategoryLabel(category: String?): String? {
+ val categoryLabelRes = when (category.toString()) {
+ Intent.CATEGORY_APP_BROWSER -> R.string.keyboard_shortcut_group_applications_browser
+ Intent.CATEGORY_APP_CONTACTS -> R.string.keyboard_shortcut_group_applications_contacts
+ Intent.CATEGORY_APP_EMAIL -> R.string.keyboard_shortcut_group_applications_email
+ Intent.CATEGORY_APP_CALENDAR -> R.string.keyboard_shortcut_group_applications_calendar
+ Intent.CATEGORY_APP_MAPS -> R.string.keyboard_shortcut_group_applications_maps
+ Intent.CATEGORY_APP_MUSIC -> R.string.keyboard_shortcut_group_applications_music
+ Intent.CATEGORY_APP_MESSAGING -> R.string.keyboard_shortcut_group_applications_sms
+ Intent.CATEGORY_APP_CALCULATOR -> R.string.keyboard_shortcut_group_applications_calculator
+ else -> {
+ Log.w(TAG, ("No label for app category $category"))
+ null
+ }
+ }
+
+ return if (categoryLabelRes == null){
+ return null
+ } else {
+ context.getString(categoryLabelRes)
+ }
+ }
+
+ private fun fetchIntentFromAppLaunchData(appLaunchData: AppLaunchData): Intent? {
+ return when (appLaunchData) {
+ is CategoryData -> Intent.makeMainSelectorActivity(
+ /* selectorAction= */ ACTION_MAIN,
+ /* selectorCategory= */ appLaunchData.category
+ )
+
+ is RoleData -> getRoleLaunchIntent(appLaunchData.role)
+ is ComponentData -> resolveComponentNameIntent(
+ packageName = appLaunchData.packageName,
+ className = appLaunchData.className
+ )
+
+ else -> null
+ }
+ }
+
+ private fun resolveComponentNameIntent(packageName: String, className: String): Intent? {
+ buildIntentFromComponentName(ComponentName(packageName, className))?.let { return it }
+ buildIntentFromComponentName(ComponentName(
+ userContext.packageManager.canonicalToCurrentPackageNames(arrayOf(packageName))[0],
+ className
+ ))?.let { return it }
+ return null
+ }
+
+ private fun buildIntentFromComponentName(componentName: ComponentName): Intent? {
+ try{
+ val flags =
+ MATCH_DIRECT_BOOT_UNAWARE or MATCH_DIRECT_BOOT_AWARE or MATCH_UNINSTALLED_PACKAGES
+ // attempt to retrieve activity info to see if a NameNotFoundException is thrown.
+ userContext.packageManager.getActivityInfo(componentName, flags)
+ } catch (e: NameNotFoundException) {
+ Log.w(
+ TAG,
+ "Unable to find activity info for componentName: $componentName"
+ )
+ return null
+ }
+
+ return Intent(ACTION_MAIN).apply {
+ addCategory(CATEGORY_LAUNCHER)
+ component = componentName
+ }
+ }
+
+ @SuppressLint("NonInjectedService")
+ private fun getRoleLaunchIntent(role: String): Intent? {
+ val packageManager = userContext.packageManager
+ val roleManager = userContext.getSystemService(RoleManager::class.java)!!
+ if (roleManager.isRoleAvailable(role)) {
+ roleManager.getDefaultApplication(role)?.let { rolePackage ->
+ packageManager.getLaunchIntentForPackage(rolePackage)?.let { return it }
+ ?: Log.w(TAG, "No launch intent for role $role")
+ } ?: Log.w(TAG, "No default application for role $role, user= ${userContext.user}")
+ } else {
+ Log.w(TAG, "Role $role is not available.")
+ }
+ return null
+ }
+
+ private fun fetchShortcutCategoryTypeByGestureType(
+ @KeyGestureType keyGestureType: Int
+ ): ShortcutCategoryType? {
+ return inputGestureMaps.gestureToShortcutCategoryTypeMap[keyGestureType]
+ }
+
+ private companion object {
+ private const val TAG = "InputGestureDataUtils"
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
index 1c380c2..d7be5e6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
@@ -22,14 +22,8 @@
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_HOME
+import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT
-import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER
-import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR
-import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR
-import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS
-import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL
-import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS
-import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN
@@ -74,13 +68,7 @@
KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT to MultiTasking,
// App Category
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR to AppCategories,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR to AppCategories,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER to AppCategories,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS to AppCategories,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL to AppCategories,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS to AppCategories,
- KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING to AppCategories,
+ KEY_GESTURE_TYPE_LAUNCH_APPLICATION to AppCategories,
)
val gestureToInternalKeyboardShortcutGroupLabelResIdMap =
@@ -116,20 +104,14 @@
R.string.shortcutHelper_category_split_screen,
// App Category
- 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
+ KEY_GESTURE_TYPE_LAUNCH_APPLICATION to
R.string.keyboard_shortcut_group_applications,
)
+ /**
+ * App Category shortcut labels are mapped dynamically based on intent
+ * see [InputGestureDataAdapter.fetchShortcutLabelByAppLaunchData]
+ */
val gestureToInternalKeyboardShortcutInfoLabelResIdMap =
mapOf(
// System Category
@@ -154,26 +136,6 @@
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
- R.string.system_multitasking_splitscreen_focus_lhs,
- KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT to
- R.string.system_multitasking_splitscreen_focus_rhs,
-
- // App Category
- 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,
)
val shortcutLabelToKeyGestureTypeMap: Map<String, Int>
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
index df6b04e..d785b5b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
@@ -26,7 +26,6 @@
import android.view.KeyEvent.KEYCODE_LEFT_BRACKET
import android.view.KeyEvent.KEYCODE_MINUS
import android.view.KeyEvent.KEYCODE_RIGHT_BRACKET
-import android.view.KeyEvent.META_ALT_ON
import android.view.KeyEvent.META_CTRL_ON
import android.view.KeyEvent.META_META_ON
import android.view.KeyboardShortcutGroup
@@ -74,20 +73,6 @@
command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_UP)
}
)
- // Change split screen focus to RHS:
- // - Meta + Alt + Right arrow
- add(
- shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
- command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_RIGHT)
- }
- )
- // Change split screen focus to LHS:
- // - Meta + Alt + Left arrow
- add(
- shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_lhs)) {
- command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_LEFT)
- }
- )
if (enableMoveToNextDisplayShortcut()) {
// Move a window to the next display:
// - Meta + Ctrl + D
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 7d9e010..2724918 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
@@ -115,6 +115,7 @@
import androidx.compose.ui.util.fastForEachIndexed
import com.android.compose.modifiers.thenIf
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
@@ -126,7 +127,6 @@
import com.android.systemui.keyboard.shortcut.ui.model.ShortcutsUiState
import com.android.systemui.res.R
import kotlinx.coroutines.delay
-import com.android.systemui.keyboard.shortcut.shared.model.Shortcut as ShortcutModel
@Composable
fun ShortcutHelper(
@@ -189,7 +189,7 @@
onKeyboardSettingsClicked,
shortcutsUiState.isShortcutCustomizerFlagEnabled,
onCustomizationRequested,
- shortcutsUiState.shouldShowResetButton
+ shortcutsUiState.shouldShowResetButton,
)
}
}
@@ -380,7 +380,7 @@
onKeyboardSettingsClicked: () -> Unit,
isShortcutCustomizerFlagEnabled: Boolean,
onCustomizationRequested: (ShortcutCustomizationRequestInfo) -> Unit = {},
- shouldShowResetButton: Boolean
+ shouldShowResetButton: Boolean,
) {
val selectedCategory = categories.fastFirstOrNull { it.type == selectedCategoryType }
var isCustomizing by remember { mutableStateOf(false) }
@@ -801,7 +801,10 @@
private fun BoxScope.ShortcutTextKey(key: ShortcutKey.Text) {
Text(
text = key.value,
- modifier = Modifier.align(Alignment.Center).padding(horizontal = 12.dp),
+ modifier =
+ Modifier.align(Alignment.Center).padding(horizontal = 12.dp).semantics {
+ hideFromAccessibility()
+ },
style = MaterialTheme.typography.titleSmall,
)
}
@@ -825,7 +828,7 @@
Spacer(Modifier.width(spacing))
Text(
text = stringResource(R.string.shortcut_helper_key_combinations_or_separator),
- modifier = Modifier.align(Alignment.CenterVertically),
+ modifier = Modifier.align(Alignment.CenterVertically).semantics { hideFromAccessibility() },
style = MaterialTheme.typography.titleSmall,
)
Spacer(Modifier.width(spacing))
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
index 71f29c0..d335a18 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
@@ -20,12 +20,12 @@
import android.content.Intent
import android.provider.Settings
import android.util.Log
-import com.android.systemui.Flags.glanceableHubShortcutButton
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.communal.data.repository.CommunalSceneRepository
import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.CommunalTransitionKeys
import com.android.systemui.dagger.SysUISingleton
@@ -46,6 +46,7 @@
@Application private val context: Context,
private val communalSceneRepository: CommunalSceneRepository,
private val communalInteractor: CommunalInteractor,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
private val sceneInteractor: SceneInteractor,
) : KeyguardQuickAffordanceConfig {
@@ -61,8 +62,7 @@
override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState>
get() = flow {
emit(
- // TODO(b/378113263): Gate on getV2FlagEnabled() when ready.
- if (!glanceableHubShortcutButton()) {
+ if (!communalSettingsInteractor.isV2FlagEnabled()) {
Log.i(TAG, "Button hidden on lockscreen: flag not enabled.")
KeyguardQuickAffordanceConfig.LockScreenState.Hidden
} else if (!communalInteractor.isCommunalEnabled.value) {
@@ -81,8 +81,7 @@
}
override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
- // TODO(b/378113263): Gate on getV2FlagEnabled() when ready.
- return if (!glanceableHubShortcutButton()) {
+ return if (!communalSettingsInteractor.isV2FlagEnabled()) {
Log.i(TAG, "Button unavailable in picker: flag not enabled.")
KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
} else if (!communalInteractor.isCommunalEnabled.value) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
index 25e6f0e..a999211 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
@@ -21,7 +21,6 @@
import android.app.DreamManager
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launchTraced as launch
-import com.android.systemui.Flags.communalHubOnMobile
import com.android.systemui.Flags.communalSceneKtfRefactor
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
@@ -177,7 +176,8 @@
newScene = CommunalScenes.Communal,
loggingReason = "FromDreamingTransitionInteractor",
transitionKey =
- if (communalHubOnMobile()) CommunalTransitionKeys.SimpleFade
+ if (communalSettingsInteractor.isV2FlagEnabled())
+ CommunalTransitionKeys.SimpleFade
else null,
)
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt
index 0cb8dd4..5c03d65 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/KeyguardTransitionAnimationFlow.kt
@@ -36,7 +36,6 @@
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
/**
@@ -51,17 +50,11 @@
private val logger: KeyguardTransitionAnimationLogger,
) {
/** Invoke once per transition between FROM->TO states to get access to a shared flow. */
- fun setup(
- duration: Duration,
- edge: Edge,
- ): FlowBuilder {
+ fun setup(duration: Duration, edge: Edge): FlowBuilder {
return FlowBuilder(duration, edge)
}
- inner class FlowBuilder(
- private val transitionDuration: Duration,
- private val edge: Edge,
- ) {
+ inner class FlowBuilder(private val transitionDuration: Duration, private val edge: Edge) {
fun setupWithoutSceneContainer(edge: Edge.StateToState): FlowBuilder {
if (SceneContainerFlag.isEnabled) return this
return setup(this.transitionDuration, edge)
@@ -72,6 +65,8 @@
* in the range of [0, 1]. View animations should begin and end within a subset of this
* range. This function maps the [startTime] and [duration] into [0, 1], when this subset is
* valid.
+ *
+ * Note that [onCancel] isn't used when the scene framework is enabled.
*/
fun sharedFlow(
duration: Duration,
@@ -81,7 +76,7 @@
onCancel: (() -> Float)? = null,
onFinish: (() -> Float)? = null,
interpolator: Interpolator = LINEAR,
- name: String? = null
+ name: String? = null,
): Flow<Float> {
return sharedFlowWithState(
duration = duration,
@@ -113,7 +108,7 @@
onCancel: (() -> Float)? = null,
onFinish: (() -> Float)? = null,
interpolator: Interpolator = LINEAR,
- name: String? = null
+ name: String? = null,
): Flow<StateToValue> {
if (!duration.isPositive()) {
throw IllegalArgumentException("duration must be a positive number: $duration")
@@ -155,20 +150,40 @@
return transitionInteractor
.transition(edge)
- .map { step ->
- StateToValue(
- from = step.from,
- to = step.to,
- transitionState = step.transitionState,
- value =
- when (step.transitionState) {
- STARTED -> stepToValue(step)
- RUNNING -> stepToValue(step)
- CANCELED -> onCancel?.invoke()
- FINISHED -> onFinish?.invoke()
- }
- )
- .also { logger.logTransitionStep(name, step, it.value) }
+ .mapNotNull { step ->
+ if (SceneContainerFlag.isEnabled && step.transitionState == CANCELED) {
+ // When the scene framework is enabled, there's no need to emit an alpha
+ // value when the keyguard transition animation is canceled because there's
+ // always going to be a new, reversed keyguard transition animation back to
+ // the original KeyguardState that starts right when this one was canceled.
+ //
+ // For example, if swiping up slightly on the Lockscreen scene and then
+ // releasing before the transition to the Bouncer scene is committed, the
+ // KTF transition of LOCKSCREEN -> PRIMARY_BOUNCER received a CANCELED and
+ // the scene framework immediately starts a reversed transition of
+ // PRIMARY_BOUNCER -> LOCKSCREEN, which picks up where the previous one left
+ // off.
+ //
+ // If it were allowed for the CANCELED from the original KTF transition to
+ // emit a value, a race condition could form where the value from CANCELED
+ // arrives downstream _after_ the reversed transition is finished, causing
+ // the transition to end up in an incorrect state at rest.
+ null
+ } else {
+ StateToValue(
+ from = step.from,
+ to = step.to,
+ transitionState = step.transitionState,
+ value =
+ when (step.transitionState) {
+ STARTED -> stepToValue(step)
+ RUNNING -> stepToValue(step)
+ CANCELED -> onCancel?.invoke()
+ FINISHED -> onFinish?.invoke()
+ },
+ )
+ .also { logger.logTransitionStep(name, step, it.value) }
+ }
}
.distinctUntilChanged()
}
@@ -181,7 +196,7 @@
duration = 1.milliseconds,
onStep = { value },
onCancel = { value },
- onFinish = { value }
+ onFinish = { value },
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index 3bdf7da..c59fe53 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.ui.binder
import android.annotation.SuppressLint
+import android.content.res.ColorStateList
import android.graphics.Rect
import android.graphics.drawable.Animatable2
import android.util.Size
@@ -37,7 +38,6 @@
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launchTraced as launch
-import com.android.settingslib.Utils
import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.animation.Expandable
import com.android.systemui.animation.view.LaunchableLinearLayout
@@ -382,25 +382,25 @@
view.isActivated = viewModel.isActivated
view.drawable.setTint(
- Utils.getColorAttrDefaultColor(
- view.context,
+ view.context.getColor(
if (viewModel.isActivated) {
- com.android.internal.R.attr.materialColorOnPrimaryFixed
+ com.android.internal.R.color.materialColorOnPrimaryFixed
} else {
- com.android.internal.R.attr.materialColorOnSurface
- },
+ com.android.internal.R.color.materialColorOnSurface
+ }
)
)
view.backgroundTintList =
if (!viewModel.isSelected) {
- Utils.getColorAttr(
- view.context,
- if (viewModel.isActivated) {
- com.android.internal.R.attr.materialColorPrimaryFixed
- } else {
- com.android.internal.R.attr.materialColorSurfaceContainerHigh
- }
+ ColorStateList.valueOf(
+ view.context.getColor(
+ if (viewModel.isActivated) {
+ com.android.internal.R.color.materialColorPrimaryFixed
+ } else {
+ com.android.internal.R.color.materialColorSurfaceContainerHigh
+ }
+ )
)
} else {
null
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
index 191e08b..5c8a234 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
@@ -18,6 +18,7 @@
package com.android.systemui.keyguard.ui.binder
import android.annotation.SuppressLint
+import android.content.res.ColorStateList
import android.graphics.drawable.Animatable2
import android.util.Size
import android.view.View
@@ -32,7 +33,6 @@
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.keyguard.logging.KeyguardQuickAffordancesLogger
-import com.android.settingslib.Utils
import com.android.systemui.animation.Expandable
import com.android.systemui.animation.view.LaunchableImageView
import com.android.systemui.common.shared.model.Icon
@@ -176,25 +176,25 @@
view.isActivated = viewModel.isActivated
view.drawable.setTint(
- Utils.getColorAttrDefaultColor(
- view.context,
+ view.context.getColor(
if (viewModel.isActivated) {
- com.android.internal.R.attr.materialColorOnPrimaryFixed
+ com.android.internal.R.color.materialColorOnPrimaryFixed
} else {
- com.android.internal.R.attr.materialColorOnSurface
+ com.android.internal.R.color.materialColorOnSurface
},
)
)
view.backgroundTintList =
if (!viewModel.isSelected) {
- Utils.getColorAttr(
- view.context,
- if (viewModel.isActivated) {
- com.android.internal.R.attr.materialColorPrimaryFixed
- } else {
- com.android.internal.R.attr.materialColorSurfaceContainerHigh
- }
+ ColorStateList.valueOf(
+ view.context.getColor(
+ if (viewModel.isActivated) {
+ com.android.internal.R.color.materialColorPrimaryFixed
+ } else {
+ com.android.internal.R.color.materialColorSurfaceContainerHigh
+ }
+ )
)
} else {
null
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index eab7528..85725d2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -368,8 +368,8 @@
SceneContainerFlag.isEnabled,
)
)
- val startPadding: Int = smartspaceViewModel.getSmartspaceStartPadding(previewContext)
- val endPadding: Int = smartspaceViewModel.getSmartspaceEndPadding(previewContext)
+ val startPadding: Int = smartspaceViewModel.getDateWeatherStartPadding(previewContext)
+ val endPadding: Int = smartspaceViewModel.getDateWeatherEndPadding(previewContext)
smartSpaceView?.let {
it.setPaddingRelative(startPadding, topPadding, endPadding, 0)
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 d54d411..73e14b1 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,8 +33,8 @@
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.shade.ShadeDisplayAware
import com.android.systemui.shared.R as sharedR
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController
import dagger.Lazy
@@ -113,8 +113,9 @@
override fun applyConstraints(constraintSet: ConstraintSet) {
if (!MigrateClocksToBlueprint.isEnabled) return
if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) return
- val horizontalPaddingStart = KeyguardSmartspaceViewModel.getSmartspaceStartMargin(context)
- val horizontalPaddingEnd = KeyguardSmartspaceViewModel.getSmartspaceEndMargin(context)
+ val dateWeatherPaddingStart = KeyguardSmartspaceViewModel.getDateWeatherStartMargin(context)
+ val smartspaceHorizontalPadding =
+ KeyguardSmartspaceViewModel.getSmartspaceHorizontalMargin(context)
constraintSet.apply {
// migrate addDateWeatherView, addWeatherView from KeyguardClockSwitchController
constrainHeight(sharedR.id.date_smartspace_view, ConstraintSet.WRAP_CONTENT)
@@ -124,7 +125,7 @@
ConstraintSet.START,
ConstraintSet.PARENT_ID,
ConstraintSet.START,
- horizontalPaddingStart,
+ dateWeatherPaddingStart,
)
// migrate addSmartspaceView from KeyguardClockSwitchController
@@ -135,7 +136,7 @@
ConstraintSet.START,
ConstraintSet.PARENT_ID,
ConstraintSet.START,
- horizontalPaddingStart,
+ smartspaceHorizontalPadding,
)
connect(
sharedR.id.bc_smartspace_view,
@@ -143,7 +144,7 @@
if (keyguardSmartspaceViewModel.isShadeLayoutWide.value) R.id.split_shade_guideline
else ConstraintSet.PARENT_ID,
ConstraintSet.END,
- horizontalPaddingEnd,
+ smartspaceHorizontalPadding,
)
if (keyguardClockViewModel.hasCustomWeatherDataDisplay.value) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
index 0280d17..15b696e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
@@ -62,12 +62,12 @@
overrideClockSize.value = clockSize
}
- fun getSmartspaceStartPadding(context: Context): Int {
- return KeyguardSmartspaceViewModel.getSmartspaceStartMargin(context)
+ fun getDateWeatherStartPadding(context: Context): Int {
+ return KeyguardSmartspaceViewModel.getDateWeatherStartMargin(context)
}
- fun getSmartspaceEndPadding(context: Context): Int {
- return KeyguardSmartspaceViewModel.getSmartspaceEndMargin(context)
+ fun getDateWeatherEndPadding(context: Context): Int {
+ return KeyguardSmartspaceViewModel.getDateWeatherEndMargin(context)
}
/*
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt
index 3266dc4..5ee80a7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt
@@ -94,14 +94,19 @@
val isShadeLayoutWide: StateFlow<Boolean> = shadeInteractor.isShadeLayoutWide
companion object {
- fun getSmartspaceStartMargin(context: Context): Int {
+ fun getDateWeatherStartMargin(context: Context): Int {
return context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_start) +
context.resources.getDimensionPixelSize(customR.dimen.status_view_margin_horizontal)
}
- fun getSmartspaceEndMargin(context: Context): Int {
+ fun getDateWeatherEndMargin(context: Context): Int {
return context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_end) +
context.resources.getDimensionPixelSize(customR.dimen.status_view_margin_horizontal)
}
+
+ fun getSmartspaceHorizontalMargin(context: Context): Int {
+ return context.resources.getDimensionPixelSize(R.dimen.smartspace_padding_horizontal) +
+ context.resources.getDimensionPixelSize(customR.dimen.status_view_margin_horizontal)
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS b/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
index 95b8fa7..4976d94 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
@@ -1,3 +1,3 @@
# Bug component: 1280508
-# Files in this directory should still be reviewed by a member of SystemUI team
+asapperstein@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
index 2f0e129..f8d317a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
@@ -19,12 +19,12 @@
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
-import androidx.annotation.AttrRes
+import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
-import com.android.systemui.res.R
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.TintedIcon
+import com.android.systemui.res.R
import com.android.systemui.temporarydisplay.chipbar.ChipbarInfo.Companion.DEFAULT_ICON_TINT
/** Utility methods for media tap-to-transfer. */
@@ -108,7 +108,7 @@
data class IconInfo(
val contentDescription: ContentDescription,
val icon: MediaTttIcon,
- @AttrRes val tint: Int?,
+ @ColorRes val tint: Int?,
/**
* True if [drawable] is the app's icon, and false if [drawable] is some generic default icon.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
index 2fda201..d33ad8f 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
@@ -122,21 +122,20 @@
final Intent launchingIntent = getIntent();
mReviewGrantedConsentRequired = launchingIntent.getBooleanExtra(
EXTRA_USER_REVIEW_GRANTED_CONSENT, false);
- if (com.android.systemui.Flags.mediaProjectionRequestAttributionFix()) {
- mPackageName = getLaunchedFromPackage();
- } else {
- mPackageName = getCallingPackage();
- }
- // This activity is launched directly by an app, or system server. System server provides
- // the package name through the intent if so.
- if (mPackageName == null || (
- com.android.systemui.Flags.mediaProjectionRequestAttributionFix()
- && getCallingPackage() == null)) {
+ // The original requester of this activity start
+ mPackageName = getLaunchedFromPackage();
+
+ // This activity is launched directly by using startActivity(),
+ // thus getCallingPackage() will be null.
+ if (getCallingPackage() == null) {
+ // System server provides the package name through the intent if so and is able to get
+ // the result back. Other applications can't.
if (launchingIntent.hasExtra(EXTRA_PACKAGE_REUSING_GRANTED_CONSENT)) {
mPackageName = launchingIntent.getStringExtra(
EXTRA_PACKAGE_REUSING_GRANTED_CONSENT);
} else {
+ // The activity was not launched for result, we abort here
finishAsCancelled();
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
index 2d00150..138ac86 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
@@ -12,7 +12,6 @@
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
import com.android.internal.util.LatencyTracker
-import com.android.settingslib.Utils
import com.android.systemui.navigationbar.gestural.BackPanelController.DelayedOnAnimationEndListener
private const val TAG = "BackPanel"
@@ -156,23 +155,21 @@
Configuration.UI_MODE_NIGHT_YES
arrowPaint.color =
- Utils.getColorAttrDefaultColor(
- context,
+ context.getColor(
if (isDeviceInNightTheme) {
- com.android.internal.R.attr.materialColorOnSecondaryContainer
+ com.android.internal.R.color.materialColorOnSecondaryContainer
} else {
- com.android.internal.R.attr.materialColorOnSecondaryFixed
- },
+ com.android.internal.R.color.materialColorOnSecondaryFixed
+ }
)
arrowBackgroundPaint.color =
- Utils.getColorAttrDefaultColor(
- context,
+ context.getColor(
if (isDeviceInNightTheme) {
- com.android.internal.R.attr.materialColorSecondaryContainer
+ com.android.internal.R.color.materialColorSecondaryContainer
} else {
- com.android.internal.R.attr.materialColorSecondaryFixedDim
- },
+ com.android.internal.R.color.materialColorSecondaryFixedDim
+ }
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt
index b26ae6c..f53b6cd 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogV2.kt
@@ -40,8 +40,8 @@
import androidx.core.view.ViewCompat
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
import com.android.settingslib.Utils
-import com.android.systemui.res.R
import com.android.systemui.animation.ViewHierarchyAnimator
+import com.android.systemui.res.R
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.util.maybeForceFullscreen
import java.lang.ref.WeakReference
@@ -347,16 +347,16 @@
private fun getForegroundColor(active: Boolean) =
Utils.getColorAttrDefaultColor(
context,
- if (active) com.android.internal.R.attr.materialColorOnPrimaryFixed
- else com.android.internal.R.attr.materialColorOnSurface
+ if (active) com.android.internal.R.color.materialColorOnPrimaryFixed
+ else com.android.internal.R.color.materialColorOnSurface,
)
@ColorInt
private fun getBackgroundColor(active: Boolean) =
Utils.getColorAttrDefaultColor(
context,
- if (active) com.android.internal.R.attr.materialColorPrimaryFixed
- else com.android.internal.R.attr.materialColorSurfaceContainerHigh
+ if (active) com.android.internal.R.color.materialColorPrimaryFixed
+ else com.android.internal.R.color.materialColorSurfaceContainerHigh,
)
private fun getMutableDrawable(@DrawableRes resId: Int) = context.getDrawable(resId)!!.mutate()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
index ba3357c..7c7f48e0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
@@ -19,6 +19,8 @@
import android.content.res.Resources;
import android.provider.Settings;
+import androidx.annotation.NonNull;
+
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.res.R;
@@ -80,6 +82,12 @@
void addTile(ComponentName tile);
/**
+ * Click on a tile. Used by external commands
+ * @param tile the component name of the {@link android.service.quicksettings.TileService}
+ */
+ void clickTile(@NonNull ComponentName tile);
+
+ /**
* Adds a custom tile to the set of current tiles.
* @param tile the component name of the {@link android.service.quicksettings.TileService}
* @param end if true, the tile will be added at the end. If false, at the beginning.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt
index 0d464f5..dc3b582 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSHostAdapter.kt
@@ -19,11 +19,13 @@
import android.content.ComponentName
import android.content.Context
import androidx.annotation.GuardedBy
+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.dump.DumpManager
import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.qs.external.TileServiceRequestController
+import com.android.systemui.qs.flags.QsInCompose
import com.android.systemui.qs.pipeline.data.repository.TileSpecRepository.Companion.POSITION_AT_END
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository
@@ -32,7 +34,6 @@
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
-import com.android.app.tracing.coroutines.launchTraced as launch
/**
* Adapter to determine what real class to use for classes that depend on [QSHost].
@@ -135,4 +136,12 @@
override fun indexOf(tileSpec: String): Int {
return specs.indexOf(tileSpec)
}
+
+ override fun clickTile(tile: ComponentName) {
+ if (QsInCompose.isUnexpectedlyInLegacyMode()) {
+ return
+ }
+ val spec = TileSpec.create(tile)
+ interactor.currentTiles.value.firstOrNull { it.spec == spec }?.tile?.click(null)
+ }
}
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 9dc21fb..4cf6aab 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -47,7 +47,6 @@
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.verticalScroll
@@ -248,7 +247,7 @@
PlatformTheme(isDarkTheme = true) {
ProvideShortcutHelperIndication(interactionsConfig = interactionsConfig()) {
AnimatedVisibility(
- visible = viewModel.isQsVisible,
+ visible = viewModel.isQsVisibleAndAnyShadeExpanded,
modifier =
Modifier.graphicsLayer { alpha = viewModel.viewAlpha }
// Clipping before translation to match QSContainerImpl.onDraw
@@ -326,9 +325,15 @@
}
SceneTransitionLayout(state = sceneState, modifier = Modifier.fillMaxSize()) {
- scene(QuickSettings) { QuickSettingsElement() }
+ scene(QuickSettings) {
+ LaunchedEffect(Unit) { viewModel.onQSOpen() }
+ QuickSettingsElement()
+ }
- scene(QuickQuickSettings) { QuickQuickSettingsElement() }
+ scene(QuickQuickSettings) {
+ LaunchedEffect(Unit) { viewModel.onQQSOpen() }
+ QuickQuickSettingsElement()
+ }
}
}
@@ -709,12 +714,7 @@
GridAnchor()
TileGrid(
viewModel = containerViewModel.tileGridViewModel,
- modifier =
- Modifier.fillMaxWidth()
- .heightIn(
- max =
- QuickSettingsShade.Dimensions.GridMaxHeight
- ),
+ modifier = Modifier.fillMaxWidth(),
)
}
}
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 02498d6..07ceb64 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
@@ -28,6 +28,7 @@
import androidx.lifecycle.LifecycleCoroutineScope
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.internal.logging.UiEventLogger
import com.android.keyguard.BouncerPanelExpansionCalculator
import com.android.systemui.Dumpable
import com.android.systemui.animation.ShadeInterpolation
@@ -51,6 +52,7 @@
import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.FooterActionsController
+import com.android.systemui.qs.QSEvent
import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeLog
import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeModule
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
@@ -62,6 +64,7 @@
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.LargeScreenHeaderHelper
import com.android.systemui.shade.ShadeDisplayAware
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
@@ -101,6 +104,7 @@
DisableFlagsInteractor: DisableFlagsInteractor,
keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val largeScreenShadeInterpolator: LargeScreenShadeInterpolator,
+ private val shadeInteractor: ShadeInteractor,
@ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
private val largeScreenHeaderHelper: LargeScreenHeaderHelper,
private val squishinessInteractor: TileSquishinessInteractor,
@@ -111,6 +115,7 @@
@Named(QUICK_QS_PANEL) val qqsMediaHost: MediaHost,
@Named(QS_PANEL) val qsMediaHost: MediaHost,
@Named(QSFragmentComposeModule.QS_USING_MEDIA_PLAYER) private val usingMedia: Boolean,
+ private val uiEventLogger: UiEventLogger,
@Assisted private val lifecycleScope: LifecycleCoroutineScope,
) : Dumpable, ExclusiveActivatable() {
@@ -129,6 +134,9 @@
var isQsVisible by mutableStateOf(false)
+ val isQsVisibleAndAnyShadeExpanded: Boolean
+ get() = anyShadeExpanded && isQsVisible
+
// This can only be negative if undefined (in which case it will be -1f), else it will be
// in [0, 1]. In some cases, it could be set back to -1f internally to indicate that it's
// different to every value in [0, 1].
@@ -429,6 +437,12 @@
),
)
+ private val anyShadeExpanded by
+ hydrator.hydratedStateOf(
+ traceName = "anyShadeExpanded",
+ source = shadeInteractor.isAnyExpanded,
+ )
+
fun applyNewQsScrollerBounds(left: Float, top: Float, right: Float, bottom: Float) {
if (usingMedia) {
qsMediaHost.currentClipping.set(
@@ -444,6 +458,14 @@
falsingInteractor.isFalseTouch(Classifier.QS_SWIPE_NESTED)
}
+ fun onQQSOpen() {
+ uiEventLogger.log(QSEvent.QQS_PANEL_EXPANDED)
+ }
+
+ fun onQSOpen() {
+ uiEventLogger.log(QSEvent.QS_PANEL_EXPANDED)
+ }
+
override suspend fun onActivated(): Nothing {
initMediaHosts() // init regardless of using media (same as current QS).
coroutineScope {
@@ -503,6 +525,8 @@
printSection("Quick Settings state") {
println("isQSExpanded", isQsExpanded)
println("isQSVisible", isQsVisible)
+ println("anyShadeExpanded", anyShadeExpanded)
+ println("isQSVisibleAndAnyShadeExpanded", isQsVisibleAndAnyShadeExpanded)
println("isQSEnabled", isQsEnabled)
println("isCustomizing", containerViewModel.editModeViewModel.isEditing.value)
println("inFirstPage", inFirstPage)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index 94b8a3a..1205c87 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -16,55 +16,10 @@
package com.android.systemui.qs.dagger;
-import com.android.systemui.media.dagger.MediaModule;
-import com.android.systemui.qs.ReduceBrightColorsController;
-import com.android.systemui.qs.ReduceBrightColorsControllerImpl;
-import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeModule;
-import com.android.systemui.qs.external.QSExternalModule;
-import com.android.systemui.qs.panels.dagger.PanelsModule;
-import com.android.systemui.qs.pipeline.dagger.QSPipelineModule;
-import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.qs.tiles.di.QSTilesModule;
-import com.android.systemui.qs.ui.adapter.QSSceneAdapter;
-import com.android.systemui.qs.ui.adapter.QSSceneAdapterImpl;
-
-import java.util.Map;
-
-import dagger.Binds;
import dagger.Module;
-import dagger.multibindings.Multibinds;
/**
- * Module for QS dependencies
+ * Module for QS dependencies for AOSP inclusion
*/
-@Module(subcomponents = {QSFragmentComponent.class, QSSceneComponent.class},
- includes = {
- MediaModule.class,
- PanelsModule.class,
- QSFragmentComposeModule.class,
- QSExternalModule.class,
- QSFlagsModule.class,
- QSHostModule.class,
- QSPipelineModule.class,
- QSTilesModule.class,
- }
-)
-public interface QSModule {
-
- /**
- * A map of internal QS tiles. Ensures that this can be injected even if
- * it is empty
- */
- @Multibinds
- Map<String, QSTileImpl<?>> tileMap();
-
- @Binds
- QSSceneAdapter bindsQsSceneInteractor(QSSceneAdapterImpl impl);
-
- /**
- * Dims the screen
- */
- @Binds
- ReduceBrightColorsController bindReduceBrightColorsController(
- ReduceBrightColorsControllerImpl impl);
-}
+@Module(includes = { QSModuleBase.class})
+public interface QSModule { }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt
new file mode 100644
index 0000000..3fd8768
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt
@@ -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.systemui.qs.dagger
+
+import com.android.systemui.media.dagger.MediaModule
+import com.android.systemui.qs.ReduceBrightColorsController
+import com.android.systemui.qs.ReduceBrightColorsControllerImpl
+import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeModule
+import com.android.systemui.qs.external.QSExternalModule
+import com.android.systemui.qs.panels.dagger.PanelsModule
+import com.android.systemui.qs.pipeline.dagger.QSPipelineModule
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tiles.di.QSTilesModule
+import com.android.systemui.qs.ui.adapter.QSSceneAdapter
+import com.android.systemui.qs.ui.adapter.QSSceneAdapterImpl
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.Multibinds
+
+/**
+ * QS Module for shared dependencies between AOSP and variants. Include this module in more
+ * specialized modules (like [QSModule]) and do not include this module directly in SystemUI modules
+ */
+@Module(
+ subcomponents = [QSFragmentComponent::class, QSSceneComponent::class],
+ includes =
+ [
+ MediaModule::class,
+ PanelsModule::class,
+ QSFragmentComposeModule::class,
+ QSExternalModule::class,
+ QSFlagsModule::class,
+ QSHostModule::class,
+ QSPipelineModule::class,
+ QSTilesModule::class,
+ ],
+)
+interface QSModuleBase {
+
+ /** A map of internal QS tiles. Ensures that this can be injected even if it is empty */
+ @Multibinds fun tileMap(): Map<String?, QSTileImpl<*>?>?
+
+ @Binds fun bindsQsSceneAdapter(impl: QSSceneAdapterImpl?): QSSceneAdapter?
+
+ /** Dims the screen */
+ @Binds
+ fun bindReduceBrightColorsController(
+ impl: ReduceBrightColorsControllerImpl?
+ ): ReduceBrightColorsController?
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
index 8ef6375..cc87206 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt
@@ -23,12 +23,12 @@
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.LifecycleOwner
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.settingslib.Utils
import com.android.systemui.animation.Expandable
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.globalactions.GlobalActionsDialogLite
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
@@ -38,6 +38,7 @@
import com.android.systemui.qs.footer.domain.model.SecurityButtonConfig
import com.android.systemui.res.R
import com.android.systemui.shade.ShadeDisplayAware
+import com.android.systemui.shade.shared.flag.DualShade
import com.android.systemui.util.icuMessageFormat
import javax.inject.Inject
import javax.inject.Named
@@ -54,7 +55,6 @@
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.isActive
-import com.android.app.tracing.coroutines.launchTraced as launch
private const val TAG = "FooterActionsViewModel"
@@ -113,7 +113,7 @@
class Factory
@Inject
constructor(
- @ShadeDisplayAware private val context: Context,
+ @ShadeDisplayAware private val context: Context,
private val falsingManager: FalsingManager,
private val footerActionsInteractor: FooterActionsInteractor,
private val globalActionsDialogLiteProvider: Provider<GlobalActionsDialogLite>,
@@ -211,7 +211,7 @@
false /* if the dismiss should be deferred */
},
null /* cancelAction */,
- true /* afterKeyguardGone */
+ true, /* afterKeyguardGone */
)
}
@@ -269,29 +269,7 @@
.distinctUntilChanged()
val userSwitcher =
- footerActionsInteractor.userSwitcherStatus
- .map { userSwitcherStatus ->
- when (userSwitcherStatus) {
- UserSwitcherStatusModel.Disabled -> null
- is UserSwitcherStatusModel.Enabled -> {
- if (userSwitcherStatus.currentUserImage == null) {
- Log.e(
- TAG,
- "Skipped the addition of user switcher button because " +
- "currentUserImage is missing",
- )
- return@map null
- }
-
- userSwitcherButtonViewModel(
- qsThemedContext,
- userSwitcherStatus,
- ::onUserSwitcherClicked
- )
- }
- }
- }
- .distinctUntilChanged()
+ userSwitcherViewModel(qsThemedContext, footerActionsInteractor, ::onUserSwitcherClicked)
val settings = settingsButtonViewModel(qsThemedContext, ::onSettingsButtonClicked)
val power =
@@ -311,6 +289,36 @@
)
}
+fun userSwitcherViewModel(
+ themedContext: Context,
+ footerActionsInteractor: FooterActionsInteractor,
+ onUserSwitcherClicked: (Expandable) -> Unit,
+): Flow<FooterActionsButtonViewModel?> {
+ return footerActionsInteractor.userSwitcherStatus
+ .map { userSwitcherStatus ->
+ when (userSwitcherStatus) {
+ UserSwitcherStatusModel.Disabled -> null
+ is UserSwitcherStatusModel.Enabled -> {
+ if (userSwitcherStatus.currentUserImage == null) {
+ Log.e(
+ TAG,
+ "Skipped the addition of user switcher button because " +
+ "currentUserImage is missing",
+ )
+ return@map null
+ }
+
+ userSwitcherButtonViewModel(
+ themedContext,
+ userSwitcherStatus,
+ onUserSwitcherClicked,
+ )
+ }
+ }
+ }
+ .distinctUntilChanged()
+}
+
fun securityButtonViewModel(
config: SecurityButtonConfig,
onSecurityButtonClicked: (Context, Expandable) -> Unit,
@@ -369,7 +377,7 @@
private fun userSwitcherContentDescription(
qsThemedContext: Context,
- currentUser: String?
+ currentUser: String?,
): String? {
return currentUser?.let { user ->
qsThemedContext.getString(R.string.accessibility_quick_settings_user, user)
@@ -384,13 +392,9 @@
id = R.id.settings_button_container,
Icon.Resource(
R.drawable.ic_settings,
- ContentDescription.Resource(R.string.accessibility_quick_settings_settings)
+ ContentDescription.Resource(R.string.accessibility_quick_settings_settings),
),
- iconTint =
- Utils.getColorAttrDefaultColor(
- qsThemedContext,
- R.attr.onShadeInactiveVariant,
- ),
+ iconTint = Utils.getColorAttrDefaultColor(qsThemedContext, R.attr.onShadeInactiveVariant),
backgroundColor = R.attr.shadeInactive,
onSettingsButtonClicked,
)
@@ -404,14 +408,14 @@
id = R.id.pm_lite,
Icon.Resource(
android.R.drawable.ic_lock_power_off,
- ContentDescription.Resource(R.string.accessibility_quick_settings_power_menu)
+ ContentDescription.Resource(R.string.accessibility_quick_settings_power_menu),
),
iconTint =
Utils.getColorAttrDefaultColor(
qsThemedContext,
- R.attr.onShadeActive,
+ if (DualShade.isEnabled) R.attr.onShadeInactiveVariant else R.attr.onShadeActive,
),
- backgroundColor = R.attr.shadeActive,
+ backgroundColor = if (DualShade.isEnabled) R.attr.shadeInactive else R.attr.shadeActive,
onPowerButtonClicked,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
index ead38f3..ef45ae76 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
@@ -209,7 +209,7 @@
// TODO(b/250618218): Remove this method once we know the root cause of b/250618218.
fun logTileBackgroundColorUpdateIfInternetTile(
- tileSpec: String,
+ tileSpec: String?,
state: Int,
disabledByPolicy: Boolean,
color: Int,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
index 1f55ac7..f4bf53ca 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
@@ -21,8 +21,6 @@
import com.android.systemui.log.LogBufferFactory
import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepository
import com.android.systemui.qs.panels.data.repository.DefaultLargeTilesRepositoryImpl
-import com.android.systemui.qs.panels.data.repository.GridLayoutTypeRepository
-import com.android.systemui.qs.panels.data.repository.GridLayoutTypeRepositoryImpl
import com.android.systemui.qs.panels.domain.interactor.EditTilesResetInteractor
import com.android.systemui.qs.panels.domain.interactor.SizedTilesResetInteractor
import com.android.systemui.qs.panels.shared.model.GridLayoutType
@@ -49,9 +47,6 @@
): DefaultLargeTilesRepository
@Binds
- fun bindGridLayoutTypeRepository(impl: GridLayoutTypeRepositoryImpl): GridLayoutTypeRepository
-
- @Binds
fun bindEditTilesResetInteractor(impl: SizedTilesResetInteractor): EditTilesResetInteractor
@Binds fun bindIconTilesViewModel(impl: IconTilesViewModelImpl): IconTilesViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepository.kt
index 47c4ffd..f17abe8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepository.kt
@@ -17,28 +17,14 @@
package com.android.systemui.qs.panels.data.repository
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.panels.shared.model.GridLayoutType
+import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType
import com.android.systemui.qs.panels.shared.model.PaginatedGridLayoutType
import javax.inject.Inject
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
-
-interface GridLayoutTypeRepository {
- val layout: StateFlow<GridLayoutType>
-
- fun setLayout(type: GridLayoutType)
-}
+import kotlinx.coroutines.flow.flowOf
@SysUISingleton
-class GridLayoutTypeRepositoryImpl @Inject constructor() : GridLayoutTypeRepository {
- private val _layout: MutableStateFlow<GridLayoutType> =
- MutableStateFlow(PaginatedGridLayoutType)
- override val layout = _layout.asStateFlow()
+class GridLayoutTypeRepository @Inject constructor() {
+ val defaultLayoutType = flowOf(PaginatedGridLayoutType)
- override fun setLayout(type: GridLayoutType) {
- if (_layout.value != type) {
- _layout.value = type
- }
- }
+ val dualShadeLayoutType = flowOf(InfiniteGridLayoutType)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractor.kt
index 4af1b22..e493cbe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractor.kt
@@ -19,14 +19,23 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.panels.data.repository.GridLayoutTypeRepository
import com.android.systemui.qs.panels.shared.model.GridLayoutType
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
+import com.android.systemui.shade.shared.model.ShadeMode
import javax.inject.Inject
-import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flatMapLatest
@SysUISingleton
-class GridLayoutTypeInteractor @Inject constructor(private val repo: GridLayoutTypeRepository) {
- val layout: StateFlow<GridLayoutType> = repo.layout
-
- fun setLayoutType(type: GridLayoutType) {
- repo.setLayout(type)
- }
+@OptIn(ExperimentalCoroutinesApi::class)
+class GridLayoutTypeInteractor
+@Inject
+constructor(private val repo: GridLayoutTypeRepository, shadeModeInteractor: ShadeModeInteractor) {
+ val layout: Flow<GridLayoutType> =
+ shadeModeInteractor.shadeMode.flatMapLatest { shadeMode ->
+ when (shadeMode) {
+ is ShadeMode.Dual -> repo.dualShadeLayoutType
+ else -> repo.defaultLayoutType
+ }
+ }
}
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 b6dbf4d..39408d3 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
@@ -49,9 +49,10 @@
import com.android.systemui.qs.panels.dagger.PaginatedBaseLayoutType
import com.android.systemui.qs.panels.ui.compose.Dimensions.FooterHeight
import com.android.systemui.qs.panels.ui.compose.Dimensions.InterPageSpacing
-import com.android.systemui.qs.panels.ui.viewmodel.EditModeButtonViewModel
+import com.android.systemui.qs.panels.ui.compose.toolbar.EditModeButton
import com.android.systemui.qs.panels.ui.viewmodel.PaginatedGridViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.toolbar.EditModeButtonViewModel
import com.android.systemui.qs.ui.compose.borderOnFocus
import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
index c6141a1..a05747d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
@@ -28,6 +28,7 @@
import androidx.compose.foundation.LocalOverscrollFactory
import androidx.compose.foundation.background
import androidx.compose.foundation.border
+import androidx.compose.foundation.clipScrollableContainer
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Box
@@ -138,7 +139,6 @@
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.shared.model.groupAndSort
import com.android.systemui.res.R
-import kotlin.math.max
import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
@@ -148,8 +148,9 @@
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun EditModeTopBar(onStopEditing: () -> Unit, onReset: (() -> Unit)?) {
+
TopAppBar(
- colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Black),
+ colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent),
title = { Text(text = stringResource(id = R.string.qs_edit)) },
navigationIcon = {
IconButton(onClick = onStopEditing) {
@@ -209,7 +210,15 @@
Column(
verticalArrangement =
spacedBy(dimensionResource(id = R.dimen.qs_label_container_margin)),
- modifier = modifier.fillMaxSize().verticalScroll(scrollState).padding(innerPadding),
+ modifier =
+ modifier
+ .fillMaxSize()
+ // Apply top padding before the scroll so the scrollable doesn't show under
+ // the
+ // top bar
+ .padding(top = innerPadding.calculateTopPadding())
+ .clipScrollableContainer(Orientation.Vertical)
+ .verticalScroll(scrollState),
) {
AnimatedContent(
targetState = listState.dragInProgress,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditModeButton.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/toolbar/EditModeButton.kt
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditModeButton.kt
rename to packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/toolbar/EditModeButton.kt
index c2764f9..85db952 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditModeButton.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/toolbar/EditModeButton.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.qs.panels.ui.compose
+package com.android.systemui.qs.panels.ui.compose.toolbar
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -30,7 +30,7 @@
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.android.systemui.lifecycle.rememberViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.EditModeButtonViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.toolbar.EditModeButtonViewModel
import com.android.systemui.qs.ui.compose.borderOnFocus
import com.android.systemui.res.R
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/toolbar/Toolbar.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/toolbar/Toolbar.kt
new file mode 100644
index 0000000..37fa9e7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/toolbar/Toolbar.kt
@@ -0,0 +1,54 @@
+/*
+ * 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.panels.ui.compose.toolbar
+
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.requiredHeight
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import com.android.systemui.compose.modifiers.sysuiResTag
+import com.android.systemui.lifecycle.rememberViewModel
+import com.android.systemui.qs.footer.ui.compose.IconButton
+import com.android.systemui.qs.panels.ui.viewmodel.toolbar.ToolbarViewModel
+
+@Composable
+fun Toolbar(toolbarViewModelFactory: ToolbarViewModel.Factory, modifier: Modifier = Modifier) {
+ val viewModel = rememberViewModel("Toolbar") { toolbarViewModelFactory.create() }
+
+ Row(
+ modifier = modifier.fillMaxWidth().requiredHeight(48.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ viewModel.userSwitcherViewModel?.let {
+ IconButton(it, Modifier.sysuiResTag("multi_user_switch"))
+ }
+
+ EditModeButton(viewModel.editModeButtonViewModelFactory)
+
+ IconButton(
+ viewModel.settingsButtonViewModel,
+ Modifier.sysuiResTag("settings_button_container"),
+ )
+
+ Spacer(modifier = Modifier.weight(1f))
+ IconButton(viewModel.powerButtonViewModel, Modifier.sysuiResTag("pm_lite"))
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
index faab696..f7ed1ad 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
@@ -18,9 +18,14 @@
import android.content.Context
import androidx.compose.ui.util.fastMap
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListUpdateCallback
+import com.android.internal.logging.UiEventLogger
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.dagger.qualifiers.Background
+import com.android.systemui.qs.QSEditEvent
import com.android.systemui.qs.panels.domain.interactor.EditTilesListInteractor
import com.android.systemui.qs.panels.domain.interactor.GridLayoutTypeInteractor
import com.android.systemui.qs.panels.domain.interactor.TilesAvailabilityInteractor
@@ -30,10 +35,12 @@
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor.Companion.POSITION_AT_END
import com.android.systemui.qs.pipeline.domain.interactor.MinimumTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.pipeline.shared.metricSpec
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.util.kotlin.emitOnStart
import javax.inject.Inject
import javax.inject.Named
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
@@ -45,6 +52,7 @@
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
@SysUISingleton
@OptIn(ExperimentalCoroutinesApi::class)
@@ -55,10 +63,12 @@
private val currentTilesInteractor: CurrentTilesInteractor,
private val tilesAvailabilityInteractor: TilesAvailabilityInteractor,
private val minTilesInteractor: MinimumTilesInteractor,
+ private val uiEventLogger: UiEventLogger,
@ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor,
- @ShadeDisplayAware private val context: Context,
+ @ShadeDisplayAware private val context: Context,
@Named("Default") private val defaultGridLayout: GridLayout,
@Application private val applicationScope: CoroutineScope,
+ @Background private val bgDispatcher: CoroutineDispatcher,
gridLayoutTypeInteractor: GridLayoutTypeInteractor,
gridLayoutMap: Map<GridLayoutType, @JvmSuppressWildcards GridLayout>,
) {
@@ -149,11 +159,17 @@
/** @see isEditing */
fun startEditing() {
+ if (!isEditing.value) {
+ uiEventLogger.log(QSEditEvent.QS_EDIT_OPEN)
+ }
_isEditing.value = true
}
/** @see isEditing */
fun stopEditing() {
+ if (isEditing.value) {
+ uiEventLogger.log(QSEditEvent.QS_EDIT_CLOSED)
+ }
_isEditing.value = false
}
@@ -164,6 +180,7 @@
fun addTile(tileSpec: TileSpec, position: Int = POSITION_AT_END) {
val specs = currentTilesInteractor.currentTilesSpecs.toMutableList()
val currentPosition = specs.indexOf(tileSpec)
+ val moved = currentPosition != -1
if (currentPosition != -1) {
// No operation needed if the element is already in the list at the right position
@@ -179,6 +196,12 @@
} else {
specs.add(tileSpec)
}
+ uiEventLogger.logWithPosition(
+ if (moved) QSEditEvent.QS_EDIT_MOVE else QSEditEvent.QS_EDIT_ADD,
+ /* uid= */ 0,
+ /* packageName= */ tileSpec.metricSpec,
+ if (moved && position == POSITION_AT_END) specs.size - 1 else position,
+ )
// Setting the new tiles as one operation to avoid UI jank with tiles disappearing and
// reappearing
@@ -187,10 +210,80 @@
/** Immediately removes [tileSpec] from the current tiles. */
fun removeTile(tileSpec: TileSpec) {
+ uiEventLogger.log(
+ QSEditEvent.QS_EDIT_REMOVE,
+ /* uid= */ 0,
+ /* packageName= */ tileSpec.metricSpec,
+ )
currentTilesInteractor.removeTiles(listOf(tileSpec))
}
fun setTiles(tileSpecs: List<TileSpec>) {
+ val currentTiles = currentTilesInteractor.currentTilesSpecs
currentTilesInteractor.setTiles(tileSpecs)
+ applicationScope.launch(bgDispatcher) {
+ calculateDiffsAndEmitUiEvents(currentTiles, tileSpecs)
+ }
+ }
+
+ private fun calculateDiffsAndEmitUiEvents(
+ currentTiles: List<TileSpec>,
+ newTiles: List<TileSpec>,
+ ) {
+ val listDiff = DiffUtil.calculateDiff(DiffCallback(currentTiles, newTiles))
+ listDiff.dispatchUpdatesTo(
+ object : ListUpdateCallback {
+ override fun onInserted(position: Int, count: Int) {
+ newTiles.getOrNull(position)?.let {
+ uiEventLogger.logWithPosition(
+ QSEditEvent.QS_EDIT_ADD,
+ /* uid= */ 0,
+ /* packageName= */ it.metricSpec,
+ position,
+ )
+ }
+ }
+
+ override fun onRemoved(position: Int, count: Int) {
+ currentTiles.getOrNull(position)?.let {
+ uiEventLogger.log(QSEditEvent.QS_EDIT_REMOVE, 0, it.metricSpec)
+ }
+ }
+
+ override fun onMoved(fromPosition: Int, toPosition: Int) {
+ currentTiles.getOrNull(fromPosition)?.let {
+ uiEventLogger.logWithPosition(
+ QSEditEvent.QS_EDIT_MOVE,
+ /* uid= */ 0,
+ /* packageName= */ it.metricSpec,
+ toPosition,
+ )
+ }
+ }
+
+ override fun onChanged(position: Int, count: Int, payload: Any?) {}
+ }
+ )
+ }
+}
+
+private class DiffCallback(
+ private val currentList: List<TileSpec>,
+ private val newList: List<TileSpec>,
+) : DiffUtil.Callback() {
+ override fun getOldListSize(): Int {
+ return currentList.size
+ }
+
+ override fun getNewListSize(): Int {
+ return newList.size
+ }
+
+ override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
+ return currentList[oldItemPosition] == newList[newItemPosition]
+ }
+
+ override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
+ return areItemsTheSame(oldItemPosition, newItemPosition)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
index 4a18872..3fcb2ab 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
@@ -24,6 +24,7 @@
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QS
import com.android.systemui.qs.panels.domain.interactor.PaginatedGridInteractor
+import com.android.systemui.qs.panels.ui.viewmodel.toolbar.EditModeButtonViewModel
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.awaitCancellation
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/EditModeButtonViewModel.kt
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/EditModeButtonViewModel.kt
index b033473..f606218 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/EditModeButtonViewModel.kt
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-package com.android.systemui.qs.panels.ui.viewmodel
+package com.android.systemui.qs.panels.ui.viewmodel.toolbar
import com.android.systemui.classifier.domain.interactor.FalsingInteractor
import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.qs.panels.ui.viewmodel.EditModeViewModel
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/ToolbarViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/ToolbarViewModel.kt
new file mode 100644
index 0000000..0fde855
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/ToolbarViewModel.kt
@@ -0,0 +1,111 @@
+/*
+ * 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.panels.ui.viewmodel.toolbar
+
+import android.content.Context
+import android.view.ContextThemeWrapper
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import com.android.systemui.animation.Expandable
+import com.android.systemui.classifier.domain.interactor.FalsingInteractor
+import com.android.systemui.classifier.domain.interactor.runIfNotFalseTap
+import com.android.systemui.globalactions.GlobalActionsDialogLite
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.Hydrator
+import com.android.systemui.qs.footer.domain.interactor.FooterActionsInteractor
+import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsButtonViewModel
+import com.android.systemui.qs.footer.ui.viewmodel.powerButtonViewModel
+import com.android.systemui.qs.footer.ui.viewmodel.settingsButtonViewModel
+import com.android.systemui.qs.footer.ui.viewmodel.userSwitcherViewModel
+import com.android.systemui.res.R
+import com.android.systemui.shade.ShadeDisplayAware
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import javax.inject.Provider
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
+
+class ToolbarViewModel
+@AssistedInject
+constructor(
+ val editModeButtonViewModelFactory: EditModeButtonViewModel.Factory,
+ private val footerActionsInteractor: FooterActionsInteractor,
+ private val globalActionsDialogLiteProvider: Provider<GlobalActionsDialogLite>,
+ private val falsingInteractor: FalsingInteractor,
+ @ShadeDisplayAware appContext: Context,
+) : ExclusiveActivatable() {
+ private val qsThemedContext =
+ ContextThemeWrapper(appContext, R.style.Theme_SystemUI_QuickSettings)
+ private val hydrator = Hydrator("ToolbarViewModel.hydrator")
+
+ val powerButtonViewModel = powerButtonViewModel(qsThemedContext, ::onPowerButtonClicked)
+
+ val settingsButtonViewModel =
+ settingsButtonViewModel(qsThemedContext, ::onSettingsButtonClicked)
+
+ val userSwitcherViewModel: FooterActionsButtonViewModel? by
+ hydrator.hydratedStateOf(
+ traceName = "userSwitcherViewModel",
+ initialValue = null,
+ source =
+ userSwitcherViewModel(
+ qsThemedContext,
+ footerActionsInteractor,
+ ::onUserSwitcherClicked,
+ ),
+ )
+
+ override suspend fun onActivated(): Nothing {
+ coroutineScope {
+ launch {
+ try {
+ globalActionsDialogLite = globalActionsDialogLiteProvider.get()
+ awaitCancellation()
+ } finally {
+ globalActionsDialogLite?.destroy()
+ }
+ }
+ launch { hydrator.activate() }
+ awaitCancellation()
+ }
+ }
+
+ private var globalActionsDialogLite: GlobalActionsDialogLite? by mutableStateOf(null)
+
+ private fun onPowerButtonClicked(expandable: Expandable) {
+ falsingInteractor.runIfNotFalseTap {
+ globalActionsDialogLite?.let {
+ footerActionsInteractor.showPowerMenuDialog(it, expandable)
+ }
+ }
+ }
+
+ private fun onUserSwitcherClicked(expandable: Expandable) {
+ falsingInteractor.runIfNotFalseTap { footerActionsInteractor.showUserSwitcher(expandable) }
+ }
+
+ private fun onSettingsButtonClicked(expandable: Expandable) {
+ falsingInteractor.runIfNotFalseTap { footerActionsInteractor.showSettings(expandable) }
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(): ToolbarViewModel
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
index 2e52845..16c2722 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
@@ -34,10 +34,7 @@
data object Invalid : TileSpec("")
/** Container for the spec of a tile provided by SystemUI. */
- data class PlatformTileSpec
- internal constructor(
- override val spec: String,
- ) : TileSpec(spec) {
+ data class PlatformTileSpec internal constructor(override val spec: String) : TileSpec(spec) {
override fun toString(): String {
return "P($spec)"
}
@@ -49,10 +46,8 @@
* [componentName] indicates the associated `TileService`.
*/
data class CustomTileSpec
- internal constructor(
- override val spec: String,
- val componentName: ComponentName,
- ) : TileSpec(spec) {
+ internal constructor(override val spec: String, val componentName: ComponentName) :
+ TileSpec(spec) {
override fun toString(): String {
return "C(${componentName.flattenToShortString()})"
}
@@ -92,3 +87,11 @@
}
}
}
+
+val TileSpec.metricSpec
+ get() =
+ when (this) {
+ is TileSpec.Invalid -> ""
+ is TileSpec.PlatformTileSpec -> spec
+ is TileSpec.CustomTileSpec -> componentName.packageName
+ }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt
index 17b78eb..e8c4274 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt
@@ -17,6 +17,7 @@
package com.android.systemui.qs.tiles.base.interactor
import android.annotation.WorkerThread
+import com.android.systemui.plugins.qs.TileDetailsViewModel
interface QSTileUserActionInteractor<DATA_TYPE> {
/**
@@ -27,4 +28,17 @@
* It's safe to run long running computations inside this function.
*/
@WorkerThread suspend fun handleInput(input: QSTileInput<DATA_TYPE>)
+
+ /**
+ * Provides the [TileDetailsViewModel] for constructing the corresponding details view.
+ *
+ * This property is defined here to reuse the business logic. For example, reusing the user
+ * long-click as the go-to-settings callback in the details view.
+ * Subclasses can override this property to provide a specific [TileDetailsViewModel]
+ * implementation.
+ *
+ * @return The [TileDetailsViewModel] instance, or null if not implemented.
+ */
+ val detailsViewModel: TileDetailsViewModel?
+ get() = null
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt
index dde3628..5f476ea 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt
@@ -17,18 +17,17 @@
package com.android.systemui.qs.tiles.base.viewmodel
import com.android.systemui.coroutines.newTracingContext
-import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
/** Creates a [CoroutineScope] for the [QSTileViewModelImpl]. */
class QSTileCoroutineScopeFactory
@Inject
-constructor(@Application private val applicationScope: CoroutineScope) {
+constructor(@Background private val bgDispatcher: CoroutineDispatcher) {
fun create(): CoroutineScope =
- CoroutineScope(
- applicationScope.coroutineContext + SupervisorJob() + newTracingContext("QSTileScope")
- )
+ CoroutineScope(bgDispatcher + SupervisorJob() + newTracingContext("QSTileScope"))
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
index aeb6cef..224fa10 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
@@ -20,6 +20,7 @@
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.Dumpable
import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.plugins.qs.TileDetailsViewModel
import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics
import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor
@@ -115,6 +116,9 @@
.flowOn(backgroundDispatcher)
.stateIn(tileScope, SharingStarted.WhileSubscribed(), true)
+ override val detailsViewModel: TileDetailsViewModel?
+ get() = userActionInteractor().detailsViewModel
+
override fun forceUpdate() {
tileScope.launch(context = backgroundDispatcher) { forceUpdates.emit(Unit) }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index bed8021..dbe1ae9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -195,8 +195,11 @@
private boolean mHasWifiEntries;
private WifiStateWorker mWifiStateWorker;
private boolean mHasActiveSubIdOnDds;
+ private boolean mIsMobileDataEnabled = false;
@VisibleForTesting
+ Map<Integer, ServiceState> mSubIdServiceState = new HashMap<>();
+ @VisibleForTesting
static final float TOAST_PARAMS_HORIZONTAL_WEIGHT = 1.0f;
@VisibleForTesting
static final float TOAST_PARAMS_VERTICAL_WEIGHT = 1.0f;
@@ -453,7 +456,7 @@
return mContext.getText(SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE);
}
- if (mCanConfigWifi && !isMobileDataEnabled()) {
+ if (mCanConfigWifi && !mIsMobileDataEnabled) {
if (DEBUG) {
Log.d(TAG, "Mobile data off");
}
@@ -551,7 +554,7 @@
numLevels += 1;
}
return getSignalStrengthIcon(subId, mContext, level, numLevels, NO_CELL_DATA_TYPE_ICON,
- !isMobileDataEnabled());
+ !mIsMobileDataEnabled);
}
Drawable getSignalStrengthIcon(int subId, Context context, int level, int numLevels,
@@ -681,6 +684,12 @@
// sets the non-DDS to be not found to hide its visual
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
+ int activeDataSubId = SubscriptionManager.getActiveDataSubscriptionId();
+ if (activeDataSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID
+ || mDefaultDataSubId == activeDataSubId) {
+ return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ }
+
SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(
SubscriptionManager.getActiveDataSubscriptionId());
if (subInfo != null && subInfo.getSubscriptionId() != mDefaultDataSubId
@@ -740,7 +749,6 @@
if (!isMobileDataEnabled()) {
return context.getString(R.string.mobile_data_off_summary);
}
-
String summary = networkTypeDescription;
boolean isForDds = subId == mDefaultDataSubId;
int activeSubId = getActiveAutoSwitchNonDdsSubId();
@@ -753,8 +761,8 @@
context.getString(
isForDds // if nonDds is active, explains Dds status as poor connection
? (isOnNonDds ? R.string.mobile_data_poor_connection
- : R.string.mobile_data_connection_active)
- : R.string.mobile_data_temp_connection_active),
+ : R.string.mobile_data_connection_active)
+ : R.string.mobile_data_temp_connection_active),
networkTypeDescription);
} else if (!isDataStateInService(subId)) {
summary = context.getString(R.string.mobile_data_no_connection);
@@ -963,10 +971,7 @@
* Return {@code true} if mobile data is enabled
*/
boolean isMobileDataEnabled() {
- if (mTelephonyManager == null || !mTelephonyManager.isDataEnabled()) {
- return false;
- }
- return true;
+ return mIsMobileDataEnabled;
}
/**
@@ -1019,8 +1024,8 @@
}
boolean isDataStateInService(int subId) {
- TelephonyManager tm = mSubIdTelephonyManagerMap.getOrDefault(subId, mTelephonyManager);
- final ServiceState serviceState = tm.getServiceState();
+ final ServiceState serviceState = mSubIdServiceState.getOrDefault(subId,
+ new ServiceState());
NetworkRegistrationInfo regInfo =
(serviceState == null) ? null : serviceState.getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS,
@@ -1036,8 +1041,8 @@
return false;
}
- TelephonyManager tm = mSubIdTelephonyManagerMap.getOrDefault(subId, mTelephonyManager);
- final ServiceState serviceState = tm.getServiceState();
+ final ServiceState serviceState = mSubIdServiceState.getOrDefault(subId,
+ new ServiceState());
return serviceState != null
&& serviceState.getState() == serviceState.STATE_IN_SERVICE;
}
@@ -1056,6 +1061,7 @@
final Network activeNetwork = mConnectivityManager.getActiveNetwork();
if (activeNetwork == null) {
+ Log.d(TAG, "getActiveNetwork is null.");
return false;
}
final NetworkCapabilities networkCapabilities =
@@ -1183,14 +1189,16 @@
}
private class InternetTelephonyCallback extends TelephonyCallback implements
+ TelephonyCallback.DataEnabledListener,
TelephonyCallback.DataConnectionStateListener,
TelephonyCallback.DisplayInfoListener,
TelephonyCallback.ServiceStateListener,
TelephonyCallback.SignalStrengthsListener,
TelephonyCallback.UserMobileDataStateListener,
- TelephonyCallback.CarrierNetworkListener{
+ TelephonyCallback.CarrierNetworkListener {
private final int mSubId;
+
private InternetTelephonyCallback(int subId) {
mSubId = subId;
}
@@ -1200,6 +1208,7 @@
if (mCallback != null) {
mCallback.onServiceStateChanged(serviceState);
}
+ mSubIdServiceState.put(mSubId, serviceState);
}
@Override
@@ -1238,6 +1247,13 @@
mCallback.onCarrierNetworkChange(active);
}
}
+
+ @Override
+ public void onDataEnabledChanged(boolean b, int i) {
+ if (mSubId == mDefaultDataSubId) {
+ mIsMobileDataEnabled = b;
+ }
+ }
}
private class InternetOnSubscriptionChangedListener
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
index 0ab533b..378d553 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
@@ -416,9 +416,10 @@
internetContent.mHasEthernet = mInternetDialogController.hasEthernet();
internetContent.mIsWifiEnabled = mInternetDialogController.isWifiEnabled();
internetContent.mHasActiveSubIdOnDds = mInternetDialogController.hasActiveSubIdOnDds();
- internetContent.mIsMobileDataEnabled = mInternetDialogController.isMobileDataEnabled();
internetContent.mIsDeviceLocked = mInternetDialogController.isDeviceLocked();
internetContent.mIsWifiScanEnabled = mInternetDialogController.isWifiScanEnabled();
+ internetContent.mActiveAutoSwitchNonDdsSubId =
+ mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
return internetContent;
}
@@ -433,7 +434,11 @@
private void setOnClickListener(SystemUIDialog dialog) {
mMobileNetworkLayout.setOnClickListener(v -> {
- int autoSwitchNonDdsSubId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
+ int autoSwitchNonDdsSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ if (mDataInternetContent.getValue() != null) {
+ autoSwitchNonDdsSubId =
+ mDataInternetContent.getValue().mActiveAutoSwitchNonDdsSubId;
+ }
if (autoSwitchNonDdsSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
showTurnOffAutoDataSwitchDialog(dialog, autoSwitchNonDdsSubId);
}
@@ -524,7 +529,7 @@
}
} else {
mMobileNetworkLayout.setVisibility(View.VISIBLE);
- mMobileDataToggle.setChecked(internetContent.mIsMobileDataEnabled);
+ mMobileDataToggle.setChecked(mInternetDialogController.isMobileDataEnabled());
mMobileTitleText.setText(getMobileNetworkTitle(mDefaultDataSubId));
String summary = getMobileNetworkSummary(mDefaultDataSubId);
if (!TextUtils.isEmpty(summary)) {
@@ -549,9 +554,9 @@
? R.color.connected_network_primary_color
: R.color.disconnected_network_primary_color;
mMobileToggleDivider.setBackgroundColor(dialog.getContext().getColor(primaryColor));
-
// Display the info for the non-DDS if it's actively being used
- int autoSwitchNonDdsSubId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
+ int autoSwitchNonDdsSubId = internetContent.mActiveAutoSwitchNonDdsSubId;
+
int nonDdsVisibility = autoSwitchNonDdsSubId
!= SubscriptionManager.INVALID_SUBSCRIPTION_ID ? View.VISIBLE : View.GONE;
@@ -983,8 +988,8 @@
boolean mIsCarrierNetworkActive = false;
boolean mIsWifiEnabled = false;
boolean mHasActiveSubIdOnDds = false;
- boolean mIsMobileDataEnabled = false;
boolean mIsDeviceLocked = false;
boolean mIsWifiScanEnabled = false;
+ int mActiveAutoSwitchNonDdsSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt
index a963b28..c4f9515 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt
@@ -18,10 +18,13 @@
import android.content.Intent
import android.provider.Settings
+import com.android.systemui.animation.Expandable
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.qs.TileDetailsViewModel
import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
import com.android.systemui.qs.tiles.base.interactor.QSTileInput
import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.dialog.InternetDetailsViewModel
import com.android.systemui.qs.tiles.dialog.InternetDialogManager
import com.android.systemui.qs.tiles.dialog.WifiStateWorker
import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
@@ -61,11 +64,18 @@
wifiStateWorker.isWifiEnabled = !wifiStateWorker.isWifiEnabled
}
is QSTileUserAction.LongClick -> {
- qsTileIntentUserActionHandler.handle(
- action.expandable,
- Intent(Settings.ACTION_WIFI_SETTINGS)
- )
+ handleLongClick(action.expandable)
}
}
}
+
+ override val detailsViewModel: TileDetailsViewModel =
+ InternetDetailsViewModel { handleLongClick(null) }
+
+ private fun handleLongClick(expandable:Expandable?){
+ qsTileIntentUserActionHandler.handle(
+ expandable,
+ Intent(Settings.ACTION_WIFI_SETTINGS)
+ )
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
index b1b0001..e8b9926 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
@@ -17,6 +17,7 @@
package com.android.systemui.qs.tiles.viewmodel
import android.os.UserHandle
+import com.android.systemui.plugins.qs.TileDetailsViewModel
import kotlinx.coroutines.flow.StateFlow
/**
@@ -37,6 +38,10 @@
/** Specifies whether this device currently supports this tile. */
val isAvailable: StateFlow<Boolean>
+ /** Specifies the [TileDetailsViewModel] for constructing the corresponding details view. */
+ val detailsViewModel: TileDetailsViewModel?
+ get() = null
+
/**
* Notifies about the user change. Implementations should avoid using 3rd party userId sources
* and use this value instead. This is to maintain consistent and concurrency-free behaviour
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
index 9d902d3..632eeef 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
@@ -27,6 +27,7 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.qs.TileDetailsViewModel
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon
import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIconWithRes
@@ -154,6 +155,10 @@
qsTileViewModel.onUserChanged(UserHandle.of(currentUser))
}
+ override fun getDetailsViewModel(): TileDetailsViewModel? {
+ return qsTileViewModel.detailsViewModel
+ }
+
@Deprecated(
"Not needed as {@link com.android.internal.logging.UiEvent} will use #getMetricsSpec",
replaceWith = ReplaceWith("getMetricsSpec"),
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
index 62b1203..91d9079 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
@@ -22,6 +22,7 @@
import com.android.systemui.qs.panels.ui.viewmodel.EditModeViewModel
import com.android.systemui.qs.panels.ui.viewmodel.QuickQuickSettingsViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.toolbar.ToolbarViewModel
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -38,6 +39,7 @@
val tileGridViewModel: TileGridViewModel,
val editModeViewModel: EditModeViewModel,
val detailsViewModel: DetailsViewModel,
+ val toolbarViewModelFactory: ToolbarViewModel.Factory,
) : ExclusiveActivatable() {
val brightnessSliderViewModel =
diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
index 9a1ffcb..3c03d28 100644
--- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
@@ -35,6 +35,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import static com.android.systemui.Flags.notificationShadeBlur;
/**
* Drawable used on SysUI scrims.
@@ -213,6 +214,10 @@
public void draw(@NonNull Canvas canvas) {
mPaint.setColor(mMainColor);
mPaint.setAlpha(mAlpha);
+ if (notificationShadeBlur()) {
+ // TODO(b/370555223): Match the alpha to the visual spec when it is finalized.
+ mPaint.setAlpha((int) (0.5f * mAlpha));
+ }
if (mConcaveInfo != null) {
drawConcave(canvas);
} else if (mCornerRadiusEnabled && mCornerRadius > 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
index 49f3cfc..4bfa61e 100644
--- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
@@ -44,6 +44,8 @@
import java.util.concurrent.Executor;
+import static com.android.systemui.Flags.notificationShadeBlur;
+
/**
* A view which can draw a scrim. This view maybe be used in multiple windows running on different
* threads, but is controlled by {@link com.android.systemui.statusbar.phone.ScrimController} so we
@@ -250,6 +252,10 @@
if (mBlendWithMainColor) {
mainTinted = ColorUtils.blendARGB(mColors.getMainColor(), mTintColor, tintAmount);
}
+ if (notificationShadeBlur()) {
+ // TODO(b/370555223): Fix color and transparency to match visual spec exactly
+ mainTinted = ColorUtils.blendARGB(mColors.getMainColor(), Color.GRAY, 0.5f);
+ }
drawable.setColor(mainTinted, animated);
} else {
boolean hasAlpha = Color.alpha(mTintColor) != 0;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 31780a5..61ac1a02 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -41,11 +41,11 @@
import com.android.compose.theme.PlatformTheme
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.Flags
-import com.android.systemui.Flags.communalHubOnMobile
import com.android.systemui.ambient.touch.TouchMonitor
import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent
import com.android.systemui.communal.dagger.Communal
import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.communal.ui.compose.CommunalContainer
import com.android.systemui.communal.ui.compose.CommunalContent
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
@@ -83,6 +83,7 @@
@Inject
constructor(
private val communalInteractor: CommunalInteractor,
+ private val communalSettingsInteractor: CommunalSettingsInteractor,
private val communalViewModel: CommunalViewModel,
private val keyguardInteractor: KeyguardInteractor,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
@@ -514,7 +515,7 @@
val touchOnUmo = keyguardMediaController.isWithinMediaViewBounds(ev.x.toInt(), ev.y.toInt())
val touchOnSmartspace =
lockscreenSmartspaceController.isWithinSmartspaceBounds(ev.x.toInt(), ev.y.toInt())
- val glanceableHubV2 = communalHubOnMobile()
+ val glanceableHubV2 = communalSettingsInteractor.isV2FlagEnabled()
if (
!hubShowing &&
(touchOnNotifications || touchOnUmo || touchOnSmartspace || glanceableHubV2)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
index 6bbd4a5..d343ed5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
@@ -35,6 +35,7 @@
import com.android.systemui.dump.DumpManager
import java.io.PrintWriter
import javax.inject.Inject
+import com.android.systemui.Flags.notificationShadeBlur
@SysUISingleton
open class BlurUtils @Inject constructor(
@@ -43,7 +44,14 @@
dumpManager: DumpManager
) : Dumpable {
val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius)
- val maxBlurRadius = resources.getDimensionPixelSize(R.dimen.max_window_blur_radius)
+ val maxBlurRadius =
+ if (notificationShadeBlur()) {
+ resources.getDimensionPixelSize(R.dimen.max_shade_window_blur_radius)
+ } else {
+ resources.getDimensionPixelSize(R.dimen.max_window_blur_radius)
+ }
+
+
private var lastAppliedBlur = 0
private var earlyWakeupEnabled = false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
index c997ac5..d0dc7ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
@@ -78,7 +78,6 @@
import com.android.internal.app.AssistUtils;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
-import com.android.settingslib.Utils;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.phone.CentralSurfaces;
@@ -768,8 +767,6 @@
Intent.CATEGORY_APP_EMAIL,
Intent.CATEGORY_APP_CALENDAR,
Intent.CATEGORY_APP_MAPS,
- Intent.CATEGORY_APP_MUSIC,
- Intent.CATEGORY_APP_MESSAGING,
Intent.CATEGORY_APP_CALCULATOR,
};
String[] shortcutLabels = {
@@ -778,19 +775,15 @@
mContext.getString(R.string.keyboard_shortcut_group_applications_email),
mContext.getString(R.string.keyboard_shortcut_group_applications_calendar),
mContext.getString(R.string.keyboard_shortcut_group_applications_maps),
- mContext.getString(R.string.keyboard_shortcut_group_applications_music),
- mContext.getString(R.string.keyboard_shortcut_group_applications_sms),
mContext.getString(R.string.keyboard_shortcut_group_applications_calculator)
};
int[] keyCodes = {
KeyEvent.KEYCODE_B,
- KeyEvent.KEYCODE_C,
- KeyEvent.KEYCODE_E,
- KeyEvent.KEYCODE_K,
- KeyEvent.KEYCODE_M,
KeyEvent.KEYCODE_P,
- KeyEvent.KEYCODE_S,
+ KeyEvent.KEYCODE_E,
+ KeyEvent.KEYCODE_C,
+ KeyEvent.KEYCODE_M,
KeyEvent.KEYCODE_U,
};
@@ -1422,13 +1415,11 @@
}
private int getColorOfTextColorOnAccent() {
- return Utils.getColorAttrDefaultColor(
- mContext, com.android.internal.R.attr.materialColorOnPrimary);
+ return mContext.getColor(com.android.internal.R.color.materialColorOnPrimary);
}
private int getColorOfTextColorSecondary() {
- return Utils.getColorAttrDefaultColor(
- mContext, com.android.internal.R.attr.materialColorOnSurface);
+ return mContext.getColor(com.android.internal.R.color.materialColorOnSurface);
}
// Create the new data structure for handling the N-to-1 key mapping and other complex case.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 1db7fb4..684466a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -53,6 +53,7 @@
import javax.inject.Inject
import kotlin.math.max
import kotlin.math.sign
+import com.android.systemui.Flags.notificationShadeBlur
/**
* Responsible for blurring the notification shade window, and applying a zoom effect to the
@@ -220,7 +221,9 @@
// Make blur be 0 if it is necessary to stop blur effect.
if (scrimsVisible) {
- blur = 0
+ if (!notificationShadeBlur()) {
+ blur = 0
+ }
zoomOut = 0f
}
@@ -240,7 +243,7 @@
Choreographer.FrameCallback {
updateScheduled = false
val (blur, zoomOut) = computeBlurAndZoomOut()
- val opaque = scrimsVisible && !blursDisabledForAppLaunch
+ val opaque = if (notificationShadeBlur()) false else scrimsVisible && !blursDisabledForAppLaunch
Trace.traceCounter(Trace.TRACE_TAG_APP, "shade_blur_radius", blur)
blurUtils.applyBlur(root.viewRootImpl, blur, opaque)
lastAppliedBlur = blur
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 6f491e7..85b50d3 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
@@ -35,6 +35,7 @@
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
import com.android.systemui.util.time.SystemClock
import javax.inject.Inject
@@ -67,9 +68,17 @@
Flags.statusBarCallChipNotificationIcon() &&
state.notificationIconView != null
) {
+ StatusBarConnectedDisplays.assertInLegacyMode()
OngoingActivityChipModel.ChipIcon.StatusBarView(
state.notificationIconView
)
+ } else if (
+ StatusBarConnectedDisplays.isEnabled &&
+ Flags.statusBarCallChipNotificationIcon()
+ ) {
+ OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(
+ state.notificationKey
+ )
} else {
OngoingActivityChipModel.ChipIcon.SingleColorIcon(phoneIcon)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
index c57c807..571a3e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/SingleNotificationChipInteractor.kt
@@ -22,6 +22,7 @@
import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad
import com.android.systemui.statusbar.chips.StatusBarChipsLog
import com.android.systemui.statusbar.chips.notification.domain.model.NotificationChipModel
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -100,10 +101,15 @@
private fun ActiveNotificationModel.toNotificationChipModel(): NotificationChipModel? {
val statusBarChipIconView = this.statusBarChipIconView
if (statusBarChipIconView == null) {
- logger.w({ "$str1: Can't show chip because status bar chip icon view is null" }) {
- str1 = extraLogTag
+ if (!StatusBarConnectedDisplays.isEnabled) {
+ logger.w({ "$str1: Can't show chip because status bar chip icon view is null" }) {
+ str1 = extraLogTag
+ }
+ // When the flag is disabled, we keep the old behavior of returning null.
+ // When the flag is enabled, the icon will always be null, and will later be
+ // fetched in the UI layer using the notification key.
+ return null
}
- return null
}
return NotificationChipModel(key, statusBarChipIconView, whenTime)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt
index bc4241d..4588b19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/model/NotificationChipModel.kt
@@ -21,6 +21,6 @@
/** Modeling all the data needed to render a status bar notification chip. */
data class NotificationChipModel(
val key: String,
- val statusBarChipIconView: StatusBarIconView,
+ val statusBarChipIconView: StatusBarIconView?,
val whenTime: Long,
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
index b2f7e2f..2cd5bb3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
@@ -24,6 +24,7 @@
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.chips.ui.model.ColorsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
@@ -50,7 +51,14 @@
/** Converts the notification to the [OngoingActivityChipModel] object. */
private fun NotificationChipModel.toActivityChipModel(): OngoingActivityChipModel.Shown {
StatusBarNotifChips.assertInNewMode()
- val icon = OngoingActivityChipModel.ChipIcon.StatusBarView(this.statusBarChipIconView)
+ val icon =
+ if (this.statusBarChipIconView != null) {
+ StatusBarConnectedDisplays.assertInLegacyMode()
+ OngoingActivityChipModel.ChipIcon.StatusBarView(this.statusBarChipIconView)
+ } else {
+ StatusBarConnectedDisplays.assertInNewMode()
+ OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(this.key)
+ }
// TODO(b/364653005): Use the notification color if applicable.
val colors = ColorsModel.Themed
val onClickListener =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
index 730784a..cf69d40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
@@ -32,11 +32,13 @@
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.chips.ui.view.ChipChronometer
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
+import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.IconViewStore
/** Binder for ongoing activity chip views. */
object OngoingActivityChipBinder {
/** Binds the given [chipModel] data to the given [chipView]. */
- fun bind(chipModel: OngoingActivityChipModel, chipView: View) {
+ fun bind(chipModel: OngoingActivityChipModel, chipView: View, iconViewStore: IconViewStore?) {
val chipContext = chipView.context
val chipDefaultIconView: ImageView =
chipView.requireViewById(R.id.ongoing_activity_chip_icon)
@@ -51,7 +53,7 @@
when (chipModel) {
is OngoingActivityChipModel.Shown -> {
// Data
- setChipIcon(chipModel, chipBackgroundView, chipDefaultIconView)
+ setChipIcon(chipModel, chipBackgroundView, chipDefaultIconView, iconViewStore)
setChipMainContent(chipModel, chipTextView, chipTimeView, chipShortTimeDeltaView)
chipView.setOnClickListener(chipModel.onClickListener)
updateChipPadding(
@@ -85,6 +87,7 @@
chipModel: OngoingActivityChipModel.Shown,
backgroundView: ChipBackgroundContainer,
defaultIconView: ImageView,
+ iconViewStore: IconViewStore?,
) {
// Always remove any previously set custom icon. If we have a new custom icon, we'll re-add
// it.
@@ -108,40 +111,64 @@
defaultIconView.untintView()
}
is OngoingActivityChipModel.ChipIcon.StatusBarView -> {
- // Hide the default icon since we'll show this custom icon instead.
- defaultIconView.visibility = View.GONE
-
- // Add the new custom icon:
- // 1. Set up the right visual params.
- val iconView = icon.impl
- with(iconView) {
- id = CUSTOM_ICON_VIEW_ID
- // TODO(b/354930838): Update the content description to not include "phone" and
- // maybe include the app name.
- contentDescription =
- context.resources.getString(R.string.ongoing_phone_call_content_description)
- tintView(iconTint)
+ StatusBarConnectedDisplays.assertInLegacyMode()
+ setStatusBarIconView(defaultIconView, icon.impl, iconTint, backgroundView)
+ }
+ is OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon -> {
+ StatusBarConnectedDisplays.assertInNewMode()
+ val iconView = fetchStatusBarIconView(iconViewStore, icon)
+ if (iconView == null) {
+ // This means that the notification key doesn't exist anymore.
+ return
}
-
- // 2. If we just reinflated the view, we may need to detach the icon view from the
- // old chip before we reattach it to the new one.
- // See also: NotificationIconContainerViewBinder#bindIcons.
- val currentParent = iconView.parent as? ViewGroup
- if (currentParent != null && currentParent != backgroundView) {
- currentParent.removeView(iconView)
- currentParent.removeTransientView(iconView)
- }
-
- // 3: Add the icon as the starting view.
- backgroundView.addView(
- iconView,
- /* index= */ 0,
- generateCustomIconLayoutParams(iconView),
- )
+ setStatusBarIconView(defaultIconView, iconView, iconTint, backgroundView)
}
}
}
+ private fun fetchStatusBarIconView(
+ iconViewStore: IconViewStore?,
+ icon: OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon,
+ ): StatusBarIconView? {
+ StatusBarConnectedDisplays.assertInNewMode()
+ if (iconViewStore == null) {
+ throw IllegalStateException("Store should always be non-null when flag is enabled.")
+ }
+ return iconViewStore.iconView(icon.notificationKey)
+ }
+
+ private fun setStatusBarIconView(
+ defaultIconView: ImageView,
+ iconView: StatusBarIconView,
+ iconTint: Int,
+ backgroundView: ChipBackgroundContainer,
+ ) {
+ // Hide the default icon since we'll show this custom icon instead.
+ defaultIconView.visibility = View.GONE
+
+ // 1. Set up the right visual params.
+ with(iconView) {
+ id = CUSTOM_ICON_VIEW_ID
+ // TODO(b/354930838): Update the content description to not include "phone" and maybe
+ // include the app name.
+ contentDescription =
+ context.resources.getString(R.string.ongoing_phone_call_content_description)
+ tintView(iconTint)
+ }
+
+ // 2. If we just reinflated the view, we may need to detach the icon view from the old chip
+ // before we reattach it to the new one.
+ // See also: NotificationIconContainerViewBinder#bindIcons.
+ val currentParent = iconView.parent as? ViewGroup
+ if (currentParent != null && currentParent != backgroundView) {
+ currentParent.removeView(iconView)
+ currentParent.removeTransientView(iconView)
+ }
+
+ // 3: Add the icon as the starting view.
+ backgroundView.addView(iconView, /* index= */ 0, generateCustomIconLayoutParams(iconView))
+ }
+
private fun View.getCustomIconView(): StatusBarIconView? {
return this.findViewById(CUSTOM_ICON_VIEW_ID)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt
index 4b0fc5a..4de4597 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt
@@ -51,9 +51,8 @@
// the right text color. Right now, it has the right text color when the chip is first
// created but the color doesn't update if dark theme changes.
override fun text(context: Context) =
- Utils.getColorAttrDefaultColor(
- context,
- com.android.internal.R.attr.materialColorOnSurface,
+ context.getColor(
+ com.android.internal.R.color.materialColorOnSurface
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
index cf07af1..2dce4e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
@@ -21,6 +21,7 @@
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
/** Model representing the display of an ongoing activity as a chip in the status bar. */
sealed class OngoingActivityChipModel {
@@ -132,6 +133,17 @@
"OngoingActivityChipModel.ChipIcon.StatusBarView created even though " +
"Flags.statusBarCallChipNotificationIcon is not enabled"
}
+ StatusBarConnectedDisplays.assertInLegacyMode()
+ }
+ }
+
+ /**
+ * The icon is a custom icon, which is set on a notification, and can be looked up using the
+ * provided [notificationKey]. The icon was likely created by an external app.
+ */
+ data class StatusBarNotificationIcon(val notificationKey: String) : ChipIcon {
+ init {
+ StatusBarConnectedDisplays.assertInNewMode()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
index ef7b1c3..04458f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
@@ -14,10 +14,13 @@
* limitations under the License.
*/
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
package com.android.systemui.statusbar.notification.collection.coordinator
import android.app.Notification
import android.os.UserHandle
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.server.notification.Flags.screenshareNotificationHiding
import com.android.systemui.dagger.qualifiers.Application
@@ -44,9 +47,9 @@
import dagger.Module
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.mapNotNull
-import com.android.app.tracing.coroutines.launchTraced as launch
@Module(includes = [PrivateSensitiveContentCoordinatorModule::class])
interface SensitiveContentCoordinatorModule
@@ -80,6 +83,7 @@
DynamicPrivacyController.Listener,
OnBeforeRenderListListener {
private var inTransitionFromLockedToGone = false
+ private var canSwipeToEnter = false
private val onSensitiveStateChanged = Runnable() { invalidateList("onSensitiveStateChanged") }
@@ -98,7 +102,9 @@
}
override fun attach(pipeline: NotifPipeline) {
- dynamicPrivacyController.addListener(this)
+ if (!SceneContainerFlag.isEnabled) {
+ dynamicPrivacyController.addListener(this)
+ }
if (screenshareNotificationHiding()) {
sensitiveNotificationProtectionController.registerSensitiveStateListener(
onSensitiveStateChanged
@@ -128,6 +134,15 @@
invalidateList("inTransitionFromLockedToGoneChanged")
}
}
+ scope.launch {
+ deviceEntryInteractor.canSwipeToEnter.collect {
+ val canSwipeToEnter = it ?: false
+ if (this@SensitiveContentCoordinatorImpl.canSwipeToEnter != canSwipeToEnter) {
+ this@SensitiveContentCoordinatorImpl.canSwipeToEnter = canSwipeToEnter
+ invalidateList("canSwipeToEnterChanged")
+ }
+ }
+ }
}
}
@@ -168,7 +183,9 @@
(devicePublic &&
!lockscreenUserManager.userAllowsPrivateNotificationsInPublic(currentUserId)) ||
isSensitiveContentProtectionActive
- val dynamicallyUnlocked = dynamicPrivacyController.isDynamicallyUnlocked
+ val dynamicallyUnlocked =
+ if (SceneContainerFlag.isEnabled) canSwipeToEnter
+ else dynamicPrivacyController.isDynamicallyUnlocked
for (entry in extractAllRepresentativeEntries(entries).filter { it.rowExists() }) {
val notifUserId = entry.sbn.user.identifier
val userLockscreen =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
index a0515ca..d258898 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
@@ -39,7 +39,6 @@
import androidx.annotation.NonNull;
-import com.android.settingslib.Utils;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.ColorUpdateLogger;
import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor;
@@ -457,8 +456,8 @@
*/
public void updateColors() {
Resources.Theme theme = mContext.getTheme();
- final @ColorInt int onSurface = Utils.getColorAttrDefaultColor(mContext,
- com.android.internal.R.attr.materialColorOnSurface);
+ final @ColorInt int onSurface = mContext.getColor(
+ com.android.internal.R.color.materialColorOnSurface);
// Same resource, separate drawables to prevent touch effects from showing on the wrong
// button.
final Drawable clearAllBg = theme.getDrawable(R.drawable.notif_footer_btn_background);
@@ -467,8 +466,8 @@
? theme.getDrawable(R.drawable.notif_footer_btn_background) : null;
final @ColorInt int scHigh;
if (!notificationFooterBackgroundTintOptimization()) {
- scHigh = Utils.getColorAttrDefaultColor(mContext,
- com.android.internal.R.attr.materialColorSurfaceContainerHigh);
+ scHigh = mContext.getColor(
+ com.android.internal.R.color.materialColorSurfaceContainerHigh);
if (scHigh != 0) {
final ColorFilter bgColorFilter = new PorterDuffColorFilter(scHigh, SRC_ATOP);
clearAllBg.setColorFilter(bgColorFilter);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
index 98ce163..b56a838 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
@@ -162,7 +162,9 @@
val sbIcon = iconBuilder.createIconView(entry)
sbIcon.scaleType = ImageView.ScaleType.CENTER_INSIDE
val sbChipIcon: StatusBarIconView?
- if (Flags.statusBarCallChipNotificationIcon()) {
+ if (
+ Flags.statusBarCallChipNotificationIcon() && !StatusBarConnectedDisplays.isEnabled
+ ) {
sbChipIcon = iconBuilder.createIconView(entry)
sbChipIcon.scaleType = ImageView.ScaleType.CENTER_INSIDE
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 5c51ada..b4092cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -37,7 +37,6 @@
import com.android.app.animation.Interpolators;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.jank.InteractionJankMonitor.Configuration;
-import com.android.settingslib.Utils;
import com.android.systemui.Gefingerpoken;
import com.android.systemui.res.R;
import com.android.systemui.shade.TouchLogger;
@@ -123,8 +122,8 @@
}
private void updateColors() {
- mNormalColor = Utils.getColorAttrDefaultColor(mContext,
- com.android.internal.R.attr.materialColorSurfaceContainerHigh);
+ mNormalColor = mContext.getColor(
+ com.android.internal.R.color.materialColorSurfaceContainerHigh);
mTintedRippleColor = mContext.getColor(
R.color.notification_ripple_tinted_color);
mNormalRippleColor = mContext.getColor(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
index 61f4e96..5c4c253 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
@@ -21,7 +21,6 @@
import android.annotation.Nullable;
import android.app.Flags;
import android.content.Context;
-import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
@@ -115,16 +114,9 @@
}
private void resolveThemeTextColors() {
- try (TypedArray ta = mContext.getTheme().obtainStyledAttributes(
- android.R.style.Theme_DeviceDefault_DayNight, new int[]{
- com.android.internal.R.attr.materialColorOnSurface,
- com.android.internal.R.attr.materialColorOnSurfaceVariant
- })) {
- if (ta != null) {
- mPrimaryTextColor = ta.getColor(0, mPrimaryTextColor);
- mSecondaryTextColor = ta.getColor(1, mSecondaryTextColor);
- }
- }
+ mPrimaryTextColor = mContext.getColor(com.android.internal.R.color.materialColorOnSurface);
+ mSecondaryTextColor = mContext.getColor(
+ com.android.internal.R.color.materialColorOnSurfaceVariant);
}
public void bind(@Nullable CharSequence title, @Nullable CharSequence text,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 34ef639..e440d27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -35,7 +35,6 @@
import androidx.annotation.Nullable;
import com.android.internal.util.ContrastColorUtil;
-import com.android.settingslib.Utils;
import com.android.systemui.Dumpable;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.shared.NotificationAddXOnHoverToDismiss;
@@ -83,8 +82,8 @@
R.color.notification_state_color_light);
mDarkColoredStatefulColors = getResources().getColorStateList(
R.color.notification_state_color_dark);
- mNormalColor = Utils.getColorAttrDefaultColor(mContext,
- com.android.internal.R.attr.materialColorSurfaceContainerHigh);
+ mNormalColor = mContext.getColor(
+ com.android.internal.R.color.materialColorSurfaceContainerHigh);
mFocusOverlayStroke = getResources().getDimension(R.dimen.notification_focus_stroke_width);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index e141b7c..be9f60d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -43,7 +43,6 @@
import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
-import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
@@ -337,10 +336,7 @@
Drawable person = mIconFactory.getBaseIconDrawable(mShortcutInfo);
if (person == null) {
person = mContext.getDrawable(R.drawable.ic_person).mutate();
- TypedArray ta = mContext.obtainStyledAttributes(
- new int[]{com.android.internal.R.attr.materialColorPrimary});
- int colorPrimary = ta.getColor(0, 0);
- ta.recycle();
+ int colorPrimary = mContext.getColor(com.android.internal.R.color.materialColorPrimary);
person.setTint(colorPrimary);
}
ImageView image = findViewById(R.id.conversation_icon);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index 182fba3..752a8ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -38,7 +38,6 @@
import com.android.internal.graphics.ColorUtils;
import com.android.internal.util.ContrastColorUtil;
import com.android.internal.widget.CachingIconView;
-import com.android.settingslib.Utils;
import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.statusbar.TransformableView;
import com.android.systemui.statusbar.notification.FeedbackIcon;
@@ -344,9 +343,8 @@
if (customBackgroundColor != 0) {
return customBackgroundColor;
}
- return Utils.getColorAttr(mView.getContext(),
- com.android.internal.R.attr.materialColorSurfaceContainerHigh)
- .getDefaultColor();
+ return mView.getContext().getColor(
+ com.android.internal.R.color.materialColorSurfaceContainerHigh);
}
public void setLegacy(boolean legacy) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 99edf65..00cd8ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -22,7 +22,6 @@
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.Path.Direction;
@@ -1519,10 +1518,9 @@
int color = mContainingNotification.getNotificationColor();
Resources.Theme theme = new ContextThemeWrapper(mContext,
com.android.internal.R.style.Theme_DeviceDefault_DayNight).getTheme();
- try (TypedArray ta = theme.obtainStyledAttributes(
- new int[]{com.android.internal.R.attr.materialColorPrimary})) {
- color = ta.getColor(0, color);
- }
+
+ color = mContext.getColor(com.android.internal.R.color.materialColorPrimary);
+
mHybridGroupManager.setOverflowNumberColor(mOverflowNumber, color);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index b9e38ab..0720899 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -83,7 +83,6 @@
import com.android.internal.policy.SystemBarUtils;
import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.keyguard.KeyguardSliceView;
-import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.ExpandHelper;
@@ -2630,6 +2629,7 @@
private void updateContentHeight() {
if (SceneContainerFlag.isEnabled()) {
updateIntrinsicStackHeight();
+ updateStackEndHeightAndStackHeight(mAmbientState.getExpansionFraction());
return;
}
@@ -4729,10 +4729,10 @@
* Update colors of section headers, shade footer, and empty shade views.
*/
void updateDecorViews() {
- final @ColorInt int onSurface = Utils.getColorAttrDefaultColor(
- mContext, com.android.internal.R.attr.materialColorOnSurface);
- final @ColorInt int onSurfaceVariant = Utils.getColorAttrDefaultColor(
- mContext, com.android.internal.R.attr.materialColorOnSurfaceVariant);
+ final @ColorInt int onSurface = mContext.getColor(
+ com.android.internal.R.color.materialColorOnSurface);
+ final @ColorInt int onSurfaceVariant = mContext.getColor(
+ com.android.internal.R.color.materialColorOnSurfaceVariant);
ColorUpdateLogger colorUpdateLogger = ColorUpdateLogger.getInstance();
if (colorUpdateLogger != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index ba707a5..245b1d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -429,9 +429,10 @@
};
/**
- * Recalculate sensitiveness without animation; called when waking up while keyguard occluded.
+ * Recalculate sensitiveness without animation; called when waking up while keyguard occluded,
+ * or whenever we update the Lockscreen public mode.
*/
- public void updateSensitivenessForOccludedWakeup() {
+ public void updateSensitivenessWithoutAnimation() {
updateSensitivenessWithAnimation(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
index d1338ea..f2ef2f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
@@ -313,6 +313,7 @@
// if it is volume panel.
options.setDisallowEnterPictureInPictureWhileLaunching(true)
}
+ intent.collectExtraIntentKeys()
try {
result[0] =
ActivityTaskManager.getService()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index 7f95fb0..adfcb71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -53,6 +53,7 @@
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.QSPanelController;
+import com.android.systemui.qs.flags.QsInCompose;
import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.res.R;
import com.android.systemui.scene.shared.flag.SceneContainerFlag;
@@ -209,10 +210,16 @@
@Override
public void clickTile(ComponentName tile) {
- // Can't inject this because it changes with the QS fragment
- QSPanelController qsPanelController = mCentralSurfaces.getQSPanelController();
- if (qsPanelController != null) {
- qsPanelController.clickTile(tile);
+ if (QsInCompose.isEnabled()) {
+ if (tile != null) {
+ mQSHost.clickTile(tile);
+ }
+ } else {
+ // Can't inject this because it changes with the QS fragment
+ QSPanelController qsPanelController = mCentralSurfaces.getQSPanelController();
+ if (qsPanelController != null) {
+ qsPanelController.clickTile(tile);
+ }
}
}
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 c6af328..7bea480 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -2234,6 +2234,9 @@
// If the state didn't change, we may still need to update public mode
mLockscreenUserManager.updatePublicMode();
+ if (SceneContainerFlag.isEnabled()) {
+ mStackScrollerController.updateSensitivenessWithoutAnimation();
+ }
}
if (mStatusBarStateController.leaveOpenOnKeyguardHide()) {
if (!mStatusBarStateController.isKeyguardRequested()) {
@@ -2681,7 +2684,7 @@
// So if AOD is off or unsupported we need to trigger these updates at screen on
// when the keyguard is occluded.
mLockscreenUserManager.updatePublicMode();
- mStackScrollerController.updateSensitivenessForOccludedWakeup();
+ mStackScrollerController.updateSensitivenessWithoutAnimation();
}
if (mLaunchCameraWhenFinishedWaking) {
startLaunchTransitionTimeout();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
index 1cca3ae..d7cc65d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
@@ -180,6 +180,7 @@
// if it is volume panel.
options.setDisallowEnterPictureInPictureWhileLaunching(true)
}
+ intent.collectExtraIntentKeys()
try {
result[0] =
ActivityTaskManager.getService()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index e7c6fb4..324db79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -51,7 +51,6 @@
import com.android.keyguard.BouncerPanelExpansionCalculator;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.settingslib.Utils;
import com.android.systemui.Dumpable;
import com.android.systemui.animation.ShadeInterpolation;
import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
@@ -82,9 +81,6 @@
import com.android.systemui.util.wakelock.DelayedWakeLock;
import com.android.systemui.util.wakelock.WakeLock;
-import kotlinx.coroutines.CoroutineDispatcher;
-import kotlinx.coroutines.ExperimentalCoroutinesApi;
-
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -93,6 +89,9 @@
import javax.inject.Inject;
+import kotlinx.coroutines.CoroutineDispatcher;
+import kotlinx.coroutines.ExperimentalCoroutinesApi;
+
/**
* Controls both the scrim behind the notifications and in front of the notifications (when a
* security method gets shown).
@@ -1532,17 +1531,17 @@
private void updateThemeColors() {
if (mScrimBehind == null) return;
- int background = Utils.getColorAttr(mScrimBehind.getContext(),
- com.android.internal.R.attr.materialColorSurfaceDim).getDefaultColor();
- int accent = Utils.getColorAttr(mScrimBehind.getContext(),
- com.android.internal.R.attr.materialColorPrimary).getDefaultColor();
+ int background = mScrimBehind.getContext().getColor(
+ com.android.internal.R.color.materialColorSurfaceDim);
+ int accent = mScrimBehind.getContext().getColor(
+ com.android.internal.R.color.materialColorPrimary);
mColors.setMainColor(background);
mColors.setSecondaryColor(accent);
final boolean isBackgroundLight = !ContrastColorUtil.isColorDark(background);
mColors.setSupportsDarkText(isBackgroundLight);
- int surface = Utils.getColorAttr(mScrimBehind.getContext(),
- com.android.internal.R.attr.materialColorSurface).getDefaultColor();
+ int surface = mScrimBehind.getContext().getColor(
+ com.android.internal.R.color.materialColorSurface);
for (ScrimState state : ScrimState.values()) {
state.setSurfaceColor(surface);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java
index b9cba99..d0d0b5c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java
@@ -29,7 +29,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.settingslib.Utils;
import com.android.systemui.res.R;
import com.android.wm.shell.shared.animation.Interpolators;
@@ -51,8 +50,8 @@
}
void updateColor() {
- final @ColorInt int onSurface = Utils.getColorAttrDefaultColor(mContext,
- com.android.internal.R.attr.materialColorOnSurface);
+ final @ColorInt int onSurface = mContext.getColor(
+ com.android.internal.R.color.materialColorOnSurface);
setTextColor(onSurface);
setBackground(getResources().getDrawable(R.drawable.rounded_bg_full, mContext.getTheme()));
}
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 e4768e8..724ba8c 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
@@ -377,6 +377,7 @@
mCarrierConfigTracker.addDefaultDataSubscriptionChangedListener(mDefaultDataListener);
mHomeStatusBarViewBinder.bind(
+ view.getContext().getDisplayId(),
mStatusBar,
mHomeStatusBarViewModel,
/* systemEventChipAnimateIn */ null,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index 2166304..c57cede 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -260,6 +260,7 @@
startTimeMs = currentInfo.callStartTime,
notificationIconView = icon,
intent = currentInfo.intent,
+ notificationKey = currentInfo.key,
)
} else {
return OngoingCallModel.NoCall
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
index 1f7bd14..4b71c02 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
@@ -90,6 +90,7 @@
startTimeMs = model.whenTime,
notificationIconView = model.statusBarChipIconView,
intent = model.contentIntent,
+ notificationKey = model.key,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
index c2c91b2..1a5dcc1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
@@ -46,5 +46,6 @@
val startTimeMs: Long,
val notificationIconView: StatusBarIconView?,
val intent: PendingIntent?,
+ val notificationKey: String,
) : OngoingCallModel
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
index 08a98c3..12f578c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
@@ -161,6 +161,13 @@
)
.stateIn(scope, SharingStarted.WhileSubscribed(), true)
+ /** True if any known mobile network is currently using a non terrestrial network */
+ val isAnyConnectionNtn =
+ iconsInteractor.icons.aggregateOver(selector = { it.isNonTerrestrial }, false) {
+ nonTerrestrialNetworks ->
+ nonTerrestrialNetworks.any { it == true }
+ }
+
companion object {
const val TAG = "DeviceBasedSatelliteInteractor"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
index f3d5139..ea915ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
@@ -114,34 +114,39 @@
private val showIcon =
if (interactor.isOpportunisticSatelliteIconEnabled) {
- canShowIcon
- .flatMapLatest { canShow ->
- if (!canShow) {
- flowOf(false)
- } else {
- combine(
- shouldShowIconForOosAfterHysteresis,
- interactor.connectionState,
- interactor.isWifiActive,
- airplaneModeRepository.isAirplaneMode,
- ) { showForOos, connectionState, isWifiActive, isAirplaneMode ->
- if (isWifiActive || isAirplaneMode) {
- false
- } else {
- showForOos ||
- connectionState == SatelliteConnectionState.On ||
- connectionState == SatelliteConnectionState.Connected
+ canShowIcon
+ .flatMapLatest { canShow ->
+ if (!canShow) {
+ flowOf(false)
+ } else {
+ combine(
+ shouldShowIconForOosAfterHysteresis,
+ interactor.isAnyConnectionNtn,
+ interactor.connectionState,
+ interactor.isWifiActive,
+ airplaneModeRepository.isAirplaneMode,
+ ) { showForOos, anyNtn, connectionState, isWifiActive, isAirplaneMode ->
+ // anyNtn means that there is some mobile network using ntn, and the
+ // mobile icon will show its own satellite icon
+ if (isWifiActive || isAirplaneMode || anyNtn) {
+ false
+ } else {
+ // Show for out of service (which has a hysteresis), or ignore
+ // the hysteresis if we're already connected
+ showForOos ||
+ connectionState == SatelliteConnectionState.On ||
+ connectionState == SatelliteConnectionState.Connected
+ }
}
}
}
- }
- .distinctUntilChanged()
- .logDiffsForTable(
- tableLog,
- columnPrefix = "vm",
- columnName = COL_VISIBLE,
- initialValue = false,
- )
+ .distinctUntilChanged()
+ .logDiffsForTable(
+ tableLog,
+ columnPrefix = "vm",
+ columnName = COL_VISIBLE,
+ initialValue = false,
+ )
} else {
flowOf(false)
}
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 72df027..d9b2bd1d 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
@@ -20,9 +20,9 @@
import android.animation.AnimatorListenerAdapter
import android.view.View
import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.app.animation.Interpolators
-import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.Flags
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lifecycle.repeatWhenAttached
@@ -31,16 +31,19 @@
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.chips.ui.binder.OngoingActivityChipBinder
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
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.icon.ui.viewbinder.ConnectedDisplaysStatusBarNotificationIconViewStore
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
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel.VisibilityModel
import javax.inject.Inject
+import kotlinx.coroutines.launch
/**
* Interface to assist with binding the [CollapsedStatusBarFragment] to [HomeStatusBarViewModel].
@@ -56,6 +59,7 @@
* to support the chip animations.
*/
fun bind(
+ displayId: Int,
view: View,
viewModel: HomeStatusBarViewModel,
systemEventChipAnimateIn: ((View) -> Unit)?,
@@ -65,8 +69,13 @@
}
@SysUISingleton
-class HomeStatusBarViewBinderImpl @Inject constructor() : HomeStatusBarViewBinder {
+class HomeStatusBarViewBinderImpl
+@Inject
+constructor(
+ private val viewStoreFactory: ConnectedDisplaysStatusBarNotificationIconViewStore.Factory
+) : HomeStatusBarViewBinder {
override fun bind(
+ displayId: Int,
view: View,
viewModel: HomeStatusBarViewModel,
systemEventChipAnimateIn: ((View) -> Unit)?,
@@ -75,6 +84,14 @@
) {
view.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.CREATED) {
+ val iconViewStore =
+ if (StatusBarConnectedDisplays.isEnabled) {
+ viewStoreFactory.create(displayId).also {
+ lifecycleScope.launch { it.activate() }
+ }
+ } else {
+ null
+ }
launch {
viewModel.isTransitioningFromLockscreenToOccluded.collect {
listener.onStatusBarVisibilityMaybeChanged()
@@ -102,7 +119,11 @@
view.requireViewById(R.id.ongoing_activity_chip_primary)
launch {
viewModel.primaryOngoingActivityChip.collect { primaryChipModel ->
- OngoingActivityChipBinder.bind(primaryChipModel, primaryChipView)
+ OngoingActivityChipBinder.bind(
+ primaryChipModel,
+ primaryChipView,
+ iconViewStore,
+ )
if (StatusBarRootModernization.isEnabled) {
when (primaryChipModel) {
is OngoingActivityChipModel.Shown ->
@@ -142,10 +163,18 @@
view.requireViewById(R.id.ongoing_activity_chip_secondary)
launch {
viewModel.ongoingActivityChips.collect { chips ->
- OngoingActivityChipBinder.bind(chips.primary, primaryChipView)
+ OngoingActivityChipBinder.bind(
+ chips.primary,
+ primaryChipView,
+ iconViewStore,
+ )
// TODO(b/364653005): Don't show the secondary chip if there isn't
// enough space for it.
- OngoingActivityChipBinder.bind(chips.secondary, secondaryChipView)
+ OngoingActivityChipBinder.bind(
+ chips.secondary,
+ secondaryChipView,
+ iconViewStore,
+ )
if (StatusBarRootModernization.isEnabled) {
primaryChipView.adjustVisibility(chips.primary.toVisibilityModel())
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 812e0eb..5614d82 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
@@ -176,6 +176,7 @@
// This binder handles everything else
scope.launch {
statusBarViewBinder.bind(
+ context.displayId,
phoneStatusBarView,
statusBarViewModel,
eventAnimationInteractor::animateStatusBarContentForChipEnter,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 16d5f8d..2b0bf1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -24,7 +24,6 @@
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
-import android.content.res.TypedArray;
import android.graphics.BlendMode;
import android.graphics.Color;
import android.graphics.PorterDuff;
@@ -174,11 +173,8 @@
mTextWatcher = new SendButtonTextWatcher();
mEditorActionHandler = new EditorActionHandler();
mUiEventLogger = Dependency.get(UiEventLogger.class);
- TypedArray ta = getContext().getTheme().obtainStyledAttributes(new int[]{
- com.android.internal.R.attr.materialColorSurfaceDim,
- });
- mLastBackgroundColor = ta.getColor(0, 0);
- ta.recycle();
+ mLastBackgroundColor = getContext().getColor(
+ com.android.internal.R.color.materialColorSurfaceDim);
}
// TODO(b/193539698): move to Controller, since we're just directly accessing a system service
@@ -229,13 +225,10 @@
textColor = mContext.getColorStateList(R.color.remote_input_text);
hintColor = mContext.getColor(R.color.remote_input_hint);
deleteFgColor = textColor.getDefaultColor();
- try (TypedArray ta = getContext().getTheme().obtainStyledAttributes(new int[]{
- com.android.internal.R.attr.materialColorSurfaceDim,
- com.android.internal.R.attr.materialColorSurfaceVariant
- })) {
- editBgColor = ta.getColor(0, backgroundColor);
- deleteBgColor = ta.getColor(1, Color.GRAY);
- }
+ editBgColor = getContext().getColor(
+ com.android.internal.R.color.materialColorSurfaceDim);
+ deleteBgColor = getContext().getColor(
+ com.android.internal.R.color.materialColorSurfaceVariant);
}
mEditText.setTextColor(textColor);
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
index 7475388..0a10b44 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
@@ -18,7 +18,7 @@
import android.os.VibrationEffect
import android.view.View
-import androidx.annotation.AttrRes
+import androidx.annotation.ColorRes
import com.android.internal.logging.InstanceId
import com.android.systemui.common.shared.model.Text
import com.android.systemui.common.shared.model.TintedIcon
@@ -52,8 +52,8 @@
) : TemporaryViewInfo() {
companion object {
// LINT.IfChange
- @AttrRes val DEFAULT_ICON_TINT = com.android.internal.R.attr.materialColorOnSecondaryFixed
- // LINT.ThenChange(systemui/res/layout/chipbar.xml)
+ @ColorRes val DEFAULT_ICON_TINT = com.android.internal.R.color.materialColorOnSecondaryFixed
+ // LINT.ThenChange(/packages/SystemUI/res/layout/chipbar.xml)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/domain/VolumeDialogRingerInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/domain/VolumeDialogRingerInteractor.kt
index b83613b..4071918 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/domain/VolumeDialogRingerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/domain/VolumeDialogRingerInteractor.kt
@@ -20,7 +20,6 @@
import android.media.AudioManager.RINGER_MODE_NORMAL
import android.media.AudioManager.RINGER_MODE_SILENT
import android.media.AudioManager.RINGER_MODE_VIBRATE
-import android.provider.Settings
import com.android.settingslib.volume.data.repository.AudioSystemRepository
import com.android.settingslib.volume.shared.model.RingerMode
import com.android.systemui.plugins.VolumeDialogController
@@ -66,11 +65,6 @@
}
},
currentRingerMode = RingerMode(state.ringerModeInternal),
- isEnabled =
- !(state.zenMode == Settings.Global.ZEN_MODE_ALARMS ||
- state.zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS ||
- (state.zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS &&
- state.disallowRinger)),
isMuted = it.level == 0 || it.muted,
level = it.level,
levelMax = it.levelMax,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/shared/model/VolumeDialogRingerModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/shared/model/VolumeDialogRingerModel.kt
index 3c24e02..84a8280 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/shared/model/VolumeDialogRingerModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/shared/model/VolumeDialogRingerModel.kt
@@ -23,8 +23,6 @@
val availableModes: List<RingerMode>,
/** Current ringer mode internal */
val currentRingerMode: RingerMode,
- /** whether the ringer is allowed given the current ZenMode */
- val isEnabled: Boolean,
/** Whether the current ring stream level is zero or the controller state is muted */
val isMuted: Boolean,
/** Ring stream level */
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
index 3bd2721..f04fb2c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
@@ -30,10 +30,10 @@
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
import com.android.internal.R as internalR
-import com.android.settingslib.Utils
import com.android.systemui.res.R
import com.android.systemui.util.children
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
+import com.android.systemui.volume.dialog.ringer.ui.util.VolumeDialogRingerDrawerTransitionListener
import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerButtonUiModel
import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerButtonViewModel
import com.android.systemui.volume.dialog.ringer.ui.viewmodel.RingerDrawerState
@@ -42,6 +42,7 @@
import com.android.systemui.volume.dialog.ringer.ui.viewmodel.VolumeDialogRingerDrawerViewModel
import com.android.systemui.volume.dialog.ui.utils.suspendAnimate
import javax.inject.Inject
+import kotlin.properties.Delegates
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.launchIn
@@ -71,6 +72,27 @@
val drawerContainer = view.requireViewById<MotionLayout>(R.id.volume_ringer_drawer)
val unselectedButtonUiModel = RingerButtonUiModel.getUnselectedButton(view.context)
val selectedButtonUiModel = RingerButtonUiModel.getSelectedButton(view.context)
+ val volumeDialogBgSmallRadius =
+ view.context.resources.getDimensionPixelSize(
+ R.dimen.volume_dialog_background_square_corner_radius
+ )
+ val volumeDialogBgFullRadius =
+ view.context.resources.getDimensionPixelSize(
+ R.dimen.volume_dialog_background_corner_radius
+ )
+ var backgroundAnimationProgress: Float by
+ Delegates.observable(0F) { _, _, progress ->
+ volumeDialogBackgroundView.applyCorners(
+ fullRadius = volumeDialogBgFullRadius,
+ diff = volumeDialogBgFullRadius - volumeDialogBgSmallRadius,
+ progress,
+ )
+ }
+ val ringerDrawerTransitionListener = VolumeDialogRingerDrawerTransitionListener {
+ backgroundAnimationProgress = it
+ }
+ drawerContainer.setTransitionListener(ringerDrawerTransitionListener)
+ volumeDialogBackgroundView.background = volumeDialogBackgroundView.background.mutate()
viewModel.ringerViewModel
.onEach { ringerState ->
when (ringerState) {
@@ -87,10 +109,8 @@
selectedButtonUiModel,
unselectedButtonUiModel,
)
+ ringerDrawerTransitionListener.setProgressChangeEnabled(true)
drawerContainer.closeDrawer(uiModel.currentButtonIndex)
- volumeDialogBackgroundView.setBackgroundResource(
- R.drawable.volume_dialog_background
- )
}
is RingerDrawerState.Closed -> {
@@ -103,11 +123,31 @@
uiModel,
selectedButtonUiModel,
unselectedButtonUiModel,
+ onProgressChanged = { progress, isReverse ->
+ // Let's make button progress when switching matches
+ // motionLayout transition progress. When full radius,
+ // progress is 0.0. When small radius, progress is 1.0.
+ backgroundAnimationProgress =
+ if (isReverse) {
+ 1F - progress
+ } else {
+ progress
+ }
+ },
) {
+ if (
+ uiModel.currentButtonIndex ==
+ uiModel.availableButtons.size - 1
+ ) {
+ ringerDrawerTransitionListener.setProgressChangeEnabled(
+ false
+ )
+ } else {
+ ringerDrawerTransitionListener.setProgressChangeEnabled(
+ true
+ )
+ }
drawerContainer.closeDrawer(uiModel.currentButtonIndex)
- volumeDialogBackgroundView.setBackgroundResource(
- R.drawable.volume_dialog_background
- )
}
}
}
@@ -120,16 +160,18 @@
unselectedButtonUiModel,
)
// Open drawer
+ if (
+ uiModel.currentButtonIndex == uiModel.availableButtons.size - 1
+ ) {
+ ringerDrawerTransitionListener.setProgressChangeEnabled(false)
+ } else {
+ ringerDrawerTransitionListener.setProgressChangeEnabled(true)
+ }
drawerContainer.transitionToState(
R.id.volume_dialog_ringer_drawer_open
)
- if (
- uiModel.currentButtonIndex != uiModel.availableButtons.size - 1
- ) {
- volumeDialogBackgroundView.setBackgroundResource(
- R.drawable.volume_dialog_background_small_radius
- )
- }
+ volumeDialogBackgroundView.background =
+ volumeDialogBackgroundView.background.mutate()
}
}
}
@@ -150,6 +192,7 @@
uiModel: RingerViewModel,
selectedButtonUiModel: RingerButtonUiModel,
unselectedButtonUiModel: RingerButtonUiModel,
+ onProgressChanged: (Float, Boolean) -> Unit = { _, _ -> },
onAnimationEnd: Runnable? = null,
) {
ensureChildCount(R.layout.volume_ringer_button, uiModel.availableButtons.size)
@@ -177,10 +220,26 @@
CLOSE_DRAWER_DELAY,
)
}
-
- // We only need to execute on roundness animation end once.
- selectedButton.animateTo(selectedButtonUiModel, roundnessAnimationEndListener)
- unselectedButton.animateTo(unselectedButtonUiModel)
+ // We only need to execute on roundness animation end and volume dialog background
+ // progress update once because these changes should be applied once on volume dialog
+ // background and ringer drawer views.
+ selectedButton.animateTo(
+ selectedButtonUiModel,
+ if (uiModel.currentButtonIndex == count - 1) {
+ onProgressChanged
+ } else {
+ { _, _ -> }
+ },
+ roundnessAnimationEndListener,
+ )
+ unselectedButton.animateTo(
+ unselectedButtonUiModel,
+ if (previousIndex == count - 1) {
+ onProgressChanged
+ } else {
+ { _, _ -> }
+ },
+ )
} else {
bindButtons(viewModel, uiModel, onAnimationEnd)
}
@@ -234,15 +293,11 @@
}
if (isSelected && !isAnimated) {
setBackgroundResource(R.drawable.volume_drawer_selection_bg)
- setColorFilter(
- Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorOnPrimary)
- )
+ setColorFilter(context.getColor(internalR.color.materialColorOnPrimary))
background = background.mutate()
} else if (!isAnimated) {
setBackgroundResource(R.drawable.volume_ringer_item_bg)
- setColorFilter(
- Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorOnSurface)
- )
+ setColorFilter(context.getColor(internalR.color.materialColorOnSurface))
background = background.mutate()
}
setOnClickListener {
@@ -366,6 +421,7 @@
private suspend fun ImageButton.animateTo(
ringerButtonUiModel: RingerButtonUiModel,
+ onProgressChanged: (Float, Boolean) -> Unit = { _, _ -> },
roundnessAnimationEndListener: DynamicAnimation.OnAnimationEndListener? = null,
) {
val roundnessAnimation =
@@ -376,6 +432,7 @@
ringerButtonUiModel.cornerRadius - (background as GradientDrawable).cornerRadius
val roundnessAnimationUpdateListener =
DynamicAnimation.OnAnimationUpdateListener { _, value, _ ->
+ onProgressChanged(value, cornerRadiusDiff > 0F)
(background as GradientDrawable).cornerRadius = radius + value * cornerRadiusDiff
background.invalidateSelf()
}
@@ -406,4 +463,9 @@
)
}
}
+
+ private fun View.applyCorners(fullRadius: Int, diff: Int, progress: Float) {
+ (background as GradientDrawable).cornerRadius = fullRadius - progress * diff
+ background.invalidateSelf()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/VolumeDialogRingerDrawerTransitionListener.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/VolumeDialogRingerDrawerTransitionListener.kt
new file mode 100644
index 0000000..6e3db0a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/VolumeDialogRingerDrawerTransitionListener.kt
@@ -0,0 +1,51 @@
+/*
+ * 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.volume.dialog.ringer.ui.util
+
+import androidx.constraintlayout.motion.widget.MotionLayout
+
+class VolumeDialogRingerDrawerTransitionListener(private val onProgressChanged: (Float) -> Unit) :
+ MotionLayout.TransitionListener {
+
+ private var notifyProgressChangeEnabled = true
+
+ fun setProgressChangeEnabled(enabled: Boolean) {
+ notifyProgressChangeEnabled = enabled
+ }
+
+ override fun onTransitionStarted(motionLayout: MotionLayout?, startId: Int, endId: Int) {}
+
+ override fun onTransitionChange(
+ motionLayout: MotionLayout?,
+ startId: Int,
+ endId: Int,
+ progress: Float,
+ ) {
+ if (notifyProgressChangeEnabled) {
+ onProgressChanged(progress)
+ }
+ }
+
+ override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {}
+
+ override fun onTransitionTrigger(
+ motionLayout: MotionLayout?,
+ triggerId: Int,
+ positive: Boolean,
+ progress: Float,
+ ) {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/RingerButtonUiModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/RingerButtonUiModel.kt
index 3c46567..832f1c3 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/RingerButtonUiModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/RingerButtonUiModel.kt
@@ -31,30 +31,20 @@
companion object {
fun getUnselectedButton(context: Context): RingerButtonUiModel {
return RingerButtonUiModel(
- tintColor =
- Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorOnSurface),
- backgroundColor =
- Utils.getColorAttrDefaultColor(
- context,
- internalR.attr.materialColorSurfaceContainerHighest,
- ),
- cornerRadius =
- context.resources.getDimensionPixelSize(
- R.dimen.volume_dialog_background_square_corner_radius
- ),
+ tintColor = context.getColor(internalR.color.materialColorOnSurface),
+ backgroundColor = context.getColor(
+ internalR.color.materialColorSurfaceContainerHighest),
+ cornerRadius = context.resources.getDimensionPixelSize(
+ R.dimen.volume_dialog_background_square_corner_radius),
)
}
fun getSelectedButton(context: Context): RingerButtonUiModel {
return RingerButtonUiModel(
- tintColor =
- Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorOnPrimary),
- backgroundColor =
- Utils.getColorAttrDefaultColor(context, internalR.attr.materialColorPrimary),
- cornerRadius =
- context.resources.getDimensionPixelSize(
- R.dimen.volume_dialog_ringer_selected_button_background_radius
- ),
+ tintColor = context.getColor(internalR.color.materialColorOnPrimary),
+ backgroundColor = context.getColor(internalR.color.materialColorPrimary),
+ cornerRadius = context.resources.getDimensionPixelSize(
+ R.dimen.volume_dialog_ringer_selected_button_background_radius),
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt
index e646636..627d75e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt
@@ -21,10 +21,13 @@
import android.media.AudioManager.RINGER_MODE_NORMAL
import android.media.AudioManager.RINGER_MODE_SILENT
import android.media.AudioManager.RINGER_MODE_VIBRATE
+import android.media.AudioManager.STREAM_RING
import android.os.VibrationEffect
import android.widget.Toast
import com.android.internal.R as internalR
import com.android.settingslib.Utils
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor
+import com.android.settingslib.volume.shared.model.AudioStream
import com.android.settingslib.volume.shared.model.RingerMode
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
@@ -57,7 +60,8 @@
@Application private val applicationContext: Context,
@VolumeDialog private val coroutineScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
- private val interactor: VolumeDialogRingerInteractor,
+ soundPolicyInteractor: NotificationsSoundPolicyInteractor,
+ private val ringerInteractor: VolumeDialogRingerInteractor,
private val vibrator: VibratorHelper,
private val volumeDialogLogger: VolumeDialogLogger,
private val visibilityInteractor: VolumeDialogVisibilityInteractor,
@@ -66,10 +70,14 @@
private val drawerState = MutableStateFlow<RingerDrawerState>(RingerDrawerState.Initial)
val ringerViewModel: StateFlow<RingerViewModelState> =
- combine(interactor.ringerModel, drawerState) { ringerModel, state ->
+ combine(
+ soundPolicyInteractor.isZenMuted(AudioStream(STREAM_RING)),
+ ringerInteractor.ringerModel,
+ drawerState,
+ ) { isZenMuted, ringerModel, state ->
level = ringerModel.level
levelMax = ringerModel.levelMax
- ringerModel.toViewModel(state)
+ ringerModel.toViewModel(state, isZenMuted)
}
.flowOn(backgroundDispatcher)
.stateIn(coroutineScope, SharingStarted.Eagerly, RingerViewModelState.Unavailable)
@@ -90,7 +98,7 @@
Events.writeEvent(Events.EVENT_RINGER_TOGGLE, ringerMode.value)
provideTouchFeedback(ringerMode)
maybeShowToast(ringerMode)
- interactor.setRingerMode(ringerMode)
+ ringerInteractor.setRingerMode(ringerMode)
}
visibilityInteractor.resetDismissTimeout()
drawerState.value =
@@ -113,7 +121,7 @@
private fun provideTouchFeedback(ringerMode: RingerMode) {
when (ringerMode.value) {
RINGER_MODE_NORMAL -> {
- interactor.scheduleTouchFeedback()
+ ringerInteractor.scheduleTouchFeedback()
null
}
RINGER_MODE_SILENT -> VibrationEffect.get(VibrationEffect.EFFECT_CLICK)
@@ -123,7 +131,8 @@
}
private fun VolumeDialogRingerModel.toViewModel(
- drawerState: RingerDrawerState
+ drawerState: RingerDrawerState,
+ isZenMuted: Boolean,
): RingerViewModelState {
val currentIndex = availableModes.indexOf(currentRingerMode)
if (currentIndex == -1) {
@@ -132,10 +141,11 @@
return if (currentIndex == -1 || isSingleVolume) {
RingerViewModelState.Unavailable
} else {
- toButtonViewModel(currentRingerMode, isSelectedButton = true)?.let {
+ toButtonViewModel(currentRingerMode, isZenMuted, isSelectedButton = true)?.let {
RingerViewModelState.Available(
RingerViewModel(
- availableButtons = availableModes.map { mode -> toButtonViewModel(mode) },
+ availableButtons =
+ availableModes.map { mode -> toButtonViewModel(mode, isZenMuted) },
currentButtonIndex = currentIndex,
selectedButton = it,
drawerState = drawerState,
@@ -147,6 +157,7 @@
private fun VolumeDialogRingerModel.toButtonViewModel(
ringerMode: RingerMode,
+ isZenMuted: Boolean,
isSelectedButton: Boolean = false,
): RingerButtonViewModel? {
return when (ringerMode.value) {
@@ -176,7 +187,7 @@
)
RINGER_MODE_NORMAL ->
when {
- isMuted && isEnabled ->
+ isMuted && !isZenMuted ->
RingerButtonViewModel(
imageResId =
if (isSelectedButton) {
@@ -226,7 +237,7 @@
private fun maybeShowToast(ringerMode: RingerMode) {
coroutineScope.launch {
- val seenToastCount = interactor.getToastCount()
+ val seenToastCount = ringerInteractor.getToastCount()
if (seenToastCount > SHOW_RINGER_TOAST_COUNT) {
return@launch
}
@@ -260,7 +271,7 @@
)
}
toastText?.let { Toast.makeText(applicationContext, it, Toast.LENGTH_SHORT).show() }
- interactor.updateToastCount(seenToastCount)
+ ringerInteractor.updateToastCount(seenToastCount)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
index e52bad9..f305246 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
@@ -18,11 +18,12 @@
import android.animation.Animator
import android.animation.ObjectAnimator
+import android.annotation.SuppressLint
import android.view.View
import android.view.animation.DecelerateInterpolator
import com.android.systemui.res.R
-import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
+import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderStateModel
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderViewModel
import com.android.systemui.volume.dialog.ui.utils.JankListenerFactory
import com.android.systemui.volume.dialog.ui.utils.awaitAnimation
@@ -48,24 +49,27 @@
val sliderView: Slider =
view.requireViewById<Slider>(R.id.volume_dialog_slider).apply {
labelBehavior = LabelFormatter.LABEL_GONE
+ trackIconActiveColor = trackInactiveTintList
}
sliderView.addOnChangeListener { _, value, fromUser ->
viewModel.setStreamVolume(value.roundToInt(), fromUser)
}
- viewModel.model.onEach { it.bindToSlider(sliderView) }.launchIn(this)
+ viewModel.state.onEach { it.bindToSlider(sliderView) }.launchIn(this)
}
- private suspend fun VolumeDialogStreamModel.bindToSlider(slider: Slider) {
+ @SuppressLint("UseCompatLoadingForDrawables")
+ private suspend fun VolumeDialogSliderStateModel.bindToSlider(slider: Slider) {
with(slider) {
- valueFrom = levelMin.toFloat()
- valueTo = levelMax.toFloat()
+ valueFrom = minValue
+ valueTo = maxValue
// coerce the current value to the new value range before animating it
value = value.coerceIn(valueFrom, valueTo)
setValueAnimated(
- level.toFloat(),
+ value,
jankListenerFactory.update(this, PROGRESS_CHANGE_ANIMATION_DURATION_MS),
)
+ trackIconActiveEnd = context.getDrawable(iconRes)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt
new file mode 100644
index 0000000..5c39b6f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt
@@ -0,0 +1,122 @@
+/*
+ * 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.volume.dialog.sliders.ui.viewmodel
+
+import android.media.AudioManager
+import androidx.annotation.DrawableRes
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor
+import com.android.settingslib.volume.domain.interactor.AudioVolumeInteractor
+import com.android.settingslib.volume.shared.model.AudioStream
+import com.android.settingslib.volume.shared.model.RingerMode
+import com.android.systemui.res.R
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flowOf
+
+class VolumeDialogSliderIconProvider
+@Inject
+constructor(
+ private val notificationsSoundPolicyInteractor: NotificationsSoundPolicyInteractor,
+ private val audioVolumeInteractor: AudioVolumeInteractor,
+) {
+
+ @DrawableRes
+ fun getStreamIcon(
+ stream: Int,
+ level: Int,
+ levelMin: Int,
+ levelMax: Int,
+ isMuted: Boolean,
+ isRoutedToBluetooth: Boolean,
+ ): Flow<Int> {
+ return combine(
+ notificationsSoundPolicyInteractor.isZenMuted(AudioStream(stream)),
+ ringerModeForStream(stream),
+ ) { isZenMuted, ringerMode ->
+ val isStreamOffline = level == 0 || isMuted
+ if (isZenMuted) {
+ // TODO(b/372466264) use icon for the corresponding zenmode
+ return@combine com.android.internal.R.drawable.ic_qs_dnd
+ }
+ when (ringerMode?.value) {
+ AudioManager.RINGER_MODE_VIBRATE ->
+ return@combine R.drawable.ic_volume_ringer_vibrate
+ AudioManager.RINGER_MODE_SILENT -> return@combine R.drawable.ic_ring_volume_off
+ }
+ if (isRoutedToBluetooth) {
+ return@combine if (stream == AudioManager.STREAM_VOICE_CALL) {
+ R.drawable.ic_volume_bt_sco
+ } else {
+ if (isStreamOffline) {
+ R.drawable.ic_volume_media_bt_mute
+ } else {
+ R.drawable.ic_volume_media_bt
+ }
+ }
+ }
+
+ return@combine if (isStreamOffline) {
+ getMutedIconForStream(stream) ?: getIconForStream(stream)
+ } else {
+ if (level < (levelMax + levelMin) / 2) {
+ // This icon is different on TV
+ R.drawable.ic_volume_media_low
+ } else {
+ getIconForStream(stream)
+ }
+ }
+ }
+ }
+
+ @DrawableRes
+ private fun getMutedIconForStream(stream: Int): Int? {
+ return when (stream) {
+ AudioManager.STREAM_MUSIC -> R.drawable.ic_volume_media_mute
+ AudioManager.STREAM_NOTIFICATION -> R.drawable.ic_volume_ringer_mute
+ AudioManager.STREAM_ALARM -> R.drawable.ic_volume_alarm_mute
+ AudioManager.STREAM_SYSTEM -> R.drawable.ic_volume_system_mute
+ else -> null
+ }
+ }
+
+ @DrawableRes
+ private fun getIconForStream(stream: Int): Int {
+ return when (stream) {
+ AudioManager.STREAM_ACCESSIBILITY -> R.drawable.ic_volume_accessibility
+ AudioManager.STREAM_MUSIC -> R.drawable.ic_volume_media
+ AudioManager.STREAM_RING -> R.drawable.ic_ring_volume
+ AudioManager.STREAM_NOTIFICATION -> R.drawable.ic_volume_ringer
+ AudioManager.STREAM_ALARM -> R.drawable.ic_alarm
+ AudioManager.STREAM_VOICE_CALL -> com.android.internal.R.drawable.ic_phone
+ AudioManager.STREAM_SYSTEM -> R.drawable.ic_volume_system
+ else -> error("Unsupported stream: $stream")
+ }
+ }
+
+ /**
+ * Emits [RingerMode] for the [stream] if it's affecting it and null when [RingerMode] doesn't
+ * affect the [stream]
+ */
+ private fun ringerModeForStream(stream: Int): Flow<RingerMode?> {
+ return if (stream == AudioManager.STREAM_RING) {
+ audioVolumeInteractor.ringerMode
+ } else {
+ flowOf(null)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderStateModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderStateModel.kt
new file mode 100644
index 0000000..5750c04
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderStateModel.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.volume.dialog.sliders.ui.viewmodel
+
+import androidx.annotation.DrawableRes
+import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
+
+data class VolumeDialogSliderStateModel(
+ val minValue: Float,
+ val maxValue: Float,
+ val value: Float,
+ @DrawableRes val iconRes: Int,
+)
+
+fun VolumeDialogStreamModel.toStateModel(@DrawableRes iconRes: Int): VolumeDialogSliderStateModel {
+ return VolumeDialogSliderStateModel(
+ minValue = levelMin.toFloat(),
+ value = level.toFloat(),
+ maxValue = levelMax.toFloat(),
+ iconRes = iconRes,
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
index 6dd5b63..2d56524 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
@@ -32,7 +32,9 @@
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.stateIn
@@ -56,12 +58,12 @@
private val interactor: VolumeDialogSliderInteractor,
private val visibilityInteractor: VolumeDialogVisibilityInteractor,
@VolumeDialog private val coroutineScope: CoroutineScope,
+ private val volumeDialogSliderIconProvider: VolumeDialogSliderIconProvider,
private val systemClock: SystemClock,
) {
private val userVolumeUpdates = MutableStateFlow<VolumeUpdate?>(null)
-
- val model: Flow<VolumeDialogStreamModel> =
+ private val model: Flow<VolumeDialogStreamModel> =
interactor.slider
.filter {
val lastVolumeUpdateTime = userVolumeUpdates.value?.timestampMillis ?: 0
@@ -70,6 +72,21 @@
.stateIn(coroutineScope, SharingStarted.Eagerly, null)
.filterNotNull()
+ val state: Flow<VolumeDialogSliderStateModel> =
+ model.flatMapLatest { streamModel ->
+ with(streamModel) {
+ volumeDialogSliderIconProvider.getStreamIcon(
+ stream = stream,
+ level = level,
+ levelMin = levelMin,
+ levelMax = levelMax,
+ isMuted = muted,
+ isRoutedToBluetooth = routedToBluetooth,
+ )
+ }
+ .map { icon -> streamModel.toStateModel(icon) }
+ }
+
init {
userVolumeUpdates
.filterNotNull()
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt
index 02747d7..6c4a853 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt
@@ -80,10 +80,10 @@
label = label,
labelColor =
if (Flags.volumeRedesign()) {
- Color.Attribute(com.android.internal.R.attr.materialColorOnSurface)
+ Color.Resource(com.android.internal.R.color.materialColorOnSurface)
} else {
- Color.Attribute(
- com.android.internal.R.attr.materialColorOnSurfaceVariant
+ Color.Resource(
+ com.android.internal.R.color.materialColorOnSurfaceVariant
)
},
deviceName =
@@ -96,10 +96,10 @@
},
deviceNameColor =
if (mediaOutputModel.canOpenAudioSwitcher) {
- Color.Attribute(com.android.internal.R.attr.materialColorOnSurface)
+ Color.Resource(com.android.internal.R.color.materialColorOnSurface)
} else {
- Color.Attribute(
- com.android.internal.R.attr.materialColorOnSurfaceVariant
+ Color.Resource(
+ com.android.internal.R.color.materialColorOnSurfaceVariant
)
},
)
@@ -126,32 +126,32 @@
iconColor =
if (mediaOutputModel.canOpenAudioSwitcher) {
if (Flags.volumeRedesign()) {
- Color.Attribute(
- com.android.internal.R.attr.materialColorOnPrimary
+ Color.Resource(
+ com.android.internal.R.color.materialColorOnPrimary
)
} else {
- Color.Attribute(
- com.android.internal.R.attr.materialColorSurface
+ Color.Resource(
+ com.android.internal.R.color.materialColorSurface
)
}
} else {
- Color.Attribute(
- com.android.internal.R.attr.materialColorSurfaceContainerHighest
+ Color.Resource(
+ com.android.internal.R.color.materialColorSurfaceContainerHighest
)
},
backgroundColor =
if (mediaOutputModel.canOpenAudioSwitcher) {
if (Flags.volumeRedesign()) {
- Color.Attribute(
- com.android.internal.R.attr.materialColorPrimary
+ Color.Resource(
+ com.android.internal.R.color.materialColorPrimary
)
} else {
- Color.Attribute(
- com.android.internal.R.attr.materialColorSecondary
+ Color.Resource(
+ com.android.internal.R.color.materialColorSecondary
)
}
} else {
- Color.Attribute(com.android.internal.R.attr.materialColorOutline)
+ Color.Resource(com.android.internal.R.color.materialColorOutline)
},
)
} else {
@@ -160,16 +160,16 @@
iconColor =
if (mediaOutputModel.canOpenAudioSwitcher) {
if (Flags.volumeRedesign()) {
- Color.Attribute(
- com.android.internal.R.attr.materialColorPrimary
+ Color.Resource(
+ com.android.internal.R.color.materialColorPrimary
)
} else {
- Color.Attribute(
- com.android.internal.R.attr.materialColorOnSurfaceVariant
+ Color.Resource(
+ com.android.internal.R.color.materialColorOnSurfaceVariant
)
}
} else {
- Color.Attribute(com.android.internal.R.attr.materialColorOutline)
+ Color.Resource(com.android.internal.R.color.materialColorOutline)
},
backgroundColor = Color.Loaded(GraphicsColor.TRANSPARENT),
)
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index f347d48..a41725f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -529,6 +529,8 @@
fun listenForDnd_onDndChange_updatesClockZenMode() =
testScope.runTest {
underTest.listenForDnd(testScope.backgroundScope)
+ runCurrent()
+ clearInvocations(events)
zenModeRepository.activateMode(dndModeId)
runCurrent()
@@ -537,7 +539,6 @@
.onZenDataChanged(
eq(ZenData(ZenMode.IMPORTANT_INTERRUPTIONS, R.string::dnd_is_on.name))
)
- clearInvocations(events)
zenModeRepository.deactivateMode(dndModeId)
runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorParameterizedTest.kt
new file mode 100644
index 0000000..d7fcb6a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorParameterizedTest.kt
@@ -0,0 +1,471 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.education.domain.interactor
+
+import android.content.pm.UserInfo
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.contextualeducation.GestureType
+import com.android.systemui.contextualeducation.GestureType.ALL_APPS
+import com.android.systemui.contextualeducation.GestureType.BACK
+import com.android.systemui.contextualeducation.GestureType.HOME
+import com.android.systemui.contextualeducation.GestureType.OVERVIEW
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.education.data.model.GestureEduModel
+import com.android.systemui.education.data.repository.contextualEducationRepository
+import com.android.systemui.education.data.repository.fakeEduClock
+import com.android.systemui.education.shared.model.EducationUiType
+import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType
+import com.android.systemui.inputdevice.tutorial.tutorialSchedulerRepository
+import com.android.systemui.keyboard.data.repository.keyboardRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
+import com.android.systemui.testKosmos
+import com.android.systemui.touchpad.data.repository.touchpadRepository
+import com.android.systemui.user.data.repository.fakeUserRepository
+import com.google.common.truth.Truth.assertThat
+import kotlin.time.Duration.Companion.hours
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.verify
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+
+@SmallTest
+@RunWith(ParameterizedAndroidJunit4::class)
+@kotlinx.coroutines.ExperimentalCoroutinesApi
+class KeyboardTouchpadEduInteractorParameterizedTest(private val gestureType: GestureType) :
+ SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val contextualEduInteractor = kosmos.contextualEducationInteractor
+ private val repository = kosmos.contextualEducationRepository
+ private val touchpadRepository = kosmos.touchpadRepository
+ private val keyboardRepository = kosmos.keyboardRepository
+ private val tutorialSchedulerRepository = kosmos.tutorialSchedulerRepository
+ private val userRepository = kosmos.fakeUserRepository
+ private val overviewProxyService = kosmos.mockOverviewProxyService
+
+ private val underTest: KeyboardTouchpadEduInteractor = kosmos.keyboardTouchpadEduInteractor
+ private val eduClock = kosmos.fakeEduClock
+ private val minDurationForNextEdu =
+ KeyboardTouchpadEduInteractor.minIntervalBetweenEdu + 1.seconds
+ private val initialDelayElapsedDuration =
+ KeyboardTouchpadEduInteractor.initialDelayDuration + 1.seconds
+
+ @Before
+ fun setup() {
+ underTest.start()
+ contextualEduInteractor.start()
+ userRepository.setUserInfos(USER_INFOS)
+ testScope.launch {
+ contextualEduInteractor.updateKeyboardFirstConnectionTime()
+ contextualEduInteractor.updateTouchpadFirstConnectionTime()
+ }
+ }
+
+ @Test
+ fun newEducationInfoOnMaxSignalCountReached() =
+ testScope.runTest {
+ triggerMaxEducationSignals(gestureType)
+ val model by collectLastValue(underTest.educationTriggered)
+
+ assertThat(model?.gestureType).isEqualTo(gestureType)
+ }
+
+ @Test
+ fun newEducationToastOn1stEducation() =
+ testScope.runTest {
+ val model by collectLastValue(underTest.educationTriggered)
+ triggerMaxEducationSignals(gestureType)
+
+ assertThat(model?.educationUiType).isEqualTo(EducationUiType.Toast)
+ }
+
+ @Test
+ fun newEducationNotificationOn2ndEducation() =
+ testScope.runTest {
+ val model by collectLastValue(underTest.educationTriggered)
+ triggerMaxEducationSignals(gestureType)
+ // runCurrent() to trigger 1st education
+ runCurrent()
+
+ eduClock.offset(minDurationForNextEdu)
+ triggerMaxEducationSignals(gestureType)
+
+ assertThat(model?.educationUiType).isEqualTo(EducationUiType.Notification)
+ }
+
+ @Test
+ fun noEducationInfoBeforeMaxSignalCountReached() =
+ testScope.runTest {
+ contextualEduInteractor.incrementSignalCount(gestureType)
+ val model by collectLastValue(underTest.educationTriggered)
+ assertThat(model).isNull()
+ }
+
+ @Test
+ fun noEducationInfoWhenShortcutTriggeredPreviously() =
+ testScope.runTest {
+ val model by collectLastValue(underTest.educationTriggered)
+ contextualEduInteractor.updateShortcutTriggerTime(gestureType)
+ triggerMaxEducationSignals(gestureType)
+ assertThat(model).isNull()
+ }
+
+ @Test
+ fun no2ndEducationBeforeMinEduIntervalReached() =
+ testScope.runTest {
+ val models by collectValues(underTest.educationTriggered)
+ triggerMaxEducationSignals(gestureType)
+ runCurrent()
+
+ // Offset a duration that is less than the required education interval
+ eduClock.offset(1.seconds)
+ triggerMaxEducationSignals(gestureType)
+ runCurrent()
+
+ assertThat(models.filterNotNull().size).isEqualTo(1)
+ }
+
+ @Test
+ fun noNewEducationInfoAfterMaxEducationCountReached() =
+ testScope.runTest {
+ val models by collectValues(underTest.educationTriggered)
+ // Trigger 2 educations
+ triggerMaxEducationSignals(gestureType)
+ runCurrent()
+ eduClock.offset(minDurationForNextEdu)
+ triggerMaxEducationSignals(gestureType)
+ runCurrent()
+
+ // Try triggering 3rd education
+ eduClock.offset(minDurationForNextEdu)
+ triggerMaxEducationSignals(gestureType)
+
+ assertThat(models.filterNotNull().size).isEqualTo(2)
+ }
+
+ @Test
+ fun startNewUsageSessionWhen2ndSignalReceivedAfterSessionDeadline() =
+ testScope.runTest {
+ val model by
+ collectLastValue(
+ kosmos.contextualEducationRepository.readGestureEduModelFlow(gestureType)
+ )
+ contextualEduInteractor.incrementSignalCount(gestureType)
+ eduClock.offset(KeyboardTouchpadEduInteractor.usageSessionDuration.plus(1.seconds))
+ val secondSignalReceivedTime = eduClock.instant()
+ contextualEduInteractor.incrementSignalCount(gestureType)
+
+ assertThat(model)
+ .isEqualTo(
+ GestureEduModel(
+ signalCount = 1,
+ usageSessionStartTime = secondSignalReceivedTime,
+ userId = 0,
+ gestureType = gestureType,
+ )
+ )
+ }
+
+ @Test
+ fun newTouchpadConnectionTimeOnFirstTouchpadConnected() =
+ testScope.runTest {
+ setIsAnyTouchpadConnected(true)
+ val model = contextualEduInteractor.getEduDeviceConnectionTime()
+ assertThat(model.touchpadFirstConnectionTime).isEqualTo(eduClock.instant())
+ }
+
+ @Test
+ fun unchangedTouchpadConnectionTimeOnSecondConnection() =
+ testScope.runTest {
+ val firstConnectionTime = eduClock.instant()
+ setIsAnyTouchpadConnected(true)
+ setIsAnyTouchpadConnected(false)
+
+ eduClock.offset(1.hours)
+ setIsAnyTouchpadConnected(true)
+
+ val model = contextualEduInteractor.getEduDeviceConnectionTime()
+ assertThat(model.touchpadFirstConnectionTime).isEqualTo(firstConnectionTime)
+ }
+
+ @Test
+ fun newTouchpadConnectionTimeOnUserChanged() =
+ testScope.runTest {
+ // Touchpad connected for user 0
+ setIsAnyTouchpadConnected(true)
+
+ // Change user
+ eduClock.offset(1.hours)
+ val newUserFirstConnectionTime = eduClock.instant()
+ userRepository.setSelectedUserInfo(USER_INFOS[0])
+ runCurrent()
+
+ val model = contextualEduInteractor.getEduDeviceConnectionTime()
+ assertThat(model.touchpadFirstConnectionTime).isEqualTo(newUserFirstConnectionTime)
+ }
+
+ @Test
+ fun newKeyboardConnectionTimeOnKeyboardConnected() =
+ testScope.runTest {
+ setIsAnyKeyboardConnected(true)
+ val model = contextualEduInteractor.getEduDeviceConnectionTime()
+ assertThat(model.keyboardFirstConnectionTime).isEqualTo(eduClock.instant())
+ }
+
+ @Test
+ fun unchangedKeyboardConnectionTimeOnSecondConnection() =
+ testScope.runTest {
+ val firstConnectionTime = eduClock.instant()
+ setIsAnyKeyboardConnected(true)
+ setIsAnyKeyboardConnected(false)
+
+ eduClock.offset(1.hours)
+ setIsAnyKeyboardConnected(true)
+
+ val model = contextualEduInteractor.getEduDeviceConnectionTime()
+ assertThat(model.keyboardFirstConnectionTime).isEqualTo(firstConnectionTime)
+ }
+
+ @Test
+ fun newKeyboardConnectionTimeOnUserChanged() =
+ testScope.runTest {
+ // Keyboard connected for user 0
+ setIsAnyKeyboardConnected(true)
+
+ // Change user
+ eduClock.offset(1.hours)
+ val newUserFirstConnectionTime = eduClock.instant()
+ userRepository.setSelectedUserInfo(USER_INFOS[0])
+ runCurrent()
+
+ val model = contextualEduInteractor.getEduDeviceConnectionTime()
+ assertThat(model.keyboardFirstConnectionTime).isEqualTo(newUserFirstConnectionTime)
+ }
+
+ @Test
+ fun updateShortcutTimeOnKeyboardShortcutTriggered() =
+ testScope.runTest {
+ // Only All Apps needs to update the keyboard shortcut
+ assumeTrue(gestureType == ALL_APPS)
+ kosmos.contextualEducationRepository.setKeyboardShortcutTriggered(ALL_APPS)
+
+ val model by
+ collectLastValue(
+ kosmos.contextualEducationRepository.readGestureEduModelFlow(ALL_APPS)
+ )
+ assertThat(model?.lastShortcutTriggeredTime).isEqualTo(eduClock.instant())
+ }
+
+ @Test
+ fun dataUpdatedOnIncrementSignalCountWhenTouchpadConnected() =
+ testScope.runTest {
+ assumeTrue(gestureType != ALL_APPS)
+ setUpForInitialDelayElapse()
+ touchpadRepository.setIsAnyTouchpadConnected(true)
+
+ val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
+ val originalValue = model!!.signalCount
+ val listener = getOverviewProxyListener()
+ listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue + 1)
+ }
+
+ @Test
+ fun dataUnchangedOnIncrementSignalCountWhenTouchpadDisconnected() =
+ testScope.runTest {
+ setUpForInitialDelayElapse()
+ touchpadRepository.setIsAnyTouchpadConnected(false)
+
+ val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
+ val originalValue = model!!.signalCount
+ val listener = getOverviewProxyListener()
+ listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue)
+ }
+
+ @Test
+ fun dataUpdatedOnIncrementSignalCountWhenKeyboardConnected() =
+ testScope.runTest {
+ assumeTrue(gestureType == ALL_APPS)
+ setUpForInitialDelayElapse()
+ keyboardRepository.setIsAnyKeyboardConnected(true)
+
+ val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
+ val originalValue = model!!.signalCount
+ val listener = getOverviewProxyListener()
+ listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue + 1)
+ }
+
+ @Test
+ fun dataUnchangedOnIncrementSignalCountWhenKeyboardDisconnected() =
+ testScope.runTest {
+ setUpForInitialDelayElapse()
+ keyboardRepository.setIsAnyKeyboardConnected(false)
+
+ val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
+ val originalValue = model!!.signalCount
+ val listener = getOverviewProxyListener()
+ listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue)
+ }
+
+ @Test
+ fun dataAddedOnUpdateShortcutTriggerTime() =
+ testScope.runTest {
+ val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
+ assertThat(model?.lastShortcutTriggeredTime).isNull()
+
+ val listener = getOverviewProxyListener()
+ listener.updateContextualEduStats(/* isTrackpadGesture= */ true, gestureType)
+
+ assertThat(model?.lastShortcutTriggeredTime).isEqualTo(kosmos.fakeEduClock.instant())
+ }
+
+ @Test
+ fun dataUpdatedOnIncrementSignalCountAfterInitialDelay() =
+ testScope.runTest {
+ setUpForDeviceConnection()
+ tutorialSchedulerRepository.updateLaunchTime(DeviceType.TOUCHPAD, eduClock.instant())
+
+ val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
+ val originalValue = model!!.signalCount
+ eduClock.offset(initialDelayElapsedDuration)
+ val listener = getOverviewProxyListener()
+ listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue + 1)
+ }
+
+ @Test
+ fun dataUnchangedOnIncrementSignalCountBeforeInitialDelay() =
+ testScope.runTest {
+ setUpForDeviceConnection()
+ tutorialSchedulerRepository.updateLaunchTime(DeviceType.TOUCHPAD, eduClock.instant())
+
+ val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
+ val originalValue = model!!.signalCount
+ // No offset to the clock to simulate update before initial delay
+ val listener = getOverviewProxyListener()
+ listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue)
+ }
+
+ @Test
+ fun dataUnchangedOnIncrementSignalCountWithoutOobeLaunchTime() =
+ testScope.runTest {
+ // No update to OOBE launch time to simulate no OOBE is launched yet
+ setUpForDeviceConnection()
+
+ val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
+ val originalValue = model!!.signalCount
+ val listener = getOverviewProxyListener()
+ listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
+
+ assertThat(model?.signalCount).isEqualTo(originalValue)
+ }
+
+ private suspend fun setUpForInitialDelayElapse() {
+ tutorialSchedulerRepository.updateLaunchTime(DeviceType.TOUCHPAD, eduClock.instant())
+ tutorialSchedulerRepository.updateLaunchTime(DeviceType.KEYBOARD, eduClock.instant())
+ eduClock.offset(initialDelayElapsedDuration)
+ }
+
+ fun logMetricsForToastEducation() =
+ testScope.runTest {
+ triggerMaxEducationSignals(gestureType)
+ runCurrent()
+
+ verify(kosmos.mockEduMetricsLogger)
+ .logContextualEducationTriggered(gestureType, EducationUiType.Toast)
+ }
+
+ @Test
+ fun logMetricsForNotificationEducation() =
+ testScope.runTest {
+ triggerMaxEducationSignals(gestureType)
+ runCurrent()
+
+ eduClock.offset(minDurationForNextEdu)
+ triggerMaxEducationSignals(gestureType)
+ runCurrent()
+
+ verify(kosmos.mockEduMetricsLogger)
+ .logContextualEducationTriggered(gestureType, EducationUiType.Notification)
+ }
+
+ @After
+ fun clear() {
+ testScope.launch { tutorialSchedulerRepository.clear() }
+ }
+
+ private suspend fun triggerMaxEducationSignals(gestureType: GestureType) {
+ // Increment max number of signal to try triggering education
+ for (i in 1..KeyboardTouchpadEduInteractor.MAX_SIGNAL_COUNT) {
+ contextualEduInteractor.incrementSignalCount(gestureType)
+ }
+ }
+
+ private fun TestScope.setIsAnyTouchpadConnected(isConnected: Boolean) {
+ touchpadRepository.setIsAnyTouchpadConnected(isConnected)
+ runCurrent()
+ }
+
+ private fun TestScope.setIsAnyKeyboardConnected(isConnected: Boolean) {
+ keyboardRepository.setIsAnyKeyboardConnected(isConnected)
+ runCurrent()
+ }
+
+ private fun setUpForDeviceConnection() {
+ touchpadRepository.setIsAnyTouchpadConnected(true)
+ keyboardRepository.setIsAnyKeyboardConnected(true)
+ }
+
+ private fun getOverviewProxyListener(): OverviewProxyListener {
+ val listenerCaptor = argumentCaptor<OverviewProxyListener>()
+ verify(overviewProxyService).addCallback(listenerCaptor.capture())
+ return listenerCaptor.firstValue
+ }
+
+ companion object {
+ private val USER_INFOS = listOf(UserInfo(101, "Second User", 0))
+
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getGestureTypes(): List<GestureType> {
+ return listOf(BACK, HOME, OVERVIEW, ALL_APPS)
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
index 2a6d29c..580f631 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/education/domain/interactor/KeyboardTouchpadEduInteractorTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 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.
@@ -16,19 +16,17 @@
package com.android.systemui.education.domain.interactor
-import android.content.pm.UserInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.contextualeducation.GestureType
-import com.android.systemui.contextualeducation.GestureType.ALL_APPS
import com.android.systemui.contextualeducation.GestureType.BACK
import com.android.systemui.contextualeducation.GestureType.HOME
import com.android.systemui.contextualeducation.GestureType.OVERVIEW
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
-import com.android.systemui.education.data.model.GestureEduModel
-import com.android.systemui.education.data.repository.contextualEducationRepository
import com.android.systemui.education.data.repository.fakeEduClock
+import com.android.systemui.education.shared.model.EducationInfo
import com.android.systemui.education.shared.model.EducationUiType
import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType
import com.android.systemui.inputdevice.tutorial.tutorialSchedulerRepository
@@ -37,50 +35,42 @@
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
import com.android.systemui.testKosmos
import com.android.systemui.touchpad.data.repository.touchpadRepository
-import com.android.systemui.user.data.repository.fakeUserRepository
import com.google.common.truth.Truth.assertThat
-import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
-import org.junit.After
-import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.verify
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4
-import platform.test.runner.parameterized.Parameters
@SmallTest
-@RunWith(ParameterizedAndroidJunit4::class)
+@RunWith(AndroidJUnit4::class)
@kotlinx.coroutines.ExperimentalCoroutinesApi
-class KeyboardTouchpadEduInteractorTest(private val gestureType: GestureType) : SysuiTestCase() {
+class KeyboardTouchpadEduInteractorTest : SysuiTestCase() {
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val contextualEduInteractor = kosmos.contextualEducationInteractor
- private val repository = kosmos.contextualEducationRepository
private val touchpadRepository = kosmos.touchpadRepository
private val keyboardRepository = kosmos.keyboardRepository
private val tutorialSchedulerRepository = kosmos.tutorialSchedulerRepository
- private val userRepository = kosmos.fakeUserRepository
private val overviewProxyService = kosmos.mockOverviewProxyService
private val underTest: KeyboardTouchpadEduInteractor = kosmos.keyboardTouchpadEduInteractor
private val eduClock = kosmos.fakeEduClock
- private val minDurationForNextEdu =
- KeyboardTouchpadEduInteractor.minIntervalBetweenEdu + 1.seconds
private val initialDelayElapsedDuration =
KeyboardTouchpadEduInteractor.initialDelayDuration + 1.seconds
+ private val minIntervalForEduNotification =
+ KeyboardTouchpadEduInteractor.minIntervalBetweenEdu + 1.seconds
@Before
fun setup() {
underTest.start()
contextualEduInteractor.start()
- userRepository.setUserInfos(USER_INFOS)
testScope.launch {
contextualEduInteractor.updateKeyboardFirstConnectionTime()
contextualEduInteractor.updateTouchpadFirstConnectionTime()
@@ -88,312 +78,76 @@
}
@Test
- fun newEducationInfoOnMaxSignalCountReached() =
- testScope.runTest {
- triggerMaxEducationSignals(gestureType)
- val model by collectLastValue(underTest.educationTriggered)
-
- assertThat(model?.gestureType).isEqualTo(gestureType)
- }
-
- @Test
- fun newEducationToastOn1stEducation() =
- testScope.runTest {
- val model by collectLastValue(underTest.educationTriggered)
- triggerMaxEducationSignals(gestureType)
-
- assertThat(model?.educationUiType).isEqualTo(EducationUiType.Toast)
- }
-
- @Test
- fun newEducationNotificationOn2ndEducation() =
- testScope.runTest {
- val model by collectLastValue(underTest.educationTriggered)
- triggerMaxEducationSignals(gestureType)
- // runCurrent() to trigger 1st education
- runCurrent()
-
- eduClock.offset(minDurationForNextEdu)
- triggerMaxEducationSignals(gestureType)
-
- assertThat(model?.educationUiType).isEqualTo(EducationUiType.Notification)
- }
-
- @Test
- fun noEducationInfoBeforeMaxSignalCountReached() =
- testScope.runTest {
- contextualEduInteractor.incrementSignalCount(gestureType)
- val model by collectLastValue(underTest.educationTriggered)
- assertThat(model).isNull()
- }
-
- @Test
- fun noEducationInfoWhenShortcutTriggeredPreviously() =
- testScope.runTest {
- val model by collectLastValue(underTest.educationTriggered)
- contextualEduInteractor.updateShortcutTriggerTime(gestureType)
- triggerMaxEducationSignals(gestureType)
- assertThat(model).isNull()
- }
-
- @Test
- fun no2ndEducationBeforeMinEduIntervalReached() =
- testScope.runTest {
- val models by collectValues(underTest.educationTriggered)
- triggerMaxEducationSignals(gestureType)
- runCurrent()
-
- // Offset a duration that is less than the required education interval
- eduClock.offset(1.seconds)
- triggerMaxEducationSignals(gestureType)
- runCurrent()
-
- assertThat(models.filterNotNull().size).isEqualTo(1)
- }
-
- @Test
- fun noNewEducationInfoAfterMaxEducationCountReached() =
- testScope.runTest {
- val models by collectValues(underTest.educationTriggered)
- // Trigger 2 educations
- triggerMaxEducationSignals(gestureType)
- runCurrent()
- eduClock.offset(minDurationForNextEdu)
- triggerMaxEducationSignals(gestureType)
- runCurrent()
-
- // Try triggering 3rd education
- eduClock.offset(minDurationForNextEdu)
- triggerMaxEducationSignals(gestureType)
-
- assertThat(models.filterNotNull().size).isEqualTo(2)
- }
-
- @Test
- fun startNewUsageSessionWhen2ndSignalReceivedAfterSessionDeadline() =
- testScope.runTest {
- val model by
- collectLastValue(
- kosmos.contextualEducationRepository.readGestureEduModelFlow(gestureType)
- )
- contextualEduInteractor.incrementSignalCount(gestureType)
- eduClock.offset(KeyboardTouchpadEduInteractor.usageSessionDuration.plus(1.seconds))
- val secondSignalReceivedTime = eduClock.instant()
- contextualEduInteractor.incrementSignalCount(gestureType)
-
- assertThat(model)
- .isEqualTo(
- GestureEduModel(
- signalCount = 1,
- usageSessionStartTime = secondSignalReceivedTime,
- userId = 0,
- gestureType = gestureType,
- )
- )
- }
-
- @Test
- fun newTouchpadConnectionTimeOnFirstTouchpadConnected() =
- testScope.runTest {
- setIsAnyTouchpadConnected(true)
- val model = contextualEduInteractor.getEduDeviceConnectionTime()
- assertThat(model.touchpadFirstConnectionTime).isEqualTo(eduClock.instant())
- }
-
- @Test
- fun unchangedTouchpadConnectionTimeOnSecondConnection() =
- testScope.runTest {
- val firstConnectionTime = eduClock.instant()
- setIsAnyTouchpadConnected(true)
- setIsAnyTouchpadConnected(false)
-
- eduClock.offset(1.hours)
- setIsAnyTouchpadConnected(true)
-
- val model = contextualEduInteractor.getEduDeviceConnectionTime()
- assertThat(model.touchpadFirstConnectionTime).isEqualTo(firstConnectionTime)
- }
-
- @Test
- fun newTouchpadConnectionTimeOnUserChanged() =
- testScope.runTest {
- // Touchpad connected for user 0
- setIsAnyTouchpadConnected(true)
-
- // Change user
- eduClock.offset(1.hours)
- val newUserFirstConnectionTime = eduClock.instant()
- userRepository.setSelectedUserInfo(USER_INFOS[0])
- runCurrent()
-
- val model = contextualEduInteractor.getEduDeviceConnectionTime()
- assertThat(model.touchpadFirstConnectionTime).isEqualTo(newUserFirstConnectionTime)
- }
-
- @Test
- fun newKeyboardConnectionTimeOnKeyboardConnected() =
- testScope.runTest {
- setIsAnyKeyboardConnected(true)
- val model = contextualEduInteractor.getEduDeviceConnectionTime()
- assertThat(model.keyboardFirstConnectionTime).isEqualTo(eduClock.instant())
- }
-
- @Test
- fun unchangedKeyboardConnectionTimeOnSecondConnection() =
- testScope.runTest {
- val firstConnectionTime = eduClock.instant()
- setIsAnyKeyboardConnected(true)
- setIsAnyKeyboardConnected(false)
-
- eduClock.offset(1.hours)
- setIsAnyKeyboardConnected(true)
-
- val model = contextualEduInteractor.getEduDeviceConnectionTime()
- assertThat(model.keyboardFirstConnectionTime).isEqualTo(firstConnectionTime)
- }
-
- @Test
- fun newKeyboardConnectionTimeOnUserChanged() =
- testScope.runTest {
- // Keyboard connected for user 0
- setIsAnyKeyboardConnected(true)
-
- // Change user
- eduClock.offset(1.hours)
- val newUserFirstConnectionTime = eduClock.instant()
- userRepository.setSelectedUserInfo(USER_INFOS[0])
- runCurrent()
-
- val model = contextualEduInteractor.getEduDeviceConnectionTime()
- assertThat(model.keyboardFirstConnectionTime).isEqualTo(newUserFirstConnectionTime)
- }
-
- @Test
- fun updateShortcutTimeOnKeyboardShortcutTriggered() =
- testScope.runTest {
- // Only All Apps needs to update the keyboard shortcut
- assumeTrue(gestureType == ALL_APPS)
- kosmos.contextualEducationRepository.setKeyboardShortcutTriggered(ALL_APPS)
-
- val model by
- collectLastValue(
- kosmos.contextualEducationRepository.readGestureEduModelFlow(ALL_APPS)
- )
- assertThat(model?.lastShortcutTriggeredTime).isEqualTo(eduClock.instant())
- }
-
- @Test
- fun dataUpdatedOnIncrementSignalCountWhenTouchpadConnected() =
- testScope.runTest {
- assumeTrue(gestureType != ALL_APPS)
- setUpForInitialDelayElapse()
- touchpadRepository.setIsAnyTouchpadConnected(true)
-
- val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
- val originalValue = model!!.signalCount
- val listener = getOverviewProxyListener()
- listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
-
- assertThat(model?.signalCount).isEqualTo(originalValue + 1)
- }
-
- @Test
- fun dataUnchangedOnIncrementSignalCountWhenTouchpadDisconnected() =
- testScope.runTest {
- setUpForInitialDelayElapse()
- touchpadRepository.setIsAnyTouchpadConnected(false)
-
- val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
- val originalValue = model!!.signalCount
- val listener = getOverviewProxyListener()
- listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
-
- assertThat(model?.signalCount).isEqualTo(originalValue)
- }
-
- @Test
- fun dataUpdatedOnIncrementSignalCountWhenKeyboardConnected() =
- testScope.runTest {
- assumeTrue(gestureType == ALL_APPS)
- setUpForInitialDelayElapse()
- keyboardRepository.setIsAnyKeyboardConnected(true)
-
- val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
- val originalValue = model!!.signalCount
- val listener = getOverviewProxyListener()
- listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
-
- assertThat(model?.signalCount).isEqualTo(originalValue + 1)
- }
-
- @Test
- fun dataUnchangedOnIncrementSignalCountWhenKeyboardDisconnected() =
- testScope.runTest {
- setUpForInitialDelayElapse()
- keyboardRepository.setIsAnyKeyboardConnected(false)
-
- val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
- val originalValue = model!!.signalCount
- val listener = getOverviewProxyListener()
- listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
-
- assertThat(model?.signalCount).isEqualTo(originalValue)
- }
-
- @Test
- fun dataAddedOnUpdateShortcutTriggerTime() =
- testScope.runTest {
- val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
- assertThat(model?.lastShortcutTriggeredTime).isNull()
-
- val listener = getOverviewProxyListener()
- listener.updateContextualEduStats(/* isTrackpadGesture= */ true, gestureType)
-
- assertThat(model?.lastShortcutTriggeredTime).isEqualTo(kosmos.fakeEduClock.instant())
- }
-
- @Test
- fun dataUpdatedOnIncrementSignalCountAfterInitialDelay() =
+ fun newEducationToastBeforeMaxToastsPerSessionTriggered() =
testScope.runTest {
setUpForDeviceConnection()
- tutorialSchedulerRepository.updateLaunchTime(DeviceType.TOUCHPAD, eduClock.instant())
+ setUpForInitialDelayElapse()
+ val model by collectLastValue(underTest.educationTriggered)
- val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
- val originalValue = model!!.signalCount
- eduClock.offset(initialDelayElapsedDuration)
- val listener = getOverviewProxyListener()
- listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
+ triggerEducation(HOME)
- assertThat(model?.signalCount).isEqualTo(originalValue + 1)
+ assertThat(model).isEqualTo(EducationInfo(HOME, EducationUiType.Toast, userId = 0))
}
@Test
- fun dataUnchangedOnIncrementSignalCountBeforeInitialDelay() =
+ fun noEducationToastAfterMaxToastsPerSessionTriggered() =
testScope.runTest {
setUpForDeviceConnection()
- tutorialSchedulerRepository.updateLaunchTime(DeviceType.TOUCHPAD, eduClock.instant())
+ setUpForInitialDelayElapse()
+ val models by collectValues(underTest.educationTriggered.filterNotNull())
+ // Show two toasts of other gestures
+ triggerEducation(HOME)
+ triggerEducation(BACK)
- val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
- val originalValue = model!!.signalCount
- // No offset to the clock to simulate update before initial delay
- val listener = getOverviewProxyListener()
- listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
+ triggerEducation(OVERVIEW)
- assertThat(model?.signalCount).isEqualTo(originalValue)
+ // No new toast education besides the 2 triggered at first
+ val firstEdu = EducationInfo(HOME, EducationUiType.Toast, userId = 0)
+ val secondEdu = EducationInfo(BACK, EducationUiType.Toast, userId = 0)
+ assertThat(models).containsExactly(firstEdu, secondEdu).inOrder()
}
@Test
- fun dataUnchangedOnIncrementSignalCountWithoutOobeLaunchTime() =
+ fun newEducationToastAfterMinIntervalElapsedWhenMaxToastsPerSessionTriggered() =
testScope.runTest {
- // No update to OOBE launch time to simulate no OOBE is launched yet
setUpForDeviceConnection()
+ setUpForInitialDelayElapse()
+ val models by collectValues(underTest.educationTriggered.filterNotNull())
+ // Show two toasts of other gestures
+ triggerEducation(HOME)
+ triggerEducation(BACK)
- val model by collectLastValue(repository.readGestureEduModelFlow(gestureType))
- val originalValue = model!!.signalCount
- val listener = getOverviewProxyListener()
- listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
+ // Trigger toast after an usage session has elapsed
+ eduClock.offset(KeyboardTouchpadEduInteractor.usageSessionDuration + 1.seconds)
+ triggerEducation(OVERVIEW)
- assertThat(model?.signalCount).isEqualTo(originalValue)
+ val firstEdu = EducationInfo(HOME, EducationUiType.Toast, userId = 0)
+ val secondEdu = EducationInfo(BACK, EducationUiType.Toast, userId = 0)
+ val thirdEdu = EducationInfo(OVERVIEW, EducationUiType.Toast, userId = 0)
+ assertThat(models).containsExactly(firstEdu, secondEdu, thirdEdu).inOrder()
+ }
+
+ @Test
+ fun newEducationNotificationAfterMaxToastsPerSessionTriggered() =
+ testScope.runTest {
+ setUpForDeviceConnection()
+ setUpForInitialDelayElapse()
+ val models by collectValues(underTest.educationTriggered.filterNotNull())
+ triggerEducation(BACK)
+
+ // Offset to let min interval for notification elapse so we could show edu notification
+ // for BACK. It would be a new usage session too because the interval (7 days) is
+ // longer than a usage session (3 days)
+ eduClock.offset(minIntervalForEduNotification)
+ triggerEducation(HOME)
+ triggerEducation(OVERVIEW)
+ triggerEducation(BACK)
+
+ val firstEdu = EducationInfo(BACK, EducationUiType.Toast, userId = 0)
+ val secondEdu = EducationInfo(HOME, EducationUiType.Toast, userId = 0)
+ val thirdEdu = EducationInfo(OVERVIEW, EducationUiType.Toast, userId = 0)
+ val fourthEdu = EducationInfo(BACK, EducationUiType.Notification, userId = 0)
+ assertThat(models).containsExactly(firstEdu, secondEdu, thirdEdu, fourthEdu).inOrder()
}
private suspend fun setUpForInitialDelayElapse() {
@@ -402,51 +156,6 @@
eduClock.offset(initialDelayElapsedDuration)
}
- fun logMetricsForToastEducation() =
- testScope.runTest {
- triggerMaxEducationSignals(gestureType)
- runCurrent()
-
- verify(kosmos.mockEduMetricsLogger)
- .logContextualEducationTriggered(gestureType, EducationUiType.Toast)
- }
-
- @Test
- fun logMetricsForNotificationEducation() =
- testScope.runTest {
- triggerMaxEducationSignals(gestureType)
- runCurrent()
-
- eduClock.offset(minDurationForNextEdu)
- triggerMaxEducationSignals(gestureType)
- runCurrent()
-
- verify(kosmos.mockEduMetricsLogger)
- .logContextualEducationTriggered(gestureType, EducationUiType.Notification)
- }
-
- @After
- fun clear() {
- testScope.launch { tutorialSchedulerRepository.clear() }
- }
-
- private suspend fun triggerMaxEducationSignals(gestureType: GestureType) {
- // Increment max number of signal to try triggering education
- for (i in 1..KeyboardTouchpadEduInteractor.MAX_SIGNAL_COUNT) {
- contextualEduInteractor.incrementSignalCount(gestureType)
- }
- }
-
- private fun TestScope.setIsAnyTouchpadConnected(isConnected: Boolean) {
- touchpadRepository.setIsAnyTouchpadConnected(isConnected)
- runCurrent()
- }
-
- private fun TestScope.setIsAnyKeyboardConnected(isConnected: Boolean) {
- keyboardRepository.setIsAnyKeyboardConnected(isConnected)
- runCurrent()
- }
-
private fun setUpForDeviceConnection() {
touchpadRepository.setIsAnyTouchpadConnected(true)
keyboardRepository.setIsAnyKeyboardConnected(true)
@@ -458,13 +167,12 @@
return listenerCaptor.firstValue
}
- companion object {
- private val USER_INFOS = listOf(UserInfo(101, "Second User", 0))
-
- @JvmStatic
- @Parameters(name = "{0}")
- fun getGestureTypes(): List<GestureType> {
- return listOf(BACK, HOME, OVERVIEW, ALL_APPS)
+ private fun TestScope.triggerEducation(gestureType: GestureType) {
+ // Increment max number of signal to try triggering education
+ for (i in 1..KeyboardTouchpadEduInteractor.MAX_SIGNAL_COUNT) {
+ val listener = getOverviewProxyListener()
+ listener.updateContextualEduStats(/* isTrackpadGesture= */ false, gestureType)
}
+ runCurrent()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
index d88d69d..d2317e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
@@ -22,7 +22,10 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.semantics.SemanticsProperties
+import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.assert
+import androidx.compose.ui.test.filter
import androidx.compose.ui.test.hasContentDescription
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.junit4.createComposeRule
@@ -182,11 +185,14 @@
}
private fun ComposeContentTestRule.assertTileGridContainsExactly(specs: List<String>) {
- onNodeWithTag(CURRENT_TILES_GRID_TEST_TAG).onChildren().apply {
- fetchSemanticsNodes().forEachIndexed { index, _ ->
- get(index).assert(hasContentDescription(specs[index]))
+ onNodeWithTag(CURRENT_TILES_GRID_TEST_TAG)
+ .onChildren()
+ .filter(SemanticsMatcher.keyIsDefined(SemanticsProperties.ContentDescription))
+ .apply {
+ fetchSemanticsNodes().forEachIndexed { index, _ ->
+ get(index).assert(hasContentDescription(specs[index]))
+ }
}
- }
}
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
index 9a924ed..d8d6f2e9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
@@ -4,9 +4,10 @@
import android.os.Handler
import android.os.Looper
import android.os.UserManager
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.internal.telephony.flags.Flags
@@ -22,8 +23,11 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
+import com.android.systemui.qs.flags.QsInCompose.isEnabled
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIconWithRes
import com.android.systemui.res.R
import com.android.systemui.statusbar.policy.BluetoothController
import com.android.systemui.util.mockito.any
@@ -41,11 +45,17 @@
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@RunWithLooper(setAsMainLooper = true)
@SmallTest
-class BluetoothTileTest : SysuiTestCase() {
+class BluetoothTileTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
@Mock private lateinit var qsLogger: QSLogger
@Mock private lateinit var qsHost: QSHost
@@ -81,7 +91,7 @@
qsLogger,
bluetoothController,
featureFlags,
- bluetoothTileDialogViewModel
+ bluetoothTileDialogViewModel,
)
tile.initialize()
@@ -109,8 +119,7 @@
tile.handleUpdateState(state, /* arg= */ null)
- assertThat(state.icon)
- .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_off))
+ assertThat(state.icon).isEqualTo(createExpectedIcon(R.drawable.qs_bluetooth_icon_off))
}
@Test
@@ -121,8 +130,7 @@
tile.handleUpdateState(state, /* arg= */ null)
- assertThat(state.icon)
- .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_off))
+ assertThat(state.icon).isEqualTo(createExpectedIcon(R.drawable.qs_bluetooth_icon_off))
}
@Test
@@ -133,8 +141,7 @@
tile.handleUpdateState(state, /* arg= */ null)
- assertThat(state.icon)
- .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_on))
+ assertThat(state.icon).isEqualTo(createExpectedIcon(R.drawable.qs_bluetooth_icon_on))
}
@Test
@@ -145,8 +152,7 @@
tile.handleUpdateState(state, /* arg= */ null)
- assertThat(state.icon)
- .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_search))
+ assertThat(state.icon).isEqualTo(createExpectedIcon(R.drawable.qs_bluetooth_icon_search))
}
@Test
@@ -161,11 +167,10 @@
.isEqualTo(
mContext.getString(
R.string.quick_settings_bluetooth_secondary_label_battery_level,
- Utils.formatPercentage(50)
+ Utils.formatPercentage(50),
)
)
- verify(bluetoothController)
- .addOnMetadataChangedListener(eq(cachedDevice), any(), any())
+ verify(bluetoothController).addOnMetadataChangedListener(eq(cachedDevice), any(), any())
}
@Test
@@ -186,7 +191,7 @@
.isEqualTo(
mContext.getString(
R.string.quick_settings_bluetooth_secondary_label_battery_level,
- Utils.formatPercentage(25)
+ Utils.formatPercentage(25),
)
)
verify(bluetoothController, times(1))
@@ -197,7 +202,7 @@
fun handleClick_hasSatelliteFeatureButNoQsTileDialogAndClickIsProcessing_doNothing() {
mSetFlagsRule.enableFlags(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
`when`(featureFlags.isEnabled(com.android.systemui.flags.Flags.BLUETOOTH_QS_TILE_DIALOG))
- .thenReturn(false)
+ .thenReturn(false)
`when`(clickJob.isCompleted).thenReturn(false)
tile.mClickJob = clickJob
@@ -210,7 +215,7 @@
fun handleClick_noSatelliteFeatureAndNoQsTileDialog_directSetBtEnable() {
mSetFlagsRule.disableFlags(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
`when`(featureFlags.isEnabled(com.android.systemui.flags.Flags.BLUETOOTH_QS_TILE_DIALOG))
- .thenReturn(false)
+ .thenReturn(false)
tile.handleClick(null)
@@ -221,7 +226,7 @@
fun handleClick_noSatelliteFeatureButHasQsTileDialog_showDialog() {
mSetFlagsRule.disableFlags(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
`when`(featureFlags.isEnabled(com.android.systemui.flags.Flags.BLUETOOTH_QS_TILE_DIALOG))
- .thenReturn(true)
+ .thenReturn(true)
tile.handleClick(null)
@@ -265,7 +270,7 @@
qsLogger: QSLogger,
bluetoothController: BluetoothController,
featureFlags: FeatureFlagsClassic,
- bluetoothTileDialogViewModel: BluetoothTileDialogViewModel
+ bluetoothTileDialogViewModel: BluetoothTileDialogViewModel,
) :
BluetoothTile(
qsHost,
@@ -279,13 +284,13 @@
qsLogger,
bluetoothController,
featureFlags,
- bluetoothTileDialogViewModel
+ bluetoothTileDialogViewModel,
) {
var restrictionChecked: String? = null
override fun checkIfRestrictionEnforcedByAdminOnly(
state: QSTile.State?,
- userRestriction: String?
+ userRestriction: String?,
) {
restrictionChecked = userRestriction
}
@@ -321,7 +326,7 @@
fun listenToDeviceMetadata(
state: QSTile.BooleanState,
cachedDevice: CachedBluetoothDevice,
- batteryLevel: Int
+ batteryLevel: Int,
) {
val btDevice = mock<BluetoothDevice>()
whenever(cachedDevice.device).thenReturn(btDevice)
@@ -332,4 +337,20 @@
addConnectedDevice(cachedDevice)
tile.handleUpdateState(state, /* arg= */ null)
}
+
+ private fun createExpectedIcon(resId: Int): QSTile.Icon {
+ return if (isEnabled) {
+ DrawableIconWithRes(mContext.getDrawable(resId), resId)
+ } else {
+ QSTileImpl.ResourceIcon.get(resId)
+ }
+ }
+
+ companion object {
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
index 6a43a61..55fb6da 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
@@ -21,15 +21,15 @@
import android.content.SharedPreferences
import android.os.Handler
import android.platform.test.annotations.DisableFlags
+import android.platform.test.flag.junit.FlagsParameterization
+import android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf
import android.provider.Settings
import android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
import android.provider.Settings.Global.ZEN_MODE_OFF
import android.testing.TestableLooper
import android.view.ContextThemeWrapper
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.animation.Expandable
@@ -39,14 +39,19 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.QsEventLogger
+import com.android.systemui.qs.flags.QSComposeFragment
+import com.android.systemui.qs.flags.QsInCompose.isEnabled
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIconWithRes
+import com.android.systemui.res.R
import com.android.systemui.statusbar.policy.ZenModeController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.settings.FakeSettings
import com.android.systemui.util.settings.SecureSettings
import com.google.common.truth.Truth.assertThat
+import java.io.File
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -55,56 +60,55 @@
import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
-import java.io.File
import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
@SmallTest
-@RunWith(AndroidJUnit4::class)
+@RunWith(ParameterizedAndroidJunit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@DisableFlags(android.app.Flags.FLAG_MODES_UI)
-class DndTileTest : SysuiTestCase() {
+class DndTileTest(flags: FlagsParameterization) : SysuiTestCase() {
companion object {
private const val DEFAULT_USER = 0
private const val KEY = Settings.Secure.ZEN_DURATION
+
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> {
+ return allCombinationsOf(QSComposeFragment.FLAG_NAME)
+ }
}
- @Mock
- private lateinit var qsHost: QSHost
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
- @Mock
- private lateinit var metricsLogger: MetricsLogger
+ @Mock private lateinit var qsHost: QSHost
- @Mock
- private lateinit var statusBarStateController: StatusBarStateController
+ @Mock private lateinit var metricsLogger: MetricsLogger
- @Mock
- private lateinit var activityStarter: ActivityStarter
+ @Mock private lateinit var statusBarStateController: StatusBarStateController
- @Mock
- private lateinit var qsLogger: QSLogger
+ @Mock private lateinit var activityStarter: ActivityStarter
- @Mock
- private lateinit var uiEventLogger: QsEventLogger
+ @Mock private lateinit var qsLogger: QSLogger
- @Mock
- private lateinit var zenModeController: ZenModeController
+ @Mock private lateinit var uiEventLogger: QsEventLogger
- @Mock
- private lateinit var sharedPreferences: SharedPreferences
+ @Mock private lateinit var zenModeController: ZenModeController
- @Mock
- private lateinit var mDialogTransitionAnimator: DialogTransitionAnimator
+ @Mock private lateinit var sharedPreferences: SharedPreferences
- @Mock
- private lateinit var hostDialog: Dialog
+ @Mock private lateinit var mDialogTransitionAnimator: DialogTransitionAnimator
- @Mock
- private lateinit var expandable: Expandable
+ @Mock private lateinit var hostDialog: Dialog
- @Mock
- private lateinit var controller: DialogTransitionAnimator.Controller
+ @Mock private lateinit var expandable: Expandable
+
+ @Mock private lateinit var controller: DialogTransitionAnimator.Controller
private lateinit var secureSettings: SecureSettings
private lateinit var testableLooper: TestableLooper
@@ -118,31 +122,32 @@
whenever(qsHost.userId).thenReturn(DEFAULT_USER)
- val wrappedContext = object : ContextWrapper(
- ContextThemeWrapper(context, R.style.Theme_SystemUI_QuickSettings)
- ) {
- override fun getSharedPreferences(file: File?, mode: Int): SharedPreferences {
- return sharedPreferences
+ val wrappedContext =
+ object :
+ ContextWrapper(ContextThemeWrapper(context, R.style.Theme_SystemUI_QuickSettings)) {
+ override fun getSharedPreferences(file: File?, mode: Int): SharedPreferences {
+ return sharedPreferences
+ }
}
- }
whenever(qsHost.context).thenReturn(wrappedContext)
whenever(expandable.dialogTransitionController(any())).thenReturn(controller)
- tile = DndTile(
- qsHost,
- uiEventLogger,
- testableLooper.looper,
- Handler(testableLooper.looper),
- FalsingManagerFake(),
- metricsLogger,
- statusBarStateController,
- activityStarter,
- qsLogger,
- zenModeController,
- sharedPreferences,
- secureSettings,
- mDialogTransitionAnimator
- )
+ tile =
+ DndTile(
+ qsHost,
+ uiEventLogger,
+ testableLooper.looper,
+ Handler(testableLooper.looper),
+ FalsingManagerFake(),
+ metricsLogger,
+ statusBarStateController,
+ activityStarter,
+ qsLogger,
+ zenModeController,
+ sharedPreferences,
+ secureSettings,
+ mDialogTransitionAnimator,
+ )
}
@After
@@ -222,7 +227,7 @@
tile.handleUpdateState(state, /* arg= */ null)
- assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_dnd_icon_off))
+ assertThat(state.icon).isEqualTo(createExpectedIcon(R.drawable.qs_dnd_icon_off))
}
@Test
@@ -232,6 +237,14 @@
tile.handleUpdateState(state, /* arg= */ null)
- assertThat(state.icon).isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_dnd_icon_on))
+ assertThat(state.icon).isEqualTo(createExpectedIcon(R.drawable.qs_dnd_icon_on))
+ }
+
+ private fun createExpectedIcon(resId: Int): QSTile.Icon {
+ return if (isEnabled) {
+ DrawableIconWithRes(mContext.getDrawable(resId), resId)
+ } else {
+ QSTileImpl.ResourceIcon.get(resId)
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
index 190d80f..5f63b15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
@@ -16,6 +16,10 @@
package com.android.systemui.qs.tiles;
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
+
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
@@ -32,12 +36,12 @@
import android.content.pm.UserInfo;
import android.os.Handler;
import android.os.RemoteException;
+import android.platform.test.flag.junit.FlagsParameterization;
import android.provider.Settings;
import android.service.dreams.IDreamManager;
import android.service.quicksettings.Tile;
import android.testing.TestableLooper;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -45,9 +49,11 @@
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.QsEventLogger;
+import com.android.systemui.qs.flags.QsInCompose;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.res.R;
@@ -63,11 +69,21 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class DreamTileTest extends SysuiTestCase {
+ @Parameters(name = "{0}")
+ public static List<FlagsParameterization> getParams() {
+ return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+ }
+
@Mock
private ActivityStarter mActivityStarter;
@Mock
@@ -101,6 +117,11 @@
private final String mExpectedTileLabel = mContext.getResources().getString(
R.string.quick_settings_screensaver_label);
+ public DreamTileTest(FlagsParameterization flags) {
+ super();
+ mSetFlagsRule.setFlagsParameterization(flags);
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -246,13 +267,13 @@
dockIntent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_DESK);
receiver.onReceive(mContext, dockIntent);
mTestableLooper.processAllMessages();
- assertEquals(QSTileImpl.ResourceIcon.get(R.drawable.ic_qs_screen_saver),
+ assertEquals(createExpectedIcon(R.drawable.ic_qs_screen_saver),
dockedTile.getState().icon);
dockIntent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
receiver.onReceive(mContext, dockIntent);
mTestableLooper.processAllMessages();
- assertEquals(QSTileImpl.ResourceIcon.get(R.drawable.ic_qs_screen_saver_undocked),
+ assertEquals(createExpectedIcon(R.drawable.ic_qs_screen_saver_undocked),
dockedTile.getState().icon);
destroyTile(dockedTile);
@@ -268,6 +289,14 @@
mTestableLooper.processAllMessages();
}
+ private QSTile.Icon createExpectedIcon(int resId) {
+ if (QsInCompose.isEnabled()) {
+ return new QSTileImpl.DrawableIconWithRes(mContext.getDrawable(resId), resId);
+ } else {
+ return QSTileImpl.ResourceIcon.get(resId);
+ }
+ }
+
private DreamTile constructTileForTest(boolean dreamSupported,
boolean dreamOnlyEnabledForSystemUser) {
return new DreamTile(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java
index 5bd6944..ba6c2dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HotspotTileTest.java
@@ -16,16 +16,20 @@
package com.android.systemui.qs.tiles;
+import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf;
+
+import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.os.Handler;
+import android.platform.test.flag.junit.FlagsParameterization;
import android.service.quicksettings.Tile;
import android.testing.TestableLooper;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
@@ -38,6 +42,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.QsEventLogger;
+import com.android.systemui.qs.flags.QsInCompose;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.res.R;
@@ -54,11 +59,21 @@
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
-@RunWith(AndroidJUnit4.class)
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
+@RunWith(ParameterizedAndroidJunit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class HotspotTileTest extends SysuiTestCase {
+ @Parameters(name = "{0}")
+ public static List<FlagsParameterization> getParams() {
+ return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+ }
+
@Rule
public MockitoRule mRule = MockitoJUnit.rule();
@Mock
@@ -74,6 +89,11 @@
private HotspotTile mTile;
private QSTile.BooleanState mState = new QSTile.BooleanState();
+ public HotspotTileTest(FlagsParameterization flags) {
+ super();
+ mSetFlagsRule.setFlagsParameterization(flags);
+ }
+
@Before
public void setUp() throws Exception {
mTestableLooper = TestableLooper.get(this);
@@ -144,7 +164,7 @@
mTile.handleUpdateState(state, /* arg= */ null);
assertThat(state.icon)
- .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_hotspot_icon_off));
+ .isEqualTo(createExpectedIcon(R.drawable.qs_hotspot_icon_off));
}
@Test
@@ -156,7 +176,7 @@
mTile.handleUpdateState(state, /* arg= */ null);
assertThat(state.icon)
- .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_hotspot_icon_search));
+ .isEqualTo(createExpectedIcon(R.drawable.qs_hotspot_icon_search));
}
@Test
@@ -168,6 +188,14 @@
mTile.handleUpdateState(state, /* arg= */ null);
assertThat(state.icon)
- .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_hotspot_icon_on));
+ .isEqualTo(createExpectedIcon(R.drawable.qs_hotspot_icon_on));
+ }
+
+ private QSTile.Icon createExpectedIcon(int resId) {
+ if (QsInCompose.isEnabled()) {
+ return new QSTileImpl.DrawableIconWithRes(mContext.getDrawable(resId), resId);
+ } else {
+ return QSTileImpl.ResourceIcon.get(resId);
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java
index 5ada2f3..b26f0a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java
@@ -260,7 +260,8 @@
@Test
public void connectCarrierNetwork_mergedCarrierEntryCanConnect_connectAndCreateSysUiToast() {
- when(mTelephonyManager.isDataEnabled()).thenReturn(true);
+ InternetDialogController spyController = spy(mInternetDialogController);
+ when(spyController.isMobileDataEnabled()).thenReturn(true);
when(mKeyguardStateController.isUnlocked()).thenReturn(true);
when(mConnectivityManager.getActiveNetwork()).thenReturn(mNetwork);
when(mConnectivityManager.getNetworkCapabilities(mNetwork))
@@ -272,7 +273,7 @@
mTestableResources.addOverride(R.string.wifi_wont_autoconnect_for_now,
TOAST_MESSAGE_STRING);
- mInternetDialogController.connectCarrierNetwork();
+ spyController.connectCarrierNetwork();
verify(mMergedCarrierEntry).connect(null /* callback */, false /* showToast */);
verify(mToastFactory).createToast(any(), any(), eq(TOAST_MESSAGE_STRING), anyString(),
@@ -281,11 +282,12 @@
@Test
public void connectCarrierNetwork_mergedCarrierEntryCanConnect_doNothingWhenSettingsOff() {
- when(mTelephonyManager.isDataEnabled()).thenReturn(false);
-
+ InternetDialogController spyController = spy(mInternetDialogController);
+ when(spyController.isMobileDataEnabled()).thenReturn(false);
mTestableResources.addOverride(R.string.wifi_wont_autoconnect_for_now,
TOAST_MESSAGE_STRING);
- mInternetDialogController.connectCarrierNetwork();
+
+ spyController.connectCarrierNetwork();
verify(mMergedCarrierEntry, never()).connect(null /* callback */, false /* showToast */);
verify(mToastFactory, never()).createToast(any(), any(), anyString(), anyString(), anyInt(),
@@ -294,12 +296,13 @@
@Test
public void connectCarrierNetwork_mergedCarrierEntryCanConnect_doNothingWhenKeyguardLocked() {
- when(mTelephonyManager.isDataEnabled()).thenReturn(true);
+ InternetDialogController spyController = spy(mInternetDialogController);
+ when(spyController.isMobileDataEnabled()).thenReturn(true);
when(mKeyguardStateController.isUnlocked()).thenReturn(false);
mTestableResources.addOverride(R.string.wifi_wont_autoconnect_for_now,
TOAST_MESSAGE_STRING);
- mInternetDialogController.connectCarrierNetwork();
+ spyController.connectCarrierNetwork();
verify(mMergedCarrierEntry, never()).connect(null /* callback */, false /* showToast */);
verify(mToastFactory, never()).createToast(any(), any(), anyString(), anyString(), anyInt(),
@@ -308,7 +311,8 @@
@Test
public void connectCarrierNetwork_mergedCarrierEntryCanConnect_doNothingWhenMobileIsPrimary() {
- when(mTelephonyManager.isDataEnabled()).thenReturn(true);
+ InternetDialogController spyController = spy(mInternetDialogController);
+ when(spyController.isMobileDataEnabled()).thenReturn(true);
when(mKeyguardStateController.isUnlocked()).thenReturn(true);
when(mConnectivityManager.getActiveNetwork()).thenReturn(mNetwork);
when(mConnectivityManager.getNetworkCapabilities(mNetwork))
@@ -446,10 +450,9 @@
when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
spyController.onAccessPointsChanged(null /* accessPoints */);
- doReturn(SUB_ID2).when(spyController).getActiveAutoSwitchNonDdsSubId();
+ doReturn(SUB_ID).when(spyController).getActiveAutoSwitchNonDdsSubId();
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
- doReturn(mServiceState).when(mTelephonyManager).getServiceState();
- doReturn(TelephonyManager.DATA_DISCONNECTED).when(mTelephonyManager).getDataState();
+ spyController.mSubIdServiceState.put(SUB_ID2, mServiceState);
assertFalse(TextUtils.equals(spyController.getSubtitleText(false),
getResourcesString("all_network_unavailable")));
@@ -469,8 +472,7 @@
spyController.onAccessPointsChanged(null /* accessPoints */);
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
- doReturn(mServiceState).when(mTelephonyManager).getServiceState();
- doReturn(TelephonyManager.DATA_DISCONNECTED).when(mTelephonyManager).getDataState();
+ spyController.mSubIdServiceState.put(SUB_ID, mServiceState);
assertTrue(TextUtils.equals(spyController.getSubtitleText(false),
getResourcesString("all_network_unavailable")));
@@ -487,11 +489,10 @@
fakeAirplaneModeEnabled(false);
when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
+ InternetDialogController spyController = spy(mInternetDialogController);
doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
- doReturn(mServiceState).when(mTelephonyManager).getServiceState();
-
- when(mTelephonyManager.isDataEnabled()).thenReturn(false);
+ spyController.mSubIdServiceState.put(SUB_ID, mServiceState);
assertThat(mInternetDialogController.getSubtitleText(false))
.isEqualTo(getResourcesString("non_carrier_network_unavailable"));
@@ -499,6 +500,9 @@
// if the Wi-Fi disallow config, then don't return Wi-Fi related string.
mInternetDialogController.mCanConfigWifi = false;
+ when(spyController.isMobileDataEnabled()).thenReturn(false);
+
+
assertThat(mInternetDialogController.getSubtitleText(false))
.isNotEqualTo(getResourcesString("non_carrier_network_unavailable"));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
index e7fb470c..c410111 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -33,7 +33,7 @@
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.Flags
-import com.android.systemui.Flags.FLAG_COMMUNAL_HUB_ON_MOBILE
+import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2
import com.android.systemui.Flags.FLAG_HUBMODE_FULLSCREEN_VERTICAL_SWIPE_FIX
import com.android.systemui.SysuiTestCase
import com.android.systemui.ambient.touch.TouchHandler
@@ -43,7 +43,9 @@
import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
+import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.ui.compose.CommunalContent
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
@@ -131,20 +133,26 @@
underTest =
GlanceableHubContainerController(
communalInteractor,
+ communalSettingsInteractor,
communalViewModel,
keyguardInteractor,
- kosmos.keyguardTransitionInteractor,
+ keyguardTransitionInteractor,
shadeInteractor,
powerManager,
communalColors,
ambientTouchComponentFactory,
communalContent,
- kosmos.sceneDataSourceDelegator,
- kosmos.notificationStackScrollLayoutController,
- kosmos.keyguardMediaController,
- kosmos.lockscreenSmartspaceController,
+ sceneDataSourceDelegator,
+ notificationStackScrollLayoutController,
+ keyguardMediaController,
+ lockscreenSmartspaceController,
logcatLogBuffer("GlanceableHubContainerControllerTest"),
)
+
+ // Make below last notification true by default or else touches will be ignored by
+ // default when the hub is not showing.
+ whenever(notificationStackScrollLayoutController.isBelowLastNotification(any(), any()))
+ .thenReturn(true)
}
testableLooper = TestableLooper.get(this)
@@ -178,6 +186,7 @@
underTest =
GlanceableHubContainerController(
communalInteractor,
+ kosmos.communalSettingsInteractor,
communalViewModel,
keyguardInteractor,
kosmos.keyguardTransitionInteractor,
@@ -207,6 +216,7 @@
val underTest =
GlanceableHubContainerController(
communalInteractor,
+ kosmos.communalSettingsInteractor,
communalViewModel,
keyguardInteractor,
kosmos.keyguardTransitionInteractor,
@@ -231,6 +241,7 @@
val underTest =
GlanceableHubContainerController(
communalInteractor,
+ kosmos.communalSettingsInteractor,
communalViewModel,
keyguardInteractor,
kosmos.keyguardTransitionInteractor,
@@ -631,7 +642,7 @@
}
}
- @DisableFlags(FLAG_COMMUNAL_HUB_ON_MOBILE)
+ @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
@Test
fun onTouchEvent_shadeInteracting_movesNotDispatched() =
with(kosmos) {
@@ -688,7 +699,7 @@
}
}
- @DisableFlags(FLAG_COMMUNAL_HUB_ON_MOBILE)
+ @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
@Test
fun onTouchEvent_bouncerInteracting_movesNotDispatched() =
with(kosmos) {
@@ -721,11 +732,13 @@
}
}
- @EnableFlags(FLAG_COMMUNAL_HUB_ON_MOBILE)
+ @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
@Test
fun onTouchEvent_onLockscreenAndGlanceableHubV2_touchIgnored() =
with(kosmos) {
testScope.runTest {
+ kosmos.setCommunalV2ConfigEnabled(true)
+
// On lockscreen.
goToScene(CommunalScenes.Blank)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 11b19f9..99467cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -1275,6 +1275,37 @@
}
@Test
+ @EnableSceneContainer
+ public void testChildHeightUpdated_whenMaxDisplayedNotificationsSet_updatesStackHeight() {
+ ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
+ int maxNotifs = 1; // any non-zero limit
+ float stackTop = 100;
+ float stackCutoff = 1100;
+ mStackScroller.setStackTop(stackTop);
+ mStackScroller.setStackCutoff(stackCutoff);
+
+ // Given we have a limit on max displayed notifications
+ int stackHeightBeforeUpdate = 100;
+ when(mStackSizeCalculator.computeHeight(eq(mStackScroller), eq(maxNotifs), anyFloat()))
+ .thenReturn((float) stackHeightBeforeUpdate);
+ mStackScroller.setMaxDisplayedNotifications(maxNotifs);
+
+ // And the stack heights are set
+ assertThat(mStackScroller.getIntrinsicStackHeight()).isEqualTo(stackHeightBeforeUpdate);
+ assertThat(mAmbientState.getStackEndHeight()).isEqualTo(stackHeightBeforeUpdate);
+
+ // When a child changes its height
+ int stackHeightAfterUpdate = 300;
+ when(mStackSizeCalculator.computeHeight(eq(mStackScroller), eq(maxNotifs), anyFloat()))
+ .thenReturn((float) stackHeightAfterUpdate);
+ mStackScroller.onChildHeightChanged(row, /* needsAnimation = */ false);
+
+ // Then the stack heights are updated
+ assertThat(mStackScroller.getIntrinsicStackHeight()).isEqualTo(stackHeightAfterUpdate);
+ assertThat(mAmbientState.getStackEndHeight()).isEqualTo(stackHeightAfterUpdate);
+ }
+
+ @Test
@DisableSceneContainer
public void testSetMaxDisplayedNotifications_notifiesListeners() {
ExpandableView.OnHeightChangedListener listener =
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 6912eda..d157cf2d 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
@@ -36,8 +36,6 @@
import static com.google.common.truth.Truth.assertThat;
-import static kotlinx.coroutines.flow.FlowKt.flowOf;
-
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -56,6 +54,8 @@
import static java.util.Collections.emptySet;
+import static kotlinx.coroutines.flow.FlowKt.flowOf;
+
import android.app.ActivityManager;
import android.app.IWallpaperManager;
import android.app.NotificationManager;
@@ -138,6 +138,7 @@
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.domain.interactor.PowerInteractor;
+import com.android.systemui.qs.flags.QSComposeFragment;
import com.android.systemui.res.R;
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
import com.android.systemui.scene.domain.startable.ScrimStartable;
@@ -181,6 +182,7 @@
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.AvalancheProvider;
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
@@ -198,7 +200,6 @@
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.ExtensionController;
-import com.android.systemui.statusbar.notification.headsup.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.window.StatusBarWindowController;
@@ -217,10 +218,6 @@
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.startingsurface.StartingSurface;
-import dagger.Lazy;
-
-import kotlinx.coroutines.test.TestScope;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -237,6 +234,9 @@
import javax.inject.Provider;
+import dagger.Lazy;
+import kotlinx.coroutines.test.TestScope;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
@RunWithLooper(setAsMainLooper = true)
@@ -667,6 +667,9 @@
mCentralSurfaces.startKeyguard();
mInitController.executePostInitTasks();
mCentralSurfaces.registerCallbacks();
+ // Clear first invocations caused by registering flows with JavaAdapter
+ mTestScope.getTestScheduler().runCurrent();
+ clearInvocations(mScrimController);
}
@Test
@@ -1159,8 +1162,7 @@
@Test
@EnableSceneContainer
- public void brightnesShowingChanged_flagEnabled_ScrimControllerNotified() {
- mCentralSurfaces.registerCallbacks();
+ public void brightnesShowingChanged_sceneContainerFlagEnabled_ScrimControllerNotified() {
final ScrimStartable scrimStartable = mKosmos.getScrimStartable();
scrimStartable.start();
@@ -1178,9 +1180,25 @@
@Test
@DisableSceneContainer
- public void brightnesShowingChanged_flagDisabled_ScrimControllerNotified() {
- mCentralSurfaces.registerCallbacks();
+ @EnableFlags(QSComposeFragment.FLAG_NAME)
+ public void brightnesShowingChanged_qsUiRefactorFlagEnabled_ScrimControllerNotified() {
+ mBrightnessMirrorShowingInteractor.setMirrorShowing(true);
+ mTestScope.getTestScheduler().runCurrent();
+ verify(mScrimController, atLeastOnce()).legacyTransitionTo(ScrimState.BRIGHTNESS_MIRROR);
+ clearInvocations(mScrimController);
+ mBrightnessMirrorShowingInteractor.setMirrorShowing(false);
+ mTestScope.getTestScheduler().runCurrent();
+ ArgumentCaptor<ScrimState> captor = ArgumentCaptor.forClass(ScrimState.class);
+ // The default is to call the one with the callback argument
+ verify(mScrimController, atLeastOnce()).legacyTransitionTo(captor.capture(), any());
+ assertThat(captor.getValue()).isNotEqualTo(ScrimState.BRIGHTNESS_MIRROR);
+ }
+
+ @Test
+ @DisableSceneContainer
+ @DisableFlags(QSComposeFragment.FLAG_NAME)
+ public void brightnesShowingChanged_flagsDisabled_ScrimControllerNotified() {
mBrightnessMirrorShowingInteractor.setMirrorShowing(true);
mTestScope.getTestScheduler().runCurrent();
verify(mScrimController, never()).legacyTransitionTo(ScrimState.BRIGHTNESS_MIRROR);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 33a4b7e..38ddb3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -45,8 +45,6 @@
import android.animation.Animator;
import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.TypedArray;
import android.graphics.Color;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
@@ -154,7 +152,6 @@
private final FakeKeyguardTransitionRepository mKeyguardTransitionRepository =
mKosmos.getKeyguardTransitionRepository();
@Mock private KeyguardInteractor mKeyguardInteractor;
- @Mock private TypedArray mMockTypedArray;
// TODO(b/204991468): Use a real PanelExpansionStateManager object once this bug is fixed. (The
// event-dispatch-on-registration pattern caused some of these unit tests to fail.)
@@ -236,12 +233,8 @@
public void setup() {
MockitoAnnotations.initMocks(this);
mContext = spy(getContext());
- when(mContext.obtainStyledAttributes(
- new int[]{com.android.internal.R.attr.materialColorSurface}))
- .thenReturn(mMockTypedArray);
-
- when(mMockTypedArray.getColorStateList(anyInt()))
- .thenAnswer((invocation) -> ColorStateList.valueOf(mSurfaceColor));
+ when(mContext.getColor(com.android.internal.R.color.materialColorSurface))
+ .thenAnswer(invocation -> mSurfaceColor);
mScrimBehind = spy(new ScrimView(mContext));
mScrimInFront = new ScrimView(mContext);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
index 1f68195..ad92b31 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
@@ -16,6 +16,7 @@
package com.android.systemui.communal.domain.interactor
+import android.content.testableContext
import android.os.userManager
import com.android.systemui.broadcast.broadcastDispatcher
import com.android.systemui.communal.data.repository.communalMediaRepository
@@ -34,6 +35,7 @@
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.plugins.activityStarter
+import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.settings.userTracker
import com.android.systemui.statusbar.phone.fakeManagedProfileController
@@ -67,6 +69,13 @@
val Kosmos.editWidgetsActivityStarter by Fixture<EditWidgetsActivityStarter> { mock() }
+fun Kosmos.setCommunalV2ConfigEnabled(enabled: Boolean) {
+ testableContext.orCreateTestableResources.addOverride(
+ com.android.internal.R.bool.config_glanceableHubEnabled,
+ enabled,
+ )
+}
+
suspend fun Kosmos.setCommunalEnabled(enabled: Boolean) {
fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, enabled)
if (enabled) {
@@ -76,6 +85,15 @@
}
}
+suspend fun Kosmos.setCommunalV2Enabled(enabled: Boolean) {
+ setCommunalV2ConfigEnabled(true)
+ if (enabled) {
+ fakeUserRepository.asMainUser()
+ } else {
+ fakeUserRepository.asDefaultUser()
+ }
+}
+
suspend fun Kosmos.setCommunalAvailable(available: Boolean) {
setCommunalEnabled(available)
with(fakeKeyguardRepository) {
@@ -83,3 +101,12 @@
setKeyguardShowing(available)
}
}
+
+suspend fun Kosmos.setCommunalV2Available(available: Boolean) {
+ setCommunalV2ConfigEnabled(true)
+ setCommunalEnabled(available)
+ with(fakeKeyguardRepository) {
+ setIsEncryptedOrLockdown(!available)
+ setKeyguardShowing(available)
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModelKosmos.kt
similarity index 60%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModelKosmos.kt
index b8d3ff4..b407b1b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalToDreamButtonViewModelKosmos.kt
@@ -14,16 +14,18 @@
* limitations under the License.
*/
-package com.android.systemui.qs.panels.ui.viewmodel
+package com.android.systemui.communal.ui.viewmodel
-import com.android.systemui.classifier.domain.interactor.falsingInteractor
+import android.service.dream.dreamManager
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.statusbar.policy.batteryController
-val Kosmos.editModeButtonViewModelFactory by
+val Kosmos.communalToDreamButtonViewModel by
Kosmos.Fixture {
- object : EditModeButtonViewModel.Factory {
- override fun create(): EditModeButtonViewModel {
- return EditModeButtonViewModel(editModeViewModel, falsingInteractor)
- }
- }
+ CommunalToDreamButtonViewModel(
+ backgroundContext = testDispatcher,
+ batteryController = batteryController,
+ dreamManager = dreamManager,
+ )
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryKosmos.kt
index 1df3ef4..1021169 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryKosmos.kt
@@ -17,9 +17,11 @@
package com.android.systemui.education.data.repository
import com.android.systemui.kosmos.Kosmos
+import java.time.Duration
import java.time.Instant
var Kosmos.contextualEducationRepository: FakeContextualEducationRepository by
Kosmos.Fixture { FakeContextualEducationRepository() }
-var Kosmos.fakeEduClock: FakeEduClock by Kosmos.Fixture { FakeEduClock(Instant.MIN) }
+var Kosmos.fakeEduClock: FakeEduClock by
+ Kosmos.Fixture { FakeEduClock(Instant.ofEpochSecond(Duration.ofDays(30).seconds)) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/globalactions/GlobalActionsDialogLiteKosmos.kt
similarity index 60%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/globalactions/GlobalActionsDialogLiteKosmos.kt
index b8d3ff4..63bfa52 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/globalactions/GlobalActionsDialogLiteKosmos.kt
@@ -14,16 +14,10 @@
* limitations under the License.
*/
-package com.android.systemui.qs.panels.ui.viewmodel
+package com.android.systemui.globalactions
-import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
-val Kosmos.editModeButtonViewModelFactory by
- Kosmos.Fixture {
- object : EditModeButtonViewModel.Factory {
- override fun create(): EditModeButtonViewModel {
- return EditModeButtonViewModel(editModeViewModel, falsingInteractor)
- }
- }
- }
+/** Provides a mock */
+val Kosmos.globalActionsDialogLite: GlobalActionsDialogLite by Kosmos.Fixture { mock() }
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 552cd94..4cb8a41 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
@@ -25,6 +25,7 @@
import com.android.systemui.keyboard.shortcut.data.repository.CustomInputGesturesRepository
import com.android.systemui.keyboard.shortcut.data.repository.CustomShortcutCategoriesRepository
import com.android.systemui.keyboard.shortcut.data.repository.DefaultShortcutCategoriesRepository
+import com.android.systemui.keyboard.shortcut.data.repository.InputGestureDataAdapter
import com.android.systemui.keyboard.shortcut.data.repository.InputGestureMaps
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutCategoriesUtils
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
@@ -112,6 +113,8 @@
val Kosmos.inputGestureMaps by Kosmos.Fixture { InputGestureMaps(applicationContext) }
+val Kosmos.inputGestureDataAdapter by Kosmos.Fixture { InputGestureDataAdapter(userTracker, inputGestureMaps, applicationContext)}
+
val Kosmos.customInputGesturesRepository by
Kosmos.Fixture { CustomInputGesturesRepository(userTracker, testDispatcher) }
@@ -122,8 +125,7 @@
applicationCoroutineScope,
testDispatcher,
shortcutCategoriesUtils,
- applicationContext,
- inputGestureMaps,
+ inputGestureDataAdapter,
customInputGesturesRepository,
fakeInputManager.inputManager,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
index 10b073e..2e6d8ed 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
@@ -28,6 +28,7 @@
import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.FakeStatusBarStateController
import com.android.systemui.statusbar.StatusBarStateControllerImpl
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.util.mockito.mock
@@ -49,3 +50,6 @@
{ alternateBouncerInteractor },
)
}
+
+var Kosmos.fakeStatusBarStateController: SysuiStatusBarStateController by
+ Kosmos.Fixture { FakeStatusBarStateController() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
index c574463..49957f0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
@@ -18,6 +18,7 @@
import android.content.res.mainResources
import androidx.lifecycle.LifecycleCoroutineScope
+import com.android.internal.logging.uiEventLoggerFake
import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
@@ -33,6 +34,7 @@
import com.android.systemui.qs.panels.ui.viewmodel.inFirstPageViewModel
import com.android.systemui.qs.panels.ui.viewmodel.mediaInRowInLandscapeViewModelFactory
import com.android.systemui.qs.ui.viewmodel.quickSettingsContainerViewModelFactory
+import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.largeScreenHeaderHelper
import com.android.systemui.shade.transition.largeScreenShadeInterpolator
import com.android.systemui.statusbar.disableflags.domain.interactor.disableFlagsInteractor
@@ -56,6 +58,7 @@
disableFlagsInteractor,
keyguardTransitionInteractor,
largeScreenShadeInterpolator,
+ shadeInteractor,
configurationInteractor,
largeScreenHeaderHelper,
tileSquishinessInteractor,
@@ -66,6 +69,7 @@
qqsMediaHost,
qsMediaHost,
usingMediaInComposeFragment,
+ uiEventLoggerFake,
lifecycleScope,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepositoryKosmos.kt
index 4acedaa..322b412 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepositoryKosmos.kt
@@ -18,5 +18,4 @@
import com.android.systemui.kosmos.Kosmos
-var Kosmos.gridLayoutTypeRepository: GridLayoutTypeRepository by
- Kosmos.Fixture { GridLayoutTypeRepositoryImpl() }
+var Kosmos.gridLayoutTypeRepository by Kosmos.Fixture { GridLayoutTypeRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractorKosmos.kt
index c951642..40c3c96 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/GridLayoutTypeInteractorKosmos.kt
@@ -20,10 +20,19 @@
import com.android.systemui.qs.panels.data.repository.gridLayoutTypeRepository
import com.android.systemui.qs.panels.shared.model.GridLayoutType
import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType
+import com.android.systemui.qs.panels.shared.model.PaginatedGridLayoutType
import com.android.systemui.qs.panels.ui.compose.GridLayout
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.infiniteGridLayout
+import com.android.systemui.qs.panels.ui.compose.paginatedGridLayout
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
val Kosmos.gridLayoutTypeInteractor by
- Kosmos.Fixture { GridLayoutTypeInteractor(gridLayoutTypeRepository) }
+ Kosmos.Fixture { GridLayoutTypeInteractor(gridLayoutTypeRepository, shadeModeInteractor) }
val Kosmos.gridLayoutMap: Map<GridLayoutType, GridLayout> by
- Kosmos.Fixture { mapOf(Pair(InfiniteGridLayoutType, infiniteGridLayout)) }
+ Kosmos.Fixture {
+ mapOf(
+ Pair(InfiniteGridLayoutType, infiniteGridLayout),
+ Pair(PaginatedGridLayoutType, paginatedGridLayout),
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayoutKosmos.kt
similarity index 61%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayoutKosmos.kt
index b8d3ff4..f412d98 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayoutKosmos.kt
@@ -14,16 +14,11 @@
* limitations under the License.
*/
-package com.android.systemui.qs.panels.ui.viewmodel
+package com.android.systemui.qs.panels.ui.compose
-import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.infiniteGridLayout
+import com.android.systemui.qs.panels.ui.viewmodel.paginatedGridViewModelFactory
-val Kosmos.editModeButtonViewModelFactory by
- Kosmos.Fixture {
- object : EditModeButtonViewModel.Factory {
- override fun create(): EditModeButtonViewModel {
- return EditModeButtonViewModel(editModeViewModel, falsingInteractor)
- }
- }
- }
+val Kosmos.paginatedGridLayout by
+ Kosmos.Fixture { PaginatedGridLayout(paginatedGridViewModelFactory, infiniteGridLayout) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayoutKosmos.kt
similarity index 89%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayoutKosmos.kt
index 6fe860c..f57806c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayoutKosmos.kt
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-package com.android.systemui.qs.panels.domain.interactor
+package com.android.systemui.qs.panels.ui.compose.infinitegrid
import com.android.systemui.haptics.msdl.tileHapticsViewModelFactoryProvider
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.panels.ui.compose.infinitegrid.InfiniteGridLayout
import com.android.systemui.qs.panels.ui.viewmodel.detailsViewModel
import com.android.systemui.qs.panels.ui.viewmodel.iconTilesViewModel
import com.android.systemui.qs.panels.ui.viewmodel.infiniteGridViewModelFactory
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt
index 33227a4..71408f6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt
@@ -17,14 +17,16 @@
package com.android.systemui.qs.panels.ui.viewmodel
import android.content.applicationContext
+import com.android.internal.logging.uiEventLoggerFake
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.kosmos.testDispatcher
import com.android.systemui.qs.panels.domain.interactor.editTilesListInteractor
import com.android.systemui.qs.panels.domain.interactor.gridLayoutMap
import com.android.systemui.qs.panels.domain.interactor.gridLayoutTypeInteractor
-import com.android.systemui.qs.panels.domain.interactor.infiniteGridLayout
import com.android.systemui.qs.panels.domain.interactor.tilesAvailabilityInteractor
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.infiniteGridLayout
import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
import com.android.systemui.qs.pipeline.domain.interactor.minimumTilesInteractor
@@ -35,10 +37,12 @@
currentTilesInteractor,
tilesAvailabilityInteractor,
minimumTilesInteractor,
+ uiEventLoggerFake,
configurationInteractor,
applicationContext,
infiniteGridLayout,
applicationCoroutineScope,
+ testDispatcher,
gridLayoutTypeInteractor,
gridLayoutMap,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
index 5c71ba2..128cfca 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
@@ -20,6 +20,7 @@
import com.android.systemui.development.ui.viewmodel.buildNumberViewModelFactory
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.panels.domain.interactor.paginatedGridInteractor
+import com.android.systemui.qs.panels.ui.viewmodel.toolbar.editModeButtonViewModelFactory
val Kosmos.paginatedGridViewModel by
Kosmos.Fixture {
@@ -33,3 +34,10 @@
falsingInteractor,
)
}
+
+val Kosmos.paginatedGridViewModelFactory by
+ Kosmos.Fixture {
+ object : PaginatedGridViewModel.Factory {
+ override fun create() = paginatedGridViewModel
+ }
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/TileGridViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/TileGridViewModelKosmos.kt
index 9481fca..e79d213 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/TileGridViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/TileGridViewModelKosmos.kt
@@ -20,7 +20,7 @@
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.qs.panels.domain.interactor.gridLayoutMap
import com.android.systemui.qs.panels.domain.interactor.gridLayoutTypeInteractor
-import com.android.systemui.qs.panels.domain.interactor.infiniteGridLayout
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.infiniteGridLayout
import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
val Kosmos.tileGridViewModel by
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/EditModeButtonViewModelKosmos.kt
similarity index 88%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/EditModeButtonViewModelKosmos.kt
index b8d3ff4..8ae1332 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/EditModeButtonViewModelKosmos.kt
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-package com.android.systemui.qs.panels.ui.viewmodel
+package com.android.systemui.qs.panels.ui.viewmodel.toolbar
import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
val Kosmos.editModeButtonViewModelFactory by
Kosmos.Fixture {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/ToolbarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/ToolbarViewModelKosmos.kt
new file mode 100644
index 0000000..52d8a3a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/toolbar/ToolbarViewModelKosmos.kt
@@ -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.
+ */
+
+package com.android.systemui.qs.panels.ui.viewmodel.toolbar
+
+import android.content.applicationContext
+import com.android.systemui.classifier.domain.interactor.falsingInteractor
+import com.android.systemui.globalactions.globalActionsDialogLite
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.footerActionsInteractor
+
+val Kosmos.toolbarViewModelFactory by
+ Kosmos.Fixture {
+ object : ToolbarViewModel.Factory {
+ override fun create(): ToolbarViewModel {
+ return ToolbarViewModel(
+ editModeButtonViewModelFactory,
+ footerActionsInteractor,
+ { globalActionsDialogLite },
+ falsingInteractor,
+ applicationContext,
+ )
+ }
+ }
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileUserActionInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileUserActionInteractor.kt
index 597d52d..bc1c60c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileUserActionInteractor.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileUserActionInteractor.kt
@@ -16,6 +16,8 @@
package com.android.systemui.qs.tiles.base.interactor
+import com.android.systemui.plugins.qs.TileDetailsViewModel
+import com.android.systemui.qs.FakeTileDetailsViewModel
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
@@ -31,4 +33,7 @@
override suspend fun handleInput(input: QSTileInput<T>) {
mutex.withLock { mutableInputs.add(input) }
}
+
+ override var detailsViewModel: TileDetailsViewModel? =
+ FakeTileDetailsViewModel("FakeQSTileUserActionInteractor")
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
index 6afc0d80..aa6ce9a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
@@ -22,6 +22,7 @@
import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
import com.android.systemui.qs.panels.ui.viewmodel.quickQuickSettingsViewModelFactory
import com.android.systemui.qs.panels.ui.viewmodel.tileGridViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.toolbar.toolbarViewModelFactory
val Kosmos.quickSettingsContainerViewModelFactory by
Kosmos.Fixture {
@@ -36,6 +37,7 @@
tileGridViewModel,
editModeViewModel,
detailsViewModel,
+ toolbarViewModelFactory,
)
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerKosmos.kt
new file mode 100644
index 0000000..fa5bd7a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerKosmos.kt
@@ -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.
+ */
+
+package com.android.systemui.statusbar.notification
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.plugins.statusbar.statusBarStateController
+import com.android.systemui.statusbar.notificationLockscreenUserManager
+import com.android.systemui.statusbar.policy.keyguardStateController
+import org.mockito.kotlin.mock
+
+var Kosmos.dynamicPrivacyController: DynamicPrivacyController by
+ Kosmos.Fixture {
+ DynamicPrivacyController(
+ notificationLockscreenUserManager,
+ keyguardStateController,
+ statusBarStateController,
+ )
+ }
+
+var Kosmos.mockDynamicPrivacyController: DynamicPrivacyController by Kosmos.Fixture { mock() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorKosmos.kt
new file mode 100644
index 0000000..88bf9a5
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorKosmos.kt
@@ -0,0 +1,47 @@
+/*
+ * 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.collection.coordinator
+
+import com.android.keyguard.keyguardUpdateMonitor
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.plugins.statusbar.statusBarStateController
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.statusbar.notification.dynamicPrivacyController
+import com.android.systemui.statusbar.notificationLockscreenUserManager
+import com.android.systemui.statusbar.policy.keyguardStateController
+import com.android.systemui.statusbar.policy.sensitiveNotificationProtectionController
+import com.android.systemui.user.domain.interactor.selectedUserInteractor
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+@OptIn(ExperimentalCoroutinesApi::class)
+var Kosmos.sensitiveContentCoordinator: SensitiveContentCoordinator by
+ Kosmos.Fixture {
+ SensitiveContentCoordinatorImpl(
+ dynamicPrivacyController,
+ notificationLockscreenUserManager,
+ keyguardUpdateMonitor,
+ statusBarStateController,
+ keyguardStateController,
+ selectedUserInteractor,
+ sensitiveNotificationProtectionController,
+ deviceEntryInteractor,
+ sceneInteractor,
+ testScope.backgroundScope,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt
index 3963d7c..766b280 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt
@@ -23,5 +23,6 @@
fun inCallModel(
startTimeMs: Long,
notificationIcon: StatusBarIconView? = null,
- intent: PendingIntent? = null
-) = OngoingCallModel.InCall(startTimeMs, notificationIcon, intent)
+ intent: PendingIntent? = null,
+ notificationKey: String = "test",
+) = OngoingCallModel.InCall(startTimeMs, notificationIcon, intent, notificationKey)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerKosmos.kt
similarity index 60%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerKosmos.kt
index b8d3ff4..8f9184d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerKosmos.kt
@@ -14,16 +14,13 @@
* limitations under the License.
*/
-package com.android.systemui.qs.panels.ui.viewmodel
+package com.android.systemui.statusbar.policy
-import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
-val Kosmos.editModeButtonViewModelFactory by
- Kosmos.Fixture {
- object : EditModeButtonViewModel.Factory {
- override fun create(): EditModeButtonViewModel {
- return EditModeButtonViewModel(editModeViewModel, falsingInteractor)
- }
- }
- }
+var Kosmos.sensitiveNotificationProtectionController: SensitiveNotificationProtectionController by
+ Kosmos.Fixture { mockSensitiveNotificationProtectionController }
+val Kosmos.mockSensitiveNotificationProtectionController:
+ SensitiveNotificationProtectionController by
+ Kosmos.Fixture { mock<SensitiveNotificationProtectionController>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelKosmos.kt
index c8ba551..34661ce 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelKosmos.kt
@@ -21,6 +21,7 @@
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.statusbar.notification.domain.interactor.notificationsSoundPolicyInteractor
import com.android.systemui.volume.dialog.domain.interactor.volumeDialogVisibilityInteractor
import com.android.systemui.volume.dialog.ringer.domain.volumeDialogRingerInteractor
import com.android.systemui.volume.dialog.shared.volumeDialogLogger
@@ -31,7 +32,8 @@
applicationContext = applicationContext,
backgroundDispatcher = testDispatcher,
coroutineScope = applicationCoroutineScope,
- interactor = volumeDialogRingerInteractor,
+ soundPolicyInteractor = notificationsSoundPolicyInteractor,
+ ringerInteractor = volumeDialogRingerInteractor,
vibrator = vibratorHelper,
volumeDialogLogger = volumeDialogLogger,
visibilityInteractor = volumeDialogVisibilityInteractor,
diff --git a/services/autofill/bugfixes.aconfig b/services/autofill/bugfixes.aconfig
index 5e1b147..9c83757 100644
--- a/services/autofill/bugfixes.aconfig
+++ b/services/autofill/bugfixes.aconfig
@@ -9,6 +9,16 @@
}
flag {
+ name: "improve_fill_dialog_aconfig"
+ namespace: "autofill"
+ description: "Improvements for Fill Dialog. Guard DeviceConfig rollout "
+ bug: "382493181"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "fill_fields_from_current_session_only"
namespace: "autofill"
description: "Only fill autofill fields that are part of the current session."
diff --git a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java
index 219b788..5e7e557 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java
@@ -354,6 +354,13 @@
}
}
+ private void handleOnInputMethodStartInputView() {
+ synchronized (mLock) {
+ mUiCallback.onInputMethodStartInputView();
+ handleOnReceiveImeStatusUpdated(true, true);
+ }
+ }
+
/**
* Handles the IME session status received from the IME.
*
@@ -437,8 +444,8 @@
final AutofillInlineSuggestionsRequestSession session = mSession.get();
if (session != null) {
session.mHandler.sendMessage(obtainMessage(
- AutofillInlineSuggestionsRequestSession::handleOnReceiveImeStatusUpdated,
- session, true, true));
+ AutofillInlineSuggestionsRequestSession::handleOnInputMethodStartInputView,
+ session));
}
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 259ea14..cba8c66 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -2139,6 +2139,32 @@
}
@Override
+ public void notifyImeAnimationStart(int sessionId, long startTimeMs, int userId) {
+ synchronized (mLock) {
+ final AutofillManagerServiceImpl service =
+ peekServiceForUserWithLocalBinderIdentityLocked(userId);
+ if (service != null) {
+ service.notifyImeAnimationStart(sessionId, startTimeMs, getCallingUid());
+ } else if (sVerbose) {
+ Slog.v(TAG, "notifyImeAnimationStart(): no service for " + userId);
+ }
+ }
+ }
+
+ @Override
+ public void notifyImeAnimationEnd(int sessionId, long endTimeMs, int userId) {
+ synchronized (mLock) {
+ final AutofillManagerServiceImpl service =
+ peekServiceForUserWithLocalBinderIdentityLocked(userId);
+ if (service != null) {
+ service.notifyImeAnimationEnd(sessionId, endTimeMs, getCallingUid());
+ } else if (sVerbose) {
+ Slog.v(TAG, "notifyImeAnimationEnd(): no service for " + userId);
+ }
+ }
+ }
+
+ @Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 5cf96bf..0fa43ac 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -823,6 +823,36 @@
}
@GuardedBy("mLock")
+ public void notifyImeAnimationStart(int sessionId, long startTimeMs, int uid) {
+ if (!isEnabledLocked()) {
+ Slog.wtf(TAG, "Service not enabled");
+ return;
+ }
+ final Session session = mSessions.get(sessionId);
+ if (session == null || uid != session.uid) {
+ Slog.v(TAG, "notifyImeAnimationStart(): no session for "
+ + sessionId + "(" + uid + ")");
+ return;
+ }
+ session.notifyImeAnimationStart(startTimeMs);
+ }
+
+ @GuardedBy("mLock")
+ public void notifyImeAnimationEnd(int sessionId, long endTimeMs, int uid) {
+ if (!isEnabledLocked()) {
+ Slog.wtf(TAG, "Service not enabled");
+ return;
+ }
+ final Session session = mSessions.get(sessionId);
+ if (session == null || uid != session.uid) {
+ Slog.v(TAG, "notifyImeAnimationEnd(): no session for "
+ + sessionId + "(" + uid + ")");
+ return;
+ }
+ session.notifyImeAnimationEnd(endTimeMs);
+ }
+
+ @GuardedBy("mLock")
@Override // from PerUserSystemService
protected void handlePackageUpdateLocked(@NonNull String packageName) {
final ServiceInfo serviceInfo = mFieldClassificationStrategy.getServiceInfo();
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 6b227d7..9c6e4741 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -40,6 +40,7 @@
import static android.service.autofill.FillRequest.FLAG_VIEW_REQUESTS_CREDMAN_SERVICE;
import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
import static android.service.autofill.Flags.highlightAutofillSingleField;
+import static android.service.autofill.Flags.improveFillDialogAconfig;
import static android.view.autofill.AutofillManager.ACTION_RESPONSE_EXPIRED;
import static android.view.autofill.AutofillManager.ACTION_START_SESSION;
import static android.view.autofill.AutofillManager.ACTION_VALUE_CHANGED;
@@ -50,6 +51,7 @@
import static android.view.autofill.AutofillManager.EXTRA_AUTOFILL_REQUEST_ID;
import static android.view.autofill.AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM;
import static android.view.autofill.AutofillManager.getSmartSuggestionModeToString;
+
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static com.android.server.autofill.FillRequestEventLogger.TRIGGER_REASON_EXPLICITLY_REQUESTED;
import static com.android.server.autofill.FillRequestEventLogger.TRIGGER_REASON_NORMAL_TRIGGER;
@@ -184,6 +186,7 @@
import android.view.autofill.IAutofillWindowPresenter;
import android.view.inputmethod.InlineSuggestionsRequest;
import android.widget.RemoteViews;
+
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
@@ -195,6 +198,7 @@
import com.android.server.autofill.ui.PendingUi;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
+
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -248,6 +252,8 @@
private static final int DEFAULT__FILL_REQUEST_ID_SNAPSHOT = -2;
private static final int DEFAULT__FIELD_CLASSIFICATION_REQUEST_ID_SNAPSHOT = -2;
+ private static final long DEFAULT_UNASSIGNED_TIME = -1;
+
static final String SESSION_ID_KEY = "autofill_session_id";
static final String REQUEST_ID_KEY = "autofill_request_id";
@@ -292,6 +298,31 @@
@Retention(RetentionPolicy.SOURCE)
@interface SessionState {}
+ /**
+ * Indicates fill dialog will not be shown.
+ */
+ private static final int SHOW_FILL_DIALOG_NO = 0;
+
+ /**
+ * Indicates fill dialog is shown.
+ */
+ private static final int SHOW_FILL_DIALOG_YES = 1;
+
+ /**
+ * Indicates fill dialog can be shown, but we need to wait.
+ * For eg, if the IME animation is happening, we need for it to complete before fill dialog can
+ * be shown.
+ */
+ private static final int SHOW_FILL_DIALOG_WAIT = 2;
+
+ @IntDef(prefix = { "SHOW_FILL_DIALOG_" }, value = {
+ SHOW_FILL_DIALOG_NO,
+ SHOW_FILL_DIALOG_YES,
+ SHOW_FILL_DIALOG_WAIT
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface ShowFillDialogState{}
+
@GuardedBy("mLock")
private final SessionFlags mSessionFlags;
@@ -576,6 +607,47 @@
private boolean mIgnoreViewStateResetToEmpty;
+ /**
+ * Whether improveFillDialog feature is enabled or not.
+ * Configured via device config flag and aconfig flag.
+ */
+ private final boolean mImproveFillDialogEnabled;
+
+ /**
+ * Timeout, after which, fill dialog won't be shown.
+ * Configured via device config flag.
+ */
+ private final long mFillDialogTimeoutMs;
+
+ /**
+ * Time to wait after ime Animation ends before showing up fill dialog.
+ * Configured via device config flag.
+ */
+ private final long mFillDialogMinWaitAfterImeAnimationMs;
+
+ /**
+ * Indicates the need to wait for ime animation to end before showing up fill dialog.
+ * This is set when we receive notification of ime animation start.
+ * Focussing on one input field from another wouldn't cause ime to re-animate. So this will let
+ * us know whether we need to wait for ime animation finish notification.
+ */
+ private boolean mWaitForImeAnimation;
+
+ /**
+ * A runnable set to run when there is a need to wait for ime animation to end before showing
+ * up fill dialog. This is set only if the fill response has been received, and the response
+ * is eligible for showing up fill dialog, but the ime animation hasn't completed. This allows
+ * for this runnable to be scheduled/run when the ime animation ends, in order to show fill
+ * dialog.
+ */
+ private Runnable mFillDialogRunnable;
+
+ private long mImeAnimationFinishTimeMs = DEFAULT_UNASSIGNED_TIME;
+
+ private long mImeAnimationStartTimeMs = DEFAULT_UNASSIGNED_TIME;
+
+ private long mLastInputStartTime = DEFAULT_UNASSIGNED_TIME;
+
/*
* Id of the previous view that was entered. Once set, it would only be replaced by non-null
* view ids.
@@ -1493,6 +1565,12 @@
// Now request the assist structure data.
requestAssistStructureLocked(requestId, flags);
+ if (mImproveFillDialogEnabled) {
+ // New request has been sent, so re-enable fill dialog.
+ // Fill dialog is eligible to be shown after each Fill request.
+ enableFillDialog();
+ }
+
return Optional.of(requestId);
}
@@ -1657,6 +1735,11 @@
mSaveEventLogger = SaveEventLogger.forSessionId(sessionId, mLatencyBaseTime);
mIsPrimaryCredential = isPrimaryCredential;
mIgnoreViewStateResetToEmpty = AutofillFeatureFlags.shouldIgnoreViewStateResetToEmpty();
+ mImproveFillDialogEnabled =
+ improveFillDialogAconfig() && AutofillFeatureFlags.isImproveFillDialogEnabled();
+ mFillDialogTimeoutMs = AutofillFeatureFlags.getFillDialogTimeoutMs();
+ mFillDialogMinWaitAfterImeAnimationMs =
+ AutofillFeatureFlags.getFillDialogMinWaitAfterImeAnimationtEndMs();
synchronized (mLock) {
mSessionFlags = new SessionFlags();
@@ -1682,6 +1765,13 @@
public void notifyInlineUiHidden(AutofillId autofillId) {
notifyFillUiHidden(autofillId);
}
+
+ @Override
+ public void onInputMethodStartInputView() {
+ // TODO(b/377868687): This method isn't called when IME doesn't
+ // support inline suggestion. Handle those cases as well.
+ onInputMethodStart();
+ }
});
mMetricsLogger.write(
@@ -3044,6 +3134,12 @@
}
}
+ private void onInputMethodStart() {
+ synchronized (mLock) {
+ mLastInputStartTime = SystemClock.elapsedRealtime();
+ }
+ }
+
private void doStartIntentSender(IntentSender intentSender, Intent intent) {
try {
synchronized (mLock) {
@@ -5407,6 +5503,15 @@
}
}
+ private void resetImeAnimationState() {
+ synchronized (mLock) {
+ mWaitForImeAnimation = false;
+ mImeAnimationStartTimeMs = DEFAULT_UNASSIGNED_TIME;
+ mImeAnimationFinishTimeMs = DEFAULT_UNASSIGNED_TIME;
+ mLastInputStartTime = DEFAULT_UNASSIGNED_TIME;
+ }
+ }
+
@Override
public void onFillReady(
@NonNull FillResponse response,
@@ -5452,18 +5557,24 @@
final AutofillId[] ids = response.getFillDialogTriggerIds();
if (ids != null && ArrayUtils.contains(ids, filledId)) {
- if (requestShowFillDialog(response, filledId, filterText, flags)) {
+ @ShowFillDialogState int fillDialogState =
+ requestShowFillDialog(response, filledId, filterText, flags);
+ if (fillDialogState == SHOW_FILL_DIALOG_YES) {
synchronized (mLock) {
final ViewState currentView = mViewStates.get(mCurrentViewId);
currentView.setState(ViewState.STATE_FILL_DIALOG_SHOWN);
}
- // Just show fill dialog once, so disabled after shown.
+ // Just show fill dialog once per fill request, so disabled after shown.
// Note: Cannot disable before requestShowFillDialog() because the method
- // need to check whether fill dialog enabled.
+ // need to check whether fill dialog is enabled.
setFillDialogDisabled();
+ resetImeAnimationState();
return;
- } else {
+ } else if (fillDialogState == SHOW_FILL_DIALOG_NO) {
+ resetImeAnimationState();
setFillDialogDisabled();
+ } else { // SHOW_FILL_DIALOG_WAIT
+ return;
}
}
@@ -5559,7 +5670,20 @@
}
}
+ private void enableFillDialog() {
+ if (sVerbose) {
+ Slog.v(TAG, "Enabling Fill Dialog....");
+ }
+ synchronized (mLock) {
+ mSessionFlags.mFillDialogDisabled = false;
+ }
+ notifyClientFillDialogTriggerIds(null);
+ }
+
private void setFillDialogDisabled() {
+ if (sVerbose) {
+ Slog.v(TAG, "Disabling Fill Dialog.");
+ }
synchronized (mLock) {
mSessionFlags.mFillDialogDisabled = true;
}
@@ -5577,24 +5701,28 @@
}
}
- private boolean requestShowFillDialog(
+ private @ShowFillDialogState int requestShowFillDialog(
FillResponse response, AutofillId filledId, String filterText, int flags) {
if (!isFillDialogUiEnabled()) {
+ // TODO(b/377868687): The above check includes credman fields. We may want to show
+ // credman fields again.
// Unsupported fill dialog UI
- if (sDebug) Log.w(TAG, "requestShowFillDialog: fill dialog is disabled");
- return false;
+ if (sDebug) Log.w(TAG, "requestShowFillDialog(): fill dialog is disabled");
+ return SHOW_FILL_DIALOG_NO;
}
- if ((flags & FillRequest.FLAG_IME_SHOWING) != 0) {
- // IME is showing, fallback to normal suggestions UI
- if (sDebug) Log.w(TAG, "requestShowFillDialog: IME is showing");
- return false;
- }
+ if (!mImproveFillDialogEnabled) {
+ if ((flags & FillRequest.FLAG_IME_SHOWING) != 0) {
+ // IME is showing, fallback to normal suggestions UI
+ if (sDebug) Log.w(TAG, "requestShowFillDialog(): IME is showing");
+ return SHOW_FILL_DIALOG_NO;
+ }
- if (mInlineSessionController.isImeShowing()) {
- // IME is showing, fallback to normal suggestions UI
- // Note: only work when inline suggestions supported
- return false;
+ if (mInlineSessionController.isImeShowing()) {
+ // IME is showing, fallback to normal suggestions UI
+ // Note: only work when inline suggestions supported
+ return SHOW_FILL_DIALOG_NO;
+ }
}
synchronized (mLock) {
@@ -5602,29 +5730,84 @@
|| !ArrayUtils.contains(mLastFillDialogTriggerIds, filledId)) {
// Last fill dialog triggered ids are changed.
if (sDebug) Log.w(TAG, "Last fill dialog triggered ids are changed.");
- return false;
+ return SHOW_FILL_DIALOG_NO;
+ }
+
+ if (mImproveFillDialogEnabled && mInlineSessionController.isImeShowing()) {
+ long currentTimestampMs = SystemClock.elapsedRealtime();
+ long durationMs = currentTimestampMs - mLastInputStartTime;
+ if (sVerbose) {
+ Log.d(TAG, "IME is showing. Checking for elapsed time ");
+ Log.d(TAG, "IME is showing. Timestamps start: " + mLastInputStartTime
+ + " current: " + currentTimestampMs + " duration: " + durationMs
+ + " mFillDialogTimeoutMs: " + mFillDialogTimeoutMs);
+ }
+
+ // Following situations can arise wrt IME animation.
+ // 1. No animation happening (eg IME already animated). In that case,
+ // mWaitForImeAnimation should be false. This is possible if the IME is already up
+ // on a field, but the user focusses on another field. Under such condition,
+ // since IME has already animated, there won't be another animation. However,
+ // onInputStartInputView is still called.
+ // 2. Animation is still proceeding. We should wait for animation to finish,
+ // and then proceed.
+ // 3. Animation is complete.
+ if (mWaitForImeAnimation) {
+ // we need to wait for animation to happen. We can't return from here yet.
+ // This is the situation #2 described above.
+ Log.d(TAG, "Waiting for ime animation to complete before showing fill dialog");
+ mFillDialogRunnable = createFillDialogEvalRunnable(
+ response, filledId, filterText, flags);
+ return SHOW_FILL_DIALOG_WAIT;
+ }
+
+ // Incorporate situations 1 & 3 discussed above. We calculate the duration from the
+ // max of start input time or the ime finish time
+ long effectiveDuration = currentTimestampMs
+ - Math.max(mLastInputStartTime, mImeAnimationFinishTimeMs);
+ if (effectiveDuration >= mFillDialogTimeoutMs) {
+ Log.d(TAG, "Fill dialog not shown since IME has been up for more time than "
+ + mFillDialogTimeoutMs + "ms");
+ return SHOW_FILL_DIALOG_NO;
+ } else if (effectiveDuration < mFillDialogMinWaitAfterImeAnimationMs) {
+ // we need to wait for some time after animation ends
+ Runnable runnable = createFillDialogEvalRunnable(
+ response, filledId, filterText, flags);
+ mHandler.postDelayed(runnable,
+ mFillDialogMinWaitAfterImeAnimationMs - effectiveDuration);
+ return SHOW_FILL_DIALOG_WAIT;
+ }
}
}
+ showFillDialog(response, filledId, filterText);
+ return SHOW_FILL_DIALOG_YES;
+ }
+
+ private Runnable createFillDialogEvalRunnable(
+ @NonNull FillResponse response,
+ @NonNull AutofillId filledId,
+ String filterText,
+ int flags) {
+ return () -> {
+ synchronized (mLock) {
+ AutofillValue value = AutofillValue.forText(filterText);
+ onFillReady(response, filledId, value, flags);
+ }
+ };
+ }
+
+ private void showFillDialog(FillResponse response, AutofillId filledId, String filterText) {
Drawable serviceIcon = null;
+ PresentationStatsEventLogger logger = null;
synchronized (mLock) {
serviceIcon = getServiceIcon(response);
+ logger = mPresentationStatsEventLogger;
}
- getUiForShowing()
- .showFillDialog(
- filledId,
- response,
- filterText,
- mService.getServicePackageName(),
- mComponentName,
- serviceIcon,
- this,
- id,
- mCompatMode,
- mPresentationStatsEventLogger,
- mLock);
- return true;
+ getUiForShowing().showFillDialog(filledId, response, filterText,
+ mService.getServicePackageName(), mComponentName, serviceIcon, this,
+ id, mCompatMode, logger, mLock);
}
/**
@@ -7689,6 +7872,30 @@
mSessionState = STATE_REMOVED;
}
+ @GuardedBy("mLock")
+ public void notifyImeAnimationStart(long startTimeMs) {
+ mImeAnimationStartTimeMs = startTimeMs;
+ mWaitForImeAnimation = true;
+ }
+
+ @GuardedBy("mLock")
+ public void notifyImeAnimationEnd(long endTimeMs) {
+ mImeAnimationFinishTimeMs = endTimeMs;
+ // Make sure to use mRunnable with synchronized
+ if (mFillDialogRunnable != null) {
+ if (sVerbose) {
+ Log.v(TAG, "Ime animation ended, starting fill dialog.");
+ }
+ mHandler.postDelayed(mFillDialogRunnable, mFillDialogMinWaitAfterImeAnimationMs);
+ mFillDialogRunnable = null;
+ } else {
+ if (sVerbose) {
+ Log.v(TAG, "Ime animation ended, no runnable present.");
+ }
+ }
+ mWaitForImeAnimation = false;
+ }
+
void onPendingSaveUi(int operation, @NonNull IBinder token) {
getUiForShowing().onPendingSaveUi(operation, token);
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java b/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java
index ffc80ee..7287bdd 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/InlineFillUi.java
@@ -409,5 +409,10 @@
* Callback to notify inline ui is hidden.
*/
void notifyInlineUiHidden(@NonNull AutofillId autofillId);
+
+ /**
+ * Callback to notify input method started.
+ */
+ void onInputMethodStartInputView();
}
}
diff --git a/services/companion/java/com/android/server/companion/BackupRestoreProcessor.java b/services/companion/java/com/android/server/companion/BackupRestoreProcessor.java
index 4bcfb33..7c8604f 100644
--- a/services/companion/java/com/android/server/companion/BackupRestoreProcessor.java
+++ b/services/companion/java/com/android/server/companion/BackupRestoreProcessor.java
@@ -240,9 +240,9 @@
boolean matchesMacAddress = Objects.equals(
associationInfo.getDeviceMacAddress(),
restored.getDeviceMacAddress());
- boolean matchesDeviceId = !Flags.associationTag()
- || (associationInfo.getDeviceId() != null
- && associationInfo.getDeviceId().isSameDevice(restored.getDeviceId()));
+ boolean matchesDeviceId = Flags.associationTag()
+ && (associationInfo.getDeviceId() != null
+ && associationInfo.getDeviceId().isSameDevice(restored.getDeviceId()));
return matchesMacAddress || matchesDeviceId;
};
AssociationInfo local = CollectionUtils.find(localAssociations, isSameDevice);
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 371306f..b3d85f8 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -158,8 +158,8 @@
"android.hardware.light-V2.0-java",
"android.hardware.gnss-V2-java",
"android.hardware.vibrator-V3-java",
+ "androidx.annotation_annotation",
"app-compat-annotations",
- "art_exported_aconfig_flags_lib",
"framework-tethering.stubs.module_lib",
"keepanno-annotations",
"service-art.stubs.system_server",
@@ -246,6 +246,7 @@
"locksettings_flags_lib",
"profiling_flags_lib",
"android.adpf.sessionmanager_aidl-java",
+ "uprobestats_flags_java_lib",
],
javac_shard_size: 50,
javacflags: [
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index eba9a25..bd7a0ac 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -449,6 +449,8 @@
private AtomicBoolean mIsSatelliteEnabled;
private AtomicBoolean mWasSatelliteEnabledNotified;
+ private final int mPid = Process.myPid();
+
/**
* Per-phone map of precise data connection state. The key of the map is the pair of transport
* type and APN setting. This is the cache to prevent redundant callbacks to the listeners.
@@ -1441,7 +1443,17 @@
}
if (events.contains(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)) {
try {
- r.callback.onCallStatesChanged(mCallStateLists.get(r.phoneId));
+ if (Flags.passCopiedCallStateList()) {
+ List<CallState> callList;
+ if (r.callerPid == mPid) {
+ callList = List.copyOf(mCallStateLists.get(r.phoneId));
+ } else {
+ callList = mCallStateLists.get(r.phoneId);
+ }
+ r.callback.onCallStatesChanged(callList);
+ } else {
+ r.callback.onCallStatesChanged(mCallStateLists.get(r.phoneId));
+ }
} catch (RemoteException ex) {
remove(r.binder);
}
@@ -2573,12 +2585,25 @@
}
if (notifyCallState) {
+ List<CallState> copyList = null;
for (Record r : mRecords) {
if (r.matchTelephonyCallbackEvent(
TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)
&& idMatch(r, subId, phoneId)) {
+ // If listener is in the same process, original instance can be passed
+ // to the listener via AIDL without serialization/de-serialization. We
+ // will pass the copied list. Since the element is newly created instead
+ // of modification for the change, we can use shallow copy for this.
try {
- r.callback.onCallStatesChanged(mCallStateLists.get(phoneId));
+ if (Flags.passCopiedCallStateList()) {
+ if (r.callerPid == mPid && copyList == null) {
+ copyList = List.copyOf(mCallStateLists.get(phoneId));
+ }
+ r.callback.onCallStatesChanged(copyList == null
+ ? mCallStateLists.get(phoneId) : copyList);
+ } else {
+ r.callback.onCallStatesChanged(mCallStateLists.get(phoneId));
+ }
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
@@ -2906,13 +2931,21 @@
log("There is no active call to report CallQuality");
return;
}
-
+ List<CallState> copyList = null;
for (Record r : mRecords) {
if (r.matchTelephonyCallbackEvent(
TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)
&& idMatch(r, subId, phoneId)) {
try {
- r.callback.onCallStatesChanged(mCallStateLists.get(phoneId));
+ if (Flags.passCopiedCallStateList()) {
+ if (r.callerPid == mPid && copyList == null) {
+ copyList = List.copyOf(mCallStateLists.get(phoneId));
+ }
+ r.callback.onCallStatesChanged(copyList == null
+ ? mCallStateLists.get(phoneId) : copyList);
+ } else {
+ r.callback.onCallStatesChanged(mCallStateLists.get(phoneId));
+ }
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 3ce6451..719928b 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -2846,6 +2846,14 @@
: AccountsDb.DEBUG_ACTION_SET_PASSWORD;
logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts,
callingUid);
+
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.ACCOUNT_MANAGER_EVENT,
+ account.type,
+ callingUid,
+ TextUtils.isEmpty(password)
+ ? FrameworkStatsLog.ACCOUNT_MANAGER_EVENT__EVENT_TYPE__PASSWORD_REMOVED
+ : FrameworkStatsLog.ACCOUNT_MANAGER_EVENT__EVENT_TYPE__PASSWORD_CHANGED);
}
} finally {
accounts.accountsDb.endTransaction();
@@ -2912,7 +2920,7 @@
if (!accountExistsCache(accounts, account)) {
return;
}
- setUserdataInternal(accounts, account, key, value);
+ setUserdataInternal(accounts, account, key, value, callingUid);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -2932,7 +2940,7 @@
}
private void setUserdataInternal(UserAccounts accounts, Account account, String key,
- String value) {
+ String value, int callingUid) {
synchronized (accounts.dbLock) {
accounts.accountsDb.beginTransaction();
try {
@@ -2958,6 +2966,11 @@
AccountManager.invalidateLocalAccountUserDataCaches();
}
}
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.ACCOUNT_MANAGER_EVENT,
+ account.type,
+ callingUid,
+ FrameworkStatsLog.ACCOUNT_MANAGER_EVENT__EVENT_TYPE__USER_DATA_CHANGED);
}
private void onResult(IAccountManagerResponse response, Bundle result) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ebe7fa5..cd929c1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -361,6 +361,8 @@
import android.os.incremental.IIncrementalService;
import android.os.incremental.IncrementalManager;
import android.os.incremental.IncrementalMetrics;
+import android.os.instrumentation.IOffsetCallback;
+import android.os.instrumentation.MethodDescriptor;
import android.os.storage.IStorageManager;
import android.os.storage.StorageManager;
import android.provider.DeviceConfig;
@@ -509,6 +511,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
@@ -2781,9 +2784,7 @@
mIsolatedAppBindArgs = new ArrayMap<>(1);
// See b/79378449 about the following exemption.
addServiceToMap(mIsolatedAppBindArgs, "package");
- if (!android.server.Flags.removeJavaServiceManagerCache()) {
- addServiceToMap(mIsolatedAppBindArgs, "permissionmgr");
- }
+ addServiceToMap(mIsolatedAppBindArgs, "permissionmgr");
}
return mIsolatedAppBindArgs;
}
@@ -2794,38 +2795,27 @@
// Add common services.
// IMPORTANT: Before adding services here, make sure ephemeral apps can access them too.
// Enable the check in ApplicationThread.bindApplication() to make sure.
-
- // Removing User Service and App Ops Service from cache breaks boot for auto.
- // Removing permissionmgr breaks tests for Android Auto due to SELinux restrictions.
- // TODO: fix SELinux restrictions and remove caching for Android Auto.
- if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
- || !android.server.Flags.removeJavaServiceManagerCache()) {
- addServiceToMap(mAppBindArgs, Context.ALARM_SERVICE);
- addServiceToMap(mAppBindArgs, Context.DISPLAY_SERVICE);
- addServiceToMap(mAppBindArgs, Context.NETWORKMANAGEMENT_SERVICE);
- addServiceToMap(mAppBindArgs, Context.CONNECTIVITY_SERVICE);
- addServiceToMap(mAppBindArgs, Context.ACCESSIBILITY_SERVICE);
- addServiceToMap(mAppBindArgs, Context.INPUT_METHOD_SERVICE);
- addServiceToMap(mAppBindArgs, Context.INPUT_SERVICE);
- addServiceToMap(mAppBindArgs, "graphicsstats");
- addServiceToMap(mAppBindArgs, "content");
- addServiceToMap(mAppBindArgs, Context.JOB_SCHEDULER_SERVICE);
- addServiceToMap(mAppBindArgs, Context.NOTIFICATION_SERVICE);
- addServiceToMap(mAppBindArgs, Context.VIBRATOR_SERVICE);
- addServiceToMap(mAppBindArgs, Context.ACCOUNT_SERVICE);
- addServiceToMap(mAppBindArgs, Context.POWER_SERVICE);
- addServiceToMap(mAppBindArgs, "mount");
- addServiceToMap(mAppBindArgs, Context.PLATFORM_COMPAT_SERVICE);
- }
- // See b/79378449
- // Getting the window service and package service binder from servicemanager
- // is blocked for Apps. However they are necessary for apps.
- // TODO: remove exception
addServiceToMap(mAppBindArgs, "package");
- addServiceToMap(mAppBindArgs, Context.WINDOW_SERVICE);
- addServiceToMap(mAppBindArgs, Context.USER_SERVICE);
addServiceToMap(mAppBindArgs, "permissionmgr");
+ addServiceToMap(mAppBindArgs, Context.WINDOW_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.ALARM_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.DISPLAY_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.NETWORKMANAGEMENT_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.CONNECTIVITY_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.ACCESSIBILITY_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.INPUT_METHOD_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.INPUT_SERVICE);
+ addServiceToMap(mAppBindArgs, "graphicsstats");
addServiceToMap(mAppBindArgs, Context.APP_OPS_SERVICE);
+ addServiceToMap(mAppBindArgs, "content");
+ addServiceToMap(mAppBindArgs, Context.JOB_SCHEDULER_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.NOTIFICATION_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.VIBRATOR_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.ACCOUNT_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.POWER_SERVICE);
+ addServiceToMap(mAppBindArgs, Context.USER_SERVICE);
+ addServiceToMap(mAppBindArgs, "mount");
+ addServiceToMap(mAppBindArgs, Context.PLATFORM_COMPAT_SERVICE);
}
return mAppBindArgs;
}
@@ -18055,6 +18045,26 @@
}
@Override
+ public void getExecutableMethodFileOffsets(@NonNull String processName,
+ int pid, int uid, @NonNull MethodDescriptor methodDescriptor,
+ @NonNull IOffsetCallback callback) {
+ final IApplicationThread thread;
+ synchronized (ActivityManagerService.this) {
+ ProcessRecord record = mProcessList.getProcessRecordLocked(processName, uid);
+ if (record == null || record.getPid() != pid) {
+ throw new NoSuchElementException();
+ }
+ thread = record.getThread();
+ }
+ try {
+ thread.getExecutableMethodFileOffsets(methodDescriptor, callback);
+ } catch (RemoteException e) {
+ throw new RuntimeException(
+ "IApplicationThread.getExecutableMethodFileOffsets failed", e);
+ }
+ }
+
+ @Override
public void addCreatorToken(Intent intent, String creatorPackage) {
ActivityManagerService.this.addCreatorToken(intent, creatorPackage);
}
@@ -19406,7 +19416,7 @@
return createOrGetIntentCreatorToken(intent, key);
} else {
- throw new IllegalArgumentException("intent does not contain a creator token.");
+ return null;
}
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index aea24d9..c27126a 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -1101,9 +1101,6 @@
/** StatsPullAtomCallback for pulling BatteryUsageStats data. */
private class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback {
- private static final long BATTERY_USAGE_STATS_PER_UID_MAX_STATS_AGE =
- TimeUnit.HOURS.toMillis(2);
-
@Override
public int onPullAtom(int atomTag, List<StatsEvent> data) {
final BatteryUsageStats bus;
@@ -1171,8 +1168,7 @@
.setMinConsumedPowerThreshold(minConsumedPowerThreshold);
if (isBatteryUsageStatsAccumulationSupported()) {
- query.accumulated()
- .setMaxStatsAgeMs(BATTERY_USAGE_STATS_PER_UID_MAX_STATS_AGE);
+ query.accumulated();
}
bus = getBatteryUsageStats(List.of(query.build())).get(0);
diff --git a/services/core/java/com/android/server/am/BroadcastFilter.java b/services/core/java/com/android/server/am/BroadcastFilter.java
index 05aeb42..8327639 100644
--- a/services/core/java/com/android/server/am/BroadcastFilter.java
+++ b/services/core/java/com/android/server/am/BroadcastFilter.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledSince;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.os.Binder;
@@ -41,7 +40,6 @@
* ({@link IntentFilter#SYSTEM_LOW_PRIORITY}, {@link IntentFilter#SYSTEM_HIGH_PRIORITY}).
*/
@ChangeId
- @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE)
@VisibleForTesting
static final long RESTRICT_PRIORITY_VALUES = 371309185L;
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index a1ab1eea..8d0805d 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -43,7 +43,6 @@
import android.app.BroadcastOptions;
import android.app.BroadcastOptions.DeliveryGroupPolicy;
import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledSince;
import android.content.ComponentName;
import android.content.IIntentReceiver;
import android.content.Intent;
@@ -86,7 +85,6 @@
* will only influence the order of broadcast delivery within the same process.
*/
@ChangeId
- @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE)
@VisibleForTesting
static final long LIMIT_PRIORITY_SCOPE = 371307720L;
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 6f83d0c..883e09f 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -216,6 +216,7 @@
"pixel_bluetooth",
"pixel_connectivity_gps",
"pixel_continuity",
+ "pixel_display",
"pixel_perf",
"pixel_sensors",
"pixel_state_server",
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 295e044..06c586f 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -3191,7 +3191,7 @@
resolveProxyPackageName, proxyAttributionTag, proxyVirtualDeviceId,
Process.INVALID_UID, null, null,
Context.DEVICE_ID_DEFAULT, proxyFlags, !isProxyTrusted,
- "proxy " + message, shouldCollectMessage, 1);
+ "proxy " + message, shouldCollectMessage);
if (proxyReturn.getOpMode() != AppOpsManager.MODE_ALLOWED) {
return new SyncNotedAppOp(proxyReturn.getOpMode(), code, proxiedAttributionTag,
proxiedPackageName);
@@ -3210,20 +3210,7 @@
return noteOperationUnchecked(code, proxiedUid, resolveProxiedPackageName,
proxiedAttributionTag, proxiedVirtualDeviceId, proxyUid, resolveProxyPackageName,
proxyAttributionTag, proxyVirtualDeviceId, proxiedFlags, shouldCollectAsyncNotedOp,
- message, shouldCollectMessage, 1);
- }
-
- @Override
- public void noteOperationsInBatch(Map batchedNoteOps) {
- for (var entry : ((Map<AppOpsManager.NotedOp, Integer>) batchedNoteOps).entrySet()) {
- AppOpsManager.NotedOp notedOp = entry.getKey();
- int notedCount = entry.getValue();
- mCheckOpsDelegateDispatcher.noteOperation(
- notedOp.getOp(), notedOp.getUid(), notedOp.getPackageName(),
- notedOp.getAttributionTag(), notedOp.getVirtualDeviceId(),
- notedOp.getShouldCollectAsyncNotedOp(), notedOp.getMessage(),
- notedOp.getShouldCollectMessage(), notedCount);
- }
+ message, shouldCollectMessage);
}
@Override
@@ -3241,7 +3228,7 @@
}
return mCheckOpsDelegateDispatcher.noteOperation(code, uid, packageName,
attributionTag, Context.DEVICE_ID_DEFAULT, shouldCollectAsyncNotedOp, message,
- shouldCollectMessage, 1);
+ shouldCollectMessage);
}
@Override
@@ -3250,12 +3237,13 @@
String message, boolean shouldCollectMessage) {
return mCheckOpsDelegateDispatcher.noteOperation(code, uid, packageName,
attributionTag, virtualDeviceId, shouldCollectAsyncNotedOp, message,
- shouldCollectMessage, 1);
+ shouldCollectMessage);
}
private SyncNotedAppOp noteOperationImpl(int code, int uid, @Nullable String packageName,
- @Nullable String attributionTag, int virtualDeviceId, boolean shouldCollectAsyncNotedOp,
- @Nullable String message, boolean shouldCollectMessage, int notedCount) {
+ @Nullable String attributionTag, int virtualDeviceId,
+ boolean shouldCollectAsyncNotedOp, @Nullable String message,
+ boolean shouldCollectMessage) {
String resolvedPackageName;
if (!shouldUseNewCheckOp()) {
verifyIncomingUid(uid);
@@ -3290,14 +3278,14 @@
return noteOperationUnchecked(code, uid, resolvedPackageName, attributionTag,
virtualDeviceId, Process.INVALID_UID, null, null,
Context.DEVICE_ID_DEFAULT, AppOpsManager.OP_FLAG_SELF, shouldCollectAsyncNotedOp,
- message, shouldCollectMessage, notedCount);
+ message, shouldCollectMessage);
}
private SyncNotedAppOp noteOperationUnchecked(int code, int uid, @NonNull String packageName,
@Nullable String attributionTag, int virtualDeviceId, int proxyUid,
String proxyPackageName, @Nullable String proxyAttributionTag, int proxyVirtualDeviceId,
@OpFlags int flags, boolean shouldCollectAsyncNotedOp, @Nullable String message,
- boolean shouldCollectMessage, int notedCount) {
+ boolean shouldCollectMessage) {
PackageVerificationResult pvr;
try {
pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName);
@@ -3400,11 +3388,11 @@
virtualDeviceId, flags, AppOpsManager.MODE_ALLOWED);
attributedOp.accessed(proxyUid, proxyPackageName, proxyAttributionTag,
- getPersistentId(proxyVirtualDeviceId), uidState.getState(), flags, notedCount);
+ getPersistentId(proxyVirtualDeviceId), uidState.getState(), flags);
if (shouldCollectAsyncNotedOp) {
collectAsyncNotedOp(uid, packageName, code, attributionTag, flags, message,
- shouldCollectMessage, notedCount);
+ shouldCollectMessage);
}
return new SyncNotedAppOp(AppOpsManager.MODE_ALLOWED, code, attributionTag,
@@ -3563,7 +3551,7 @@
*/
private void collectAsyncNotedOp(int uid, @NonNull String packageName, int opCode,
@Nullable String attributionTag, @OpFlags int flags, @NonNull String message,
- boolean shouldCollectMessage, int notedCount) {
+ boolean shouldCollectMessage) {
Objects.requireNonNull(message);
int callingUid = Binder.getCallingUid();
@@ -3571,51 +3559,42 @@
final long token = Binder.clearCallingIdentity();
try {
synchronized (this) {
+ Pair<String, Integer> key = getAsyncNotedOpsKey(packageName, uid);
+
+ RemoteCallbackList<IAppOpsAsyncNotedCallback> callbacks = mAsyncOpWatchers.get(key);
+ AsyncNotedAppOp asyncNotedOp = new AsyncNotedAppOp(opCode, callingUid,
+ attributionTag, message, System.currentTimeMillis());
+ final boolean[] wasNoteForwarded = {false};
+
if ((flags & (OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED)) != 0
&& shouldCollectMessage) {
reportRuntimeAppOpAccessMessageAsyncLocked(uid, packageName, opCode,
attributionTag, message);
}
- Pair<String, Integer> key = getAsyncNotedOpsKey(packageName, uid);
- RemoteCallbackList<IAppOpsAsyncNotedCallback> callbacks = mAsyncOpWatchers.get(key);
- if (callbacks == null) {
- return;
- }
-
- final boolean[] wasNoteForwarded = {false};
- if (Flags.rateLimitBatchedNoteOpAsyncCallbacksEnabled()) {
- notedCount = 1;
- }
-
- for (int i = 0; i < notedCount; i++) {
- AsyncNotedAppOp asyncNotedOp = new AsyncNotedAppOp(opCode, callingUid,
- attributionTag, message, System.currentTimeMillis());
- wasNoteForwarded[0] = false;
+ if (callbacks != null) {
callbacks.broadcast((cb) -> {
try {
cb.opNoted(asyncNotedOp);
wasNoteForwarded[0] = true;
} catch (RemoteException e) {
Slog.e(TAG,
- "Could not forward noteOp of " + opCode + " to "
- + packageName
+ "Could not forward noteOp of " + opCode + " to " + packageName
+ "/" + uid + "(" + attributionTag + ")", e);
}
});
+ }
- if (!wasNoteForwarded[0]) {
- ArrayList<AsyncNotedAppOp> unforwardedOps = mUnforwardedAsyncNotedOps.get(
- key);
- if (unforwardedOps == null) {
- unforwardedOps = new ArrayList<>(1);
- mUnforwardedAsyncNotedOps.put(key, unforwardedOps);
- }
+ if (!wasNoteForwarded[0]) {
+ ArrayList<AsyncNotedAppOp> unforwardedOps = mUnforwardedAsyncNotedOps.get(key);
+ if (unforwardedOps == null) {
+ unforwardedOps = new ArrayList<>(1);
+ mUnforwardedAsyncNotedOps.put(key, unforwardedOps);
+ }
- unforwardedOps.add(asyncNotedOp);
- if (unforwardedOps.size() > MAX_UNFORWARDED_OPS) {
- unforwardedOps.remove(0);
- }
+ unforwardedOps.add(asyncNotedOp);
+ if (unforwardedOps.size() > MAX_UNFORWARDED_OPS) {
+ unforwardedOps.remove(0);
}
}
}
@@ -4047,7 +4026,7 @@
if (shouldCollectAsyncNotedOp && !isRestricted) {
collectAsyncNotedOp(uid, packageName, code, attributionTag, AppOpsManager.OP_FLAG_SELF,
- message, shouldCollectMessage, 1);
+ message, shouldCollectMessage);
}
return new SyncNotedAppOp(isRestricted ? MODE_IGNORED : MODE_ALLOWED, code, attributionTag,
@@ -7595,36 +7574,34 @@
public SyncNotedAppOp noteOperation(int code, int uid, String packageName,
String attributionTag, int virtualDeviceId, boolean shouldCollectAsyncNotedOp,
- String message, boolean shouldCollectMessage, int notedCount) {
+ String message, boolean shouldCollectMessage) {
if (mPolicy != null) {
if (mCheckOpsDelegate != null) {
return mPolicy.noteOperation(code, uid, packageName, attributionTag,
virtualDeviceId, shouldCollectAsyncNotedOp, message,
- shouldCollectMessage, notedCount, this::noteDelegateOperationImpl
+ shouldCollectMessage, this::noteDelegateOperationImpl
);
} else {
return mPolicy.noteOperation(code, uid, packageName, attributionTag,
virtualDeviceId, shouldCollectAsyncNotedOp, message,
- shouldCollectMessage, notedCount, AppOpsService.this::noteOperationImpl
+ shouldCollectMessage, AppOpsService.this::noteOperationImpl
);
}
} else if (mCheckOpsDelegate != null) {
return noteDelegateOperationImpl(code, uid, packageName, attributionTag,
- virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
- notedCount);
+ virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
return noteOperationImpl(code, uid, packageName, attributionTag,
- virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
- notedCount);
+ virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
private SyncNotedAppOp noteDelegateOperationImpl(int code, int uid,
@Nullable String packageName, @Nullable String featureId, int virtualDeviceId,
boolean shouldCollectAsyncNotedOp, @Nullable String message,
- boolean shouldCollectMessage, int notedCount) {
+ boolean shouldCollectMessage) {
return mCheckOpsDelegate.noteOperation(code, uid, packageName, featureId,
virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
- notedCount, AppOpsService.this::noteOperationImpl
+ AppOpsService.this::noteOperationImpl
);
}
diff --git a/services/core/java/com/android/server/appop/AttributedOp.java b/services/core/java/com/android/server/appop/AttributedOp.java
index 4d114b4..314664b 100644
--- a/services/core/java/com/android/server/appop/AttributedOp.java
+++ b/services/core/java/com/android/server/appop/AttributedOp.java
@@ -100,12 +100,10 @@
* @param proxyDeviceId The device Id of the proxy
* @param uidState UID state of the app noteOp/startOp was called for
* @param flags OpFlags of the call
- * @param accessCount The number of times the op is accessed
*/
public void accessed(int proxyUid, @Nullable String proxyPackageName,
@Nullable String proxyAttributionTag, @Nullable String proxyDeviceId,
- @AppOpsManager.UidState int uidState, @AppOpsManager.OpFlags int flags,
- int accessCount) {
+ @AppOpsManager.UidState int uidState, @AppOpsManager.OpFlags int flags) {
long accessTime = System.currentTimeMillis();
accessed(accessTime, -1, proxyUid, proxyPackageName, proxyAttributionTag, proxyDeviceId,
uidState, flags);
@@ -113,7 +111,7 @@
mAppOpsService.mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
parent.packageName, persistentDeviceId, tag, uidState, flags, accessTime,
AppOpsManager.ATTRIBUTION_FLAGS_NONE, AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE,
- DiscreteRegistry.ACCESS_TYPE_NOTE_OP, accessCount);
+ DiscreteRegistry.ACCESS_TYPE_NOTE_OP);
}
/**
@@ -257,7 +255,7 @@
if (isStarted) {
mAppOpsService.mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
parent.packageName, persistentDeviceId, tag, uidState, flags, startTime,
- attributionFlags, attributionChainId, DiscreteRegistry.ACCESS_TYPE_START_OP, 1);
+ attributionFlags, attributionChainId, DiscreteRegistry.ACCESS_TYPE_START_OP);
}
}
@@ -453,7 +451,7 @@
mAppOpsService.mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
parent.packageName, persistentDeviceId, tag, event.getUidState(),
event.getFlags(), startTime, event.getAttributionFlags(),
- event.getAttributionChainId(), DiscreteRegistry.ACCESS_TYPE_RESUME_OP, 1);
+ event.getAttributionChainId(), DiscreteRegistry.ACCESS_TYPE_RESUME_OP);
if (shouldSendActive) {
mAppOpsService.scheduleOpActiveChangedIfNeededLocked(parent.op, parent.uid,
parent.packageName, tag, event.getVirtualDeviceId(), true,
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 5e67f26..6b02538 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -475,7 +475,7 @@
@NonNull String deviceId, @Nullable String attributionTag, @UidState int uidState,
@OpFlags int flags, long accessTime,
@AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId,
- @DiscreteRegistry.AccessType int accessType, int accessCount) {
+ @DiscreteRegistry.AccessType int accessType) {
synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
if (!isPersistenceInitializedMLocked()) {
@@ -484,7 +484,7 @@
}
getUpdatedPendingHistoricalOpsMLocked(
System.currentTimeMillis()).increaseAccessCount(op, uid, packageName,
- attributionTag, uidState, flags, accessCount);
+ attributionTag, uidState, flags, 1);
mDiscreteRegistry.recordDiscreteAccess(uid, packageName, deviceId, op,
attributionTag, flags, uidState, accessTime, -1, attributionFlags,
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 34d4fb0..acb46d9 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -793,6 +793,7 @@
* (see AudioService.onAudioServerDied() method)
*/
// Always executed on AudioDeviceBroker message queue
+ @GuardedBy("mDeviceBroker.mDeviceStateLock")
/*package*/ void onRestoreDevices() {
synchronized (mDevicesLock) {
int res;
@@ -815,6 +816,9 @@
"Device inventory restore failed to reconnect " + di,
EventLogger.Event.ALOGE, TAG);
mConnectedDevices.remove(di.getKey(), di);
+ if (AudioSystem.isBluetoothScoDevice(di.mDeviceType)) {
+ mDeviceBroker.onSetBtScoActiveDevice(null);
+ }
}
}
mAppliedStrategyRolesInt.clear();
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 5928f81..09b8e21 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4684,6 +4684,12 @@
switch (mode) {
case AudioSystem.MODE_IN_COMMUNICATION:
case AudioSystem.MODE_IN_CALL:
+ // TODO(b/382704431): remove to allow STREAM_VOICE_CALL to drive abs volume
+ // over A2DP
+ if (getDeviceForStream(AudioSystem.STREAM_VOICE_CALL)
+ == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
+ return AudioSystem.STREAM_MUSIC;
+ }
return AudioSystem.STREAM_VOICE_CALL;
case AudioSystem.MODE_CALL_SCREENING:
case AudioSystem.MODE_COMMUNICATION_REDIRECT:
@@ -4695,15 +4701,20 @@
// other conditions will influence the stream type choice, read on...
break;
}
- if (voiceActivityCanOverride
- && mVoicePlaybackActive.get()) {
+
+ if (voiceActivityCanOverride && mVoicePlaybackActive.get()) {
+ // TODO(b/382704431): remove to allow STREAM_VOICE_CALL to drive abs volume over A2DP
+ if (getDeviceForStream(AudioSystem.STREAM_VOICE_CALL)
+ == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
+ return AudioSystem.STREAM_MUSIC;
+ }
return AudioSystem.STREAM_VOICE_CALL;
}
return AudioSystem.STREAM_MUSIC;
}
- private AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false);
- private AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false);
+ private final AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false);
+ private final AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false);
private final IPlaybackConfigDispatcher mPlaybackActivityMonitor =
new IPlaybackConfigDispatcher.Stub() {
@@ -4923,7 +4934,7 @@
private void onUpdateContextualVolumes() {
final int streamType = getBluetoothContextualVolumeStream();
- Log.i(TAG,
+ Slog.i(TAG,
"onUpdateContextualVolumes: absolute volume driving streams " + streamType
+ " avrcp supported: " + mAvrcpAbsVolSupported);
synchronized (mCachedAbsVolDrivingStreamsLock) {
@@ -4932,7 +4943,7 @@
if (absDev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
enabled = mAvrcpAbsVolSupported;
if (!enabled) {
- Log.w(TAG, "Updating avrcp not supported in onUpdateContextualVolumes");
+ Slog.w(TAG, "Updating avrcp not supported in onUpdateContextualVolumes");
}
}
if (stream != streamType) {
@@ -4960,7 +4971,7 @@
return;
}
if (absVolumeDevices.size() > 1) {
- Log.w(TAG, "onUpdateContextualVolumes too many active devices: "
+ Slog.w(TAG, "onUpdateContextualVolumes too many active devices: "
+ absVolumeDevices.stream().map(AudioSystem::getOutputDeviceName)
.collect(Collectors.joining(","))
+ ", for stream: " + streamType);
@@ -4971,7 +4982,7 @@
final int index = getStreamVolume(streamType, device);
if (DEBUG_VOL) {
- Log.i(TAG, "onUpdateContextualVolumes streamType: " + streamType
+ Slog.i(TAG, "onUpdateContextualVolumes streamType: " + streamType
+ ", device: " + AudioSystem.getOutputDeviceName(device)
+ ", index: " + index);
}
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index 2513443..5d9db65 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -19,17 +19,19 @@
import static android.Manifest.permission.CONTROL_DEVICE_STATE;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED;
-import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN;
-import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FEATURE_DUAL_DISPLAY;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FEATURE_REAR_DISPLAY;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY;
import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
+import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED;
+import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN;
+import static android.frameworks.devicestate.DeviceStateConfiguration.DeviceStatePropertyValue.FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN;
import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT;
import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT;
import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY;
import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED;
import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST;
import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS;
import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP;
@@ -98,7 +100,6 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.WeakHashMap;
@@ -854,7 +855,7 @@
}
}
- private void requestStateInternal(int state, int flags, int callingPid, int callingUid,
+ private void requestStateInternal(int requestedState, int flags, int callingPid, int callingUid,
@NonNull IBinder token, boolean hasControlDeviceStatePermission) {
synchronized (mLock) {
final ProcessRecord processRecord = mProcessRecords.get(callingPid);
@@ -869,19 +870,30 @@
+ " token: " + token);
}
- final Optional<DeviceState> deviceState = getStateLocked(state);
- if (!deviceState.isPresent()) {
- throw new IllegalArgumentException("Requested state: " + state
+ final Optional<DeviceState> requestedDeviceState = getStateLocked(requestedState);
+ if (requestedDeviceState.isEmpty()) {
+ throw new IllegalArgumentException("Requested state: " + requestedState
+ " is not supported.");
}
- OverrideRequest request = new OverrideRequest(token, callingPid, callingUid,
- deviceState.get(), flags, OVERRIDE_REQUEST_TYPE_EMULATED_STATE);
+ final OverrideRequest request = new OverrideRequest(token, callingPid, callingUid,
+ requestedDeviceState.get(), flags, OVERRIDE_REQUEST_TYPE_EMULATED_STATE);
if (Flags.deviceStatePropertyMigration()) {
- // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
- if (!hasControlDeviceStatePermission && deviceState.get().hasProperty(
- PROPERTY_FEATURE_REAR_DISPLAY)) {
+ final boolean isRequestingRdm = requestedDeviceState.get()
+ .hasProperty(PROPERTY_FEATURE_REAR_DISPLAY);
+ final boolean isRequestingRdmOuterDefault = requestedDeviceState.get()
+ .hasProperty(PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT);
+
+ final boolean isDeviceClosed = mCommittedState.isEmpty() ? false
+ : mCommittedState.get().hasProperty(
+ PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED);
+
+ final boolean shouldShowRdmEduDialog = isRequestingRdm && shouldShowRdmEduDialog(
+ hasControlDeviceStatePermission, isRequestingRdmOuterDefault,
+ isDeviceClosed);
+
+ if (shouldShowRdmEduDialog) {
showRearDisplayEducationalOverlayLocked(request);
} else {
mOverrideRequestController.addRequest(request);
@@ -889,7 +901,7 @@
} else {
// If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
if (!hasControlDeviceStatePermission && mRearDisplayState != null
- && state == mRearDisplayState.getIdentifier()) {
+ && requestedState == mRearDisplayState.getIdentifier()) {
showRearDisplayEducationalOverlayLocked(request);
} else {
mOverrideRequestController.addRequest(request);
@@ -899,6 +911,28 @@
}
/**
+ * Determines if the system should show an educational dialog before entering rear display mode
+ * @param hasControlDeviceStatePermission If the app has the CONTROL_DEVICE_STATE permission, we
+ * don't need to show the overlay
+ * @param requestingRdmOuterDefault True if the system is requesting
+ * PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT
+ * @param isDeviceClosed True if the device is closed (folded) when the request was made
+ */
+ @VisibleForTesting
+ static boolean shouldShowRdmEduDialog(boolean hasControlDeviceStatePermission,
+ boolean requestingRdmOuterDefault, boolean isDeviceClosed) {
+ if (hasControlDeviceStatePermission) {
+ return false;
+ }
+
+ if (requestingRdmOuterDefault) {
+ return isDeviceClosed;
+ } else {
+ return true;
+ }
+ }
+
+ /**
* If we get a request to enter rear display mode, we need to display an educational
* overlay to let the user know what will happen. This calls into the
* {@link StatusBarManagerInternal} to notify SystemUI to display the educational dialog.
diff --git a/services/core/java/com/android/server/display/plugin/PluginEventStorage.java b/services/core/java/com/android/server/display/plugin/PluginEventStorage.java
new file mode 100644
index 0000000..c58ba55
--- /dev/null
+++ b/services/core/java/com/android/server/display/plugin/PluginEventStorage.java
@@ -0,0 +1,134 @@
+/*
+ * 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.display.plugin;
+
+import android.util.IndentingPrintWriter;
+
+import com.android.internal.util.RingBuffer;
+
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+class PluginEventStorage {
+ private static final long TIME_FRAME_LENGTH = 60_000;
+ private static final long MIN_EVENT_DELAY = 500;
+ private static final int MAX_TIME_FRAMES = 10;
+ // not thread safe
+ private static final SimpleDateFormat sDateFormat = new SimpleDateFormat(
+ "MM-dd HH:mm:ss.SSS", Locale.US);
+
+ RingBuffer<TimeFrame> mEvents = new RingBuffer<>(
+ TimeFrame::new, TimeFrame[]::new, MAX_TIME_FRAMES);
+
+ private final Map<PluginType<?>, Long> mEventTimes = new HashMap<>();
+ private long mTimeFrameStart = 0;
+ private final Map<PluginType<?>, EventCounter> mCounters = new HashMap<>();
+
+ <T> void onValueUpdated(PluginType<T> type) {
+ long eventTime = System.currentTimeMillis();
+ if (eventTime - TIME_FRAME_LENGTH > mTimeFrameStart) { // event is in next TimeFrame
+ closeCurrentTimeFrame();
+ mTimeFrameStart = eventTime;
+ }
+ updateCurrentTimeFrame(type, eventTime);
+ }
+
+ private void closeCurrentTimeFrame() {
+ if (!mCounters.isEmpty()) {
+ mEvents.append(new TimeFrame(
+ mTimeFrameStart, mTimeFrameStart + TIME_FRAME_LENGTH, mCounters));
+ mCounters.clear();
+ }
+ }
+
+ private <T> void updateCurrentTimeFrame(PluginType<T> type, long eventTime) {
+ EventCounter counter = mCounters.get(type);
+ long previousTimestamp = mEventTimes.getOrDefault(type, 0L);
+ if (counter == null) {
+ counter = new EventCounter();
+ mCounters.put(type, counter);
+ }
+ counter.increase(eventTime, previousTimestamp);
+ mEventTimes.put(type, eventTime);
+ }
+
+ List<TimeFrame> getTimeFrames() {
+ List<TimeFrame> timeFrames = new ArrayList<>(Arrays.stream(mEvents.toArray()).toList());
+ timeFrames.add(new TimeFrame(
+ mTimeFrameStart, System.currentTimeMillis(), mCounters));
+ return timeFrames;
+ }
+
+ static class TimeFrame {
+ private final long mStart;
+ private final long mEnd;
+ private final Map<PluginType<?>, EventCounter> mCounters;
+
+ private TimeFrame() {
+ this(0, 0, Map.of());
+ }
+
+ private TimeFrame(long start, long end, Map<PluginType<?>, EventCounter> counters) {
+ mStart = start;
+ mEnd = end;
+ mCounters = new HashMap<>(counters);
+ }
+
+ @SuppressWarnings("JavaUtilDate")
+ void dump(PrintWriter pw) {
+ pw.append("TimeFrame:[")
+ .append(sDateFormat.format(new Date(mStart)))
+ .append(" - ")
+ .append(sDateFormat.format(new Date(mEnd)))
+ .println("]:");
+ IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ if (mCounters.isEmpty()) {
+ ipw.println("NO EVENTS");
+ } else {
+ for (Map.Entry<PluginType<?>, EventCounter> entry: mCounters.entrySet()) {
+ ipw.append(entry.getKey().mName).append(" -> {");
+ entry.getValue().dump(ipw);
+ ipw.println("}");
+ }
+ }
+ }
+ }
+
+ private static class EventCounter {
+ private int mEventCounter = 0;
+ private int mFastEventCounter = 0;
+
+ private void increase(long timestamp, long previousTimestamp) {
+ mEventCounter++;
+ if (timestamp - previousTimestamp < MIN_EVENT_DELAY) {
+ mFastEventCounter++;
+ }
+ }
+
+ private void dump(PrintWriter pw) {
+ pw.append("Count:").append(String.valueOf(mEventCounter))
+ .append("; Fast:").append(String.valueOf(mFastEventCounter));
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/display/plugin/PluginStorage.java b/services/core/java/com/android/server/display/plugin/PluginStorage.java
index 2bcea77..dd3415f 100644
--- a/services/core/java/com/android/server/display/plugin/PluginStorage.java
+++ b/services/core/java/com/android/server/display/plugin/PluginStorage.java
@@ -25,6 +25,7 @@
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -39,6 +40,8 @@
private final Map<PluginType<?>, Object> mValues = new HashMap<>();
@GuardedBy("mLock")
private final Map<PluginType<?>, ListenersContainer<?>> mListeners = new HashMap<>();
+ @GuardedBy("mLock")
+ private final PluginEventStorage mPluginEventStorage = new PluginEventStorage();
/**
* Updates value in storage and forwards it to corresponding listeners.
@@ -50,6 +53,7 @@
Set<PluginManager.PluginChangeListener<T>> localListeners;
synchronized (mLock) {
mValues.put(type, value);
+ mPluginEventStorage.onValueUpdated(type);
ListenersContainer<T> container = getListenersContainerForTypeLocked(type);
localListeners = new LinkedHashSet<>(container.mListeners);
}
@@ -91,13 +95,19 @@
Map<PluginType<?>, Object> localValues;
@SuppressWarnings("rawtypes")
Map<PluginType, Set> localListeners = new HashMap<>();
+ List<PluginEventStorage.TimeFrame> timeFrames;
synchronized (mLock) {
+ timeFrames = mPluginEventStorage.getTimeFrames();
localValues = new HashMap<>(mValues);
mListeners.forEach((type, container) -> localListeners.put(type, container.mListeners));
}
pw.println("PluginStorage:");
pw.println("values=" + localValues);
pw.println("listeners=" + localListeners);
+ pw.println("PluginEventStorage:");
+ for (PluginEventStorage.TimeFrame timeFrame: timeFrames) {
+ timeFrame.dump(pw);
+ }
}
@GuardedBy("mLock")
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
index 4a533f4..ef73463 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
@@ -186,7 +186,9 @@
/** Invoked when the underlying binder of this broker has died at the client process. */
@Override
public void binderDied() {
- unregister();
+ if (mIsRegistered.get()) {
+ unregister();
+ }
}
/* package */ void attachDeathRecipient() throws RemoteException {
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
index 8c5095f3..155a92a 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
@@ -65,8 +65,12 @@
/** Variables for managing endpoint ID creation */
private final Object mEndpointLock = new Object();
+ /**
+ * The next available endpoint ID to register. Per EndpointId.aidl definition, dynamic
+ * endpoint IDs must have the left-most bit as 1, and the values 0/-1 are invalid.
+ */
@GuardedBy("mEndpointLock")
- private long mNextEndpointId = 0;
+ private long mNextEndpointId = -2;
/** The minimum session ID reservable by endpoints (retrieved from HAL) */
private final int mMinSessionId;
@@ -282,10 +286,10 @@
/** @return an available endpoint ID */
private long getNewEndpointId() {
synchronized (mEndpointLock) {
- if (mNextEndpointId == Long.MAX_VALUE) {
+ if (mNextEndpointId >= 0) {
throw new IllegalStateException("Too many endpoints connected");
}
- return mNextEndpointId++;
+ return mNextEndpointId--;
}
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java b/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java
index 8e72553..9d52c6a 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubHalEndpointCallback.java
@@ -68,7 +68,7 @@
}
HubEndpointInfo[] endpointInfos = new HubEndpointInfo[halEndpointInfos.length];
for (int i = 0; i < halEndpointInfos.length; i++) {
- endpointInfos[i++] = new HubEndpointInfo(halEndpointInfos[i]);
+ endpointInfos[i] = new HubEndpointInfo(halEndpointInfos[i]);
}
mEndpointLifecycleCallback.onEndpointStarted(endpointInfos);
}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index 0b47a61..d916eda 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -798,7 +798,7 @@
throws RemoteException {
super.registerEndpoint_enforcePermission();
if (mEndpointManager == null) {
- Log.e(TAG, "ContextHubService.registerEndpoint: endpoint manager failed to initialize");
+ Log.e(TAG, "Endpoint manager failed to initialize");
throw new UnsupportedOperationException("Endpoint registration is not supported");
}
return mEndpointManager.registerEndpoint(pendingHubEndpointInfo, callback);
@@ -809,7 +809,8 @@
public void registerEndpointDiscoveryCallbackId(
long endpointId, IContextHubEndpointDiscoveryCallback callback) throws RemoteException {
super.registerEndpointDiscoveryCallbackId_enforcePermission();
- // TODO(b/375487784): Implement this
+ checkEndpointDiscoveryPreconditions();
+ mHubInfoRegistry.registerEndpointDiscoveryCallback(endpointId, callback);
}
@android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@@ -818,7 +819,8 @@
String serviceDescriptor, IContextHubEndpointDiscoveryCallback callback)
throws RemoteException {
super.registerEndpointDiscoveryCallbackDescriptor_enforcePermission();
- // TODO(b/375487784): Implement this
+ checkEndpointDiscoveryPreconditions();
+ mHubInfoRegistry.registerEndpointDiscoveryCallback(serviceDescriptor, callback);
}
@android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@@ -826,7 +828,15 @@
public void unregisterEndpointDiscoveryCallback(IContextHubEndpointDiscoveryCallback callback)
throws RemoteException {
super.unregisterEndpointDiscoveryCallback_enforcePermission();
- // TODO(b/375487784): Implement this
+ checkEndpointDiscoveryPreconditions();
+ mHubInfoRegistry.unregisterEndpointDiscoveryCallback(callback);
+ }
+
+ private void checkEndpointDiscoveryPreconditions() {
+ if (mHubInfoRegistry == null) {
+ Log.e(TAG, "Hub endpoint registry failed to initialize");
+ throw new UnsupportedOperationException("Endpoint discovery is not supported");
+ }
}
/**
diff --git a/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java b/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java
index b912492..6f5f191 100644
--- a/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java
+++ b/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java
@@ -18,7 +18,9 @@
import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.HubServiceInfo;
+import android.hardware.contexthub.IContextHubEndpointDiscoveryCallback;
import android.hardware.location.HubInfo;
+import android.os.DeadObjectException;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
@@ -29,6 +31,9 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.BiConsumer;
class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycleCallback {
private static final String TAG = "HubInfoRegistry";
@@ -43,6 +48,56 @@
private final ArrayMap<HubEndpointInfo.HubEndpointIdentifier, HubEndpointInfo>
mHubEndpointInfos = new ArrayMap<>();
+ /**
+ * A wrapper class that is used to store arguments to
+ * ContextHubManager.registerEndpointCallback.
+ */
+ private static class DiscoveryCallback {
+ private final IContextHubEndpointDiscoveryCallback mCallback;
+ private final Optional<Long> mEndpointId;
+ private final Optional<String> mServiceDescriptor;
+
+ DiscoveryCallback(IContextHubEndpointDiscoveryCallback callback, long endpointId) {
+ mCallback = callback;
+ mEndpointId = Optional.of(endpointId);
+ mServiceDescriptor = Optional.empty();
+ }
+
+ DiscoveryCallback(IContextHubEndpointDiscoveryCallback callback, String serviceDescriptor) {
+ mCallback = callback;
+ mEndpointId = Optional.empty();
+ mServiceDescriptor = Optional.of(serviceDescriptor);
+ }
+
+ public IContextHubEndpointDiscoveryCallback getCallback() {
+ return mCallback;
+ }
+
+ /**
+ * @param info The hub endpoint info to check
+ * @return true if info matches
+ */
+ public boolean isMatch(HubEndpointInfo info) {
+ if (mEndpointId.isPresent()) {
+ return mEndpointId.get() == info.getIdentifier().getEndpoint();
+ }
+ if (mServiceDescriptor.isPresent()) {
+ for (HubServiceInfo serviceInfo : info.getServiceInfoCollection()) {
+ if (mServiceDescriptor.get().equals(serviceInfo.getServiceDescriptor())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ /* The list of discovery callbacks registered with the service */
+ @GuardedBy("mCallbackLock")
+ private final List<DiscoveryCallback> mEndpointDiscoveryCallbacks = new ArrayList<>();
+
+ private final Object mCallbackLock = new Object();
+
HubInfoRegistry(IContextHubWrapper contextHubWrapper) {
mContextHubWrapper = contextHubWrapper;
refreshCachedHubs();
@@ -109,16 +164,50 @@
mHubEndpointInfos.put(endpointInfo.getIdentifier(), endpointInfo);
}
}
+
+ invokeForMatchingEndpoints(
+ endpointInfos,
+ (cb, infoList) -> {
+ try {
+ cb.onEndpointsStarted(infoList);
+ } catch (RemoteException e) {
+ if (e instanceof DeadObjectException) {
+ Log.w(TAG, "onEndpointStarted: callback died, unregistering");
+ unregisterEndpointDiscoveryCallback(cb);
+ } else {
+ Log.e(TAG, "Exception while calling onEndpointsStarted", e);
+ }
+ }
+ });
}
@Override
public void onEndpointStopped(
HubEndpointInfo.HubEndpointIdentifier[] endpointIds, byte reason) {
+ ArrayList<HubEndpointInfo> removedInfoList = new ArrayList<>();
synchronized (mLock) {
for (HubEndpointInfo.HubEndpointIdentifier endpointId : endpointIds) {
- mHubEndpointInfos.remove(endpointId);
+ HubEndpointInfo info = mHubEndpointInfos.remove(endpointId);
+ if (info != null) {
+ removedInfoList.add(info);
+ }
}
}
+
+ invokeForMatchingEndpoints(
+ removedInfoList.toArray(new HubEndpointInfo[removedInfoList.size()]),
+ (cb, infoList) -> {
+ try {
+ cb.onEndpointsStopped(infoList, reason);
+ } catch (RemoteException e) {
+ if (e instanceof DeadObjectException) {
+ Log.w(TAG, "onEndpointStopped: callback died, unregistering");
+ unregisterEndpointDiscoveryCallback(cb);
+ } else {
+ Log.e(TAG, "Exception while calling onEndpointsStopped", e);
+ }
+ }
+ });
}
/** Return a list of {@link HubEndpointInfo} that represents endpoints with the matching id. */
@@ -151,6 +240,77 @@
return searchResult;
}
+ /* package */
+ void registerEndpointDiscoveryCallback(
+ long endpointId, IContextHubEndpointDiscoveryCallback callback) {
+ Objects.requireNonNull(callback, "callback cannot be null");
+ synchronized (mCallbackLock) {
+ checkCallbackAlreadyRegistered(callback);
+ mEndpointDiscoveryCallbacks.add(new DiscoveryCallback(callback, endpointId));
+ }
+ }
+
+ /* package */
+ void registerEndpointDiscoveryCallback(
+ String serviceDescriptor, IContextHubEndpointDiscoveryCallback callback) {
+ Objects.requireNonNull(callback, "callback cannot be null");
+ synchronized (mCallbackLock) {
+ checkCallbackAlreadyRegistered(callback);
+ mEndpointDiscoveryCallbacks.add(new DiscoveryCallback(callback, serviceDescriptor));
+ }
+ }
+
+ /* package */
+ void unregisterEndpointDiscoveryCallback(IContextHubEndpointDiscoveryCallback callback) {
+ Objects.requireNonNull(callback, "callback cannot be null");
+ synchronized (mCallbackLock) {
+ for (DiscoveryCallback discoveryCallback : mEndpointDiscoveryCallbacks) {
+ if (discoveryCallback.getCallback().asBinder() == callback.asBinder()) {
+ mEndpointDiscoveryCallbacks.remove(discoveryCallback);
+ break;
+ }
+ }
+ }
+ }
+
+ private void checkCallbackAlreadyRegistered(
+ IContextHubEndpointDiscoveryCallback callback) {
+ synchronized (mCallbackLock) {
+ for (DiscoveryCallback discoveryCallback : mEndpointDiscoveryCallbacks) {
+ if (discoveryCallback.mCallback.asBinder() == callback.asBinder()) {
+ throw new IllegalArgumentException("Callback is already registered");
+ }
+ }
+ }
+ }
+
+ /**
+ * Iterates through all registered discovery callbacks and invokes a given callback for those
+ * that match the endpoints the callback is targeted for.
+ *
+ * @param endpointInfos The list of endpoint infos to check for a match.
+ * @param consumer The callback to invoke, which consumes the callback object and the list of
+ * matched endpoint infos.
+ */
+ private void invokeForMatchingEndpoints(
+ HubEndpointInfo[] endpointInfos,
+ BiConsumer<IContextHubEndpointDiscoveryCallback, HubEndpointInfo[]> consumer) {
+ synchronized (mCallbackLock) {
+ for (DiscoveryCallback discoveryCallback : mEndpointDiscoveryCallbacks) {
+ ArrayList<HubEndpointInfo> infoList = new ArrayList<>();
+ for (HubEndpointInfo endpointInfo : endpointInfos) {
+ if (discoveryCallback.isMatch(endpointInfo)) {
+ infoList.add(endpointInfo);
+ }
+ }
+
+ consumer.accept(
+ discoveryCallback.getCallback(),
+ infoList.toArray(new HubEndpointInfo[infoList.size()]));
+ }
+ }
+ }
+
void dump(IndentingPrintWriter ipw) {
synchronized (mLock) {
dumpLocked(ipw);
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
index db1e6b4..5ee9452 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
@@ -66,6 +66,7 @@
private final int mUserId;
private final Handler mHandler;
private final boolean mIsSelfScanOnlyProvider;
+ private final boolean mSupportsSystemMediaRouting;
private final ServiceConnection mServiceConnection = new ServiceConnectionImpl();
// Connection state
@@ -95,12 +96,14 @@
@NonNull Looper looper,
@NonNull ComponentName componentName,
boolean isSelfScanOnlyProvider,
+ boolean supportsSystemMediaRouting,
int userId) {
super(componentName, /* isSystemRouteProvider= */ false);
mContext = Objects.requireNonNull(context, "Context must not be null.");
mRequestIdToSessionCreationRequest = new LongSparseArray<>();
mSessionOriginalIdToTransferRequest = new HashMap<>();
mIsSelfScanOnlyProvider = isSelfScanOnlyProvider;
+ mSupportsSystemMediaRouting = supportsSystemMediaRouting;
mUserId = userId;
mHandler = new Handler(looper);
}
@@ -651,11 +654,12 @@
}
return TextUtils.formatSimple(
"ProviderServiceProxy - package: %s, bound: %b, connection (active:%b, ready:%b), "
- + "pending (session creations: %d, transfers: %d)",
+ + "system media=%b, pending (session creations: %d, transfers: %d)",
mComponentName.getPackageName(),
mBound,
mActiveConnection != null,
mConnectionReady,
+ mSupportsSystemMediaRouting,
pendingSessionCreationCount,
pendingTransferCount);
}
@@ -697,7 +701,7 @@
Connection(IMediaRoute2ProviderService serviceBinder) {
mService = serviceBinder;
- mCallbackStub = new ServiceCallbackStub(this);
+ mCallbackStub = new ServiceCallbackStub(this, mSupportsSystemMediaRouting);
}
public boolean register() {
@@ -811,9 +815,11 @@
private static final class ServiceCallbackStub extends
IMediaRoute2ProviderServiceCallback.Stub {
private final WeakReference<Connection> mConnectionRef;
+ private final boolean mAllowSystemMediaRoutes;
- ServiceCallbackStub(Connection connection) {
+ ServiceCallbackStub(Connection connection, boolean allowSystemMediaRoutes) {
mConnectionRef = new WeakReference<>(connection);
+ mAllowSystemMediaRoutes = allowSystemMediaRoutes;
}
public void dispose() {
@@ -846,6 +852,13 @@
+ "Disallowed route: "
+ route);
}
+
+ if (route.supportsSystemMediaRouting() && !mAllowSystemMediaRoutes) {
+ throw new SecurityException(
+ "This provider is not allowed to publish routes that support system"
+ + " media routing. Disallowed route: "
+ + route);
+ }
}
Connection connection = mConnectionRef.get();
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
index 93ef6f0..69c460e 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
@@ -17,7 +17,9 @@
package com.android.server.media;
import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import android.Manifest;
import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -130,22 +132,33 @@
ServiceInfo serviceInfo = resolveInfo.serviceInfo;
if (serviceInfo != null) {
boolean isSelfScanOnlyProvider = false;
+ boolean supportsSystemMediaRouting = false;
Iterator<String> categoriesIterator = resolveInfo.filter.categoriesIterator();
if (categoriesIterator != null) {
while (categoriesIterator.hasNext()) {
+ String category = categoriesIterator.next();
isSelfScanOnlyProvider |=
- MediaRoute2ProviderService.CATEGORY_SELF_SCAN_ONLY.equals(
- categoriesIterator.next());
+ MediaRoute2ProviderService.CATEGORY_SELF_SCAN_ONLY.equals(category);
+ supportsSystemMediaRouting |=
+ MediaRoute2ProviderService.SERVICE_INTERFACE_SYSTEM_MEDIA.equals(
+ category);
}
}
int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name);
if (sourceIndex < 0) {
+ supportsSystemMediaRouting &= Flags.enableMirroringInMediaRouter2();
+ supportsSystemMediaRouting &=
+ mPackageManager.checkPermission(
+ Manifest.permission.MODIFY_AUDIO_ROUTING,
+ serviceInfo.packageName)
+ == PERMISSION_GRANTED;
MediaRoute2ProviderServiceProxy proxy =
new MediaRoute2ProviderServiceProxy(
mContext,
mHandler.getLooper(),
new ComponentName(serviceInfo.packageName, serviceInfo.name),
isSelfScanOnlyProvider,
+ supportsSystemMediaRouting,
mUserId);
Slog.i(
TAG,
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 849751b..1673b8e 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityService.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java
@@ -32,6 +32,7 @@
import android.media.quality.SoundProfile;
import android.media.quality.SoundProfileHandle;
import android.os.PersistableBundle;
+import android.os.UserHandle;
import android.util.Log;
import com.android.server.SystemService;
@@ -81,7 +82,7 @@
private final class BinderService extends IMediaQualityManager.Stub {
@Override
- public PictureProfile createPictureProfile(PictureProfile pp, int userId) {
+ public PictureProfile createPictureProfile(PictureProfile pp, UserHandle user) {
SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
@@ -100,12 +101,12 @@
}
@Override
- public void updatePictureProfile(String id, PictureProfile pp, int userId) {
+ public void updatePictureProfile(String id, PictureProfile pp, UserHandle user) {
// TODO: implement
}
@Override
- public void removePictureProfile(String id, int userId) {
+ public void removePictureProfile(String id, UserHandle user) {
Long intId = mPictureProfileTempIdMap.inverse().get(id);
if (intId != null) {
SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
@@ -118,7 +119,8 @@
}
@Override
- public PictureProfile getPictureProfile(int type, String name, int userId) {
+ public PictureProfile getPictureProfile(int type, String name, boolean includeParams,
+ UserHandle user) {
String selection = BaseParameters.PARAMETER_TYPE + " = ? AND "
+ BaseParameters.PARAMETER_NAME + " = ?";
String[] selectionArguments = {Integer.toString(type), name};
@@ -144,7 +146,8 @@
}
@Override
- public List<PictureProfile> getPictureProfilesByPackage(String packageName, int userId) {
+ public List<PictureProfile> getPictureProfilesByPackage(
+ String packageName, boolean includeParams, UserHandle user) {
String selection = BaseParameters.PARAMETER_PACKAGE + " = ?";
String[] selectionArguments = {packageName};
return getPictureProfilesBasedOnConditions(getAllMediaProfileColumns(), selection,
@@ -152,18 +155,19 @@
}
@Override
- public List<PictureProfile> getAvailablePictureProfiles(int userId) {
+ public List<PictureProfile> getAvailablePictureProfiles(
+ boolean includeParams, UserHandle user) {
return new ArrayList<>();
}
@Override
- public boolean setDefaultPictureProfile(String profileId, int userId) {
+ public boolean setDefaultPictureProfile(String profileId, UserHandle user) {
// TODO: pass the profile ID to MediaQuality HAL when ready.
return false;
}
@Override
- public List<String> getPictureProfilePackageNames(int userId) {
+ public List<String> getPictureProfilePackageNames(UserHandle user) {
String [] column = {BaseParameters.PARAMETER_PACKAGE};
List<PictureProfile> pictureProfiles = getPictureProfilesBasedOnConditions(column,
null, null);
@@ -174,17 +178,17 @@
}
@Override
- public List<PictureProfileHandle> getPictureProfileHandle(String[] id, int userId) {
+ public List<PictureProfileHandle> getPictureProfileHandle(String[] id, UserHandle user) {
return new ArrayList<>();
}
@Override
- public List<SoundProfileHandle> getSoundProfileHandle(String[] id, int userId) {
+ public List<SoundProfileHandle> getSoundProfileHandle(String[] id, UserHandle user) {
return new ArrayList<>();
}
@Override
- public SoundProfile createSoundProfile(SoundProfile sp, int userId) {
+ public SoundProfile createSoundProfile(SoundProfile sp, UserHandle user) {
SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
@@ -203,12 +207,12 @@
}
@Override
- public void updateSoundProfile(String id, SoundProfile pp, int userId) {
+ public void updateSoundProfile(String id, SoundProfile pp, UserHandle user) {
// TODO: implement
}
@Override
- public void removeSoundProfile(String id, int userId) {
+ public void removeSoundProfile(String id, UserHandle user) {
Long intId = mSoundProfileTempIdMap.inverse().get(id);
if (intId != null) {
SQLiteDatabase db = mMediaQualityDbHelper.getWritableDatabase();
@@ -221,9 +225,10 @@
}
@Override
- public SoundProfile getSoundProfile(int type, String id, int userId) {
+ public SoundProfile getSoundProfile(int type, String id, boolean includeParams,
+ UserHandle user) {
String selection = BaseParameters.PARAMETER_TYPE + " = ? AND "
- + BaseParameters.PARAMETER_NAME + " = ?";
+ + BaseParameters.PARAMETER_ID + " = ?";
String[] selectionArguments = {String.valueOf(type), id};
try (
@@ -247,7 +252,8 @@
}
@Override
- public List<SoundProfile> getSoundProfilesByPackage(String packageName, int userId) {
+ public List<SoundProfile> getSoundProfilesByPackage(
+ String packageName, boolean includeParams, UserHandle user) {
String selection = BaseParameters.PARAMETER_PACKAGE + " = ?";
String[] selectionArguments = {packageName};
return getSoundProfilesBasedOnConditions(getAllMediaProfileColumns(), selection,
@@ -255,18 +261,19 @@
}
@Override
- public List<SoundProfile> getAvailableSoundProfiles(int userId) {
+ public List<SoundProfile> getAvailableSoundProfiles(
+ boolean includeParams, UserHandle user) {
return new ArrayList<>();
}
@Override
- public boolean setDefaultSoundProfile(String profileId, int userId) {
+ public boolean setDefaultSoundProfile(String profileId, UserHandle user) {
// TODO: pass the profile ID to MediaQuality HAL when ready.
return false;
}
@Override
- public List<String> getSoundProfilePackageNames(int userId) {
+ public List<String> getSoundProfilePackageNames(UserHandle user) {
String [] column = {BaseParameters.PARAMETER_NAME};
List<SoundProfile> soundProfiles = getSoundProfilesBasedOnConditions(column,
null, null);
@@ -456,70 +463,71 @@
}
@Override
- public void setAmbientBacklightSettings(AmbientBacklightSettings settings, int userId) {
+ public void setAmbientBacklightSettings(
+ AmbientBacklightSettings settings, UserHandle user) {
}
@Override
- public void setAmbientBacklightEnabled(boolean enabled, int userId) {
+ public void setAmbientBacklightEnabled(boolean enabled, UserHandle user) {
}
@Override
- public List<ParamCapability> getParamCapabilities(List<String> names, int userId) {
+ public List<ParamCapability> getParamCapabilities(List<String> names, UserHandle user) {
return new ArrayList<>();
}
@Override
- public List<String> getPictureProfileAllowList(int userId) {
+ public List<String> getPictureProfileAllowList(UserHandle user) {
return new ArrayList<>();
}
@Override
- public void setPictureProfileAllowList(List<String> packages, int userId) {
+ public void setPictureProfileAllowList(List<String> packages, UserHandle user) {
}
@Override
- public List<String> getSoundProfileAllowList(int userId) {
+ public List<String> getSoundProfileAllowList(UserHandle user) {
return new ArrayList<>();
}
@Override
- public void setSoundProfileAllowList(List<String> packages, int userId) {
+ public void setSoundProfileAllowList(List<String> packages, UserHandle user) {
}
@Override
- public boolean isSupported(int userId) {
+ public boolean isSupported(UserHandle user) {
return false;
}
@Override
- public void setAutoPictureQualityEnabled(boolean enabled, int userId) {
+ public void setAutoPictureQualityEnabled(boolean enabled, UserHandle user) {
}
@Override
- public boolean isAutoPictureQualityEnabled(int userId) {
+ public boolean isAutoPictureQualityEnabled(UserHandle user) {
return false;
}
@Override
- public void setSuperResolutionEnabled(boolean enabled, int userId) {
+ public void setSuperResolutionEnabled(boolean enabled, UserHandle user) {
}
@Override
- public boolean isSuperResolutionEnabled(int userId) {
+ public boolean isSuperResolutionEnabled(UserHandle user) {
return false;
}
@Override
- public void setAutoSoundQualityEnabled(boolean enabled, int userId) {
+ public void setAutoSoundQualityEnabled(boolean enabled, UserHandle user) {
}
@Override
- public boolean isAutoSoundQualityEnabled(int userId) {
+ public boolean isAutoSoundQualityEnabled(UserHandle user) {
return false;
}
@Override
- public boolean isAmbientBacklightEnabled(int userId) {
+ public boolean isAmbientBacklightEnabled(UserHandle user) {
return false;
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 15af36b..39eea74 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2594,6 +2594,7 @@
intent.setPackage(pkg);
intent.putExtra(EXTRA_AUTOMATIC_ZEN_RULE_ID, id);
intent.putExtra(EXTRA_AUTOMATIC_ZEN_RULE_STATUS, status);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
getContext().sendBroadcastAsUser(intent, UserHandle.of(userId));
});
}
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index c09077e..f17ac5c 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -21,6 +21,7 @@
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
+import android.service.notification.RateEstimator;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index dc173b1..95aff56 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -112,9 +112,10 @@
import android.util.StatsEvent;
import android.util.proto.ProtoOutputStream;
+import androidx.annotation.VisibleForTesting;
+
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.util.FrameworkStatsLog;
@@ -279,6 +280,11 @@
mCallbacks.remove(callback);
}
+ @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+ public List<Callback> getCallbacks() {
+ return mCallbacks;
+ }
+
public void initZenMode() {
if (DEBUG) Log.d(TAG, "initZenMode");
synchronized (mConfigLock) {
diff --git a/services/core/java/com/android/server/os/instrumentation/DynamicInstrumentationManagerService.java b/services/core/java/com/android/server/os/instrumentation/DynamicInstrumentationManagerService.java
index 8ec7160..871d12e 100644
--- a/services/core/java/com/android/server/os/instrumentation/DynamicInstrumentationManagerService.java
+++ b/services/core/java/com/android/server/os/instrumentation/DynamicInstrumentationManagerService.java
@@ -20,116 +20,100 @@
import static android.content.Context.DYNAMIC_INSTRUMENTATION_SERVICE;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.PermissionManuallyEnforced;
+import android.annotation.RequiresPermission;
+import android.app.ActivityManagerInternal;
import android.content.Context;
+import android.os.RemoteException;
import android.os.instrumentation.ExecutableMethodFileOffsets;
import android.os.instrumentation.IDynamicInstrumentationManager;
+import android.os.instrumentation.IOffsetCallback;
import android.os.instrumentation.MethodDescriptor;
+import android.os.instrumentation.MethodDescriptorParser;
import android.os.instrumentation.TargetProcess;
-import com.android.internal.annotations.VisibleForTesting;
+
+import com.android.server.LocalServices;
import com.android.server.SystemService;
import dalvik.system.VMDebug;
import java.lang.reflect.Method;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+
/**
* System private implementation of the {@link IDynamicInstrumentationManager interface}.
*/
public class DynamicInstrumentationManagerService extends SystemService {
+
+ private ActivityManagerInternal mAmInternal;
+
public DynamicInstrumentationManagerService(@NonNull Context context) {
super(context);
}
@Override
public void onStart() {
+ mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
publishBinderService(DYNAMIC_INSTRUMENTATION_SERVICE, new BinderService());
}
private final class BinderService extends IDynamicInstrumentationManager.Stub {
@Override
@PermissionManuallyEnforced
- public @Nullable ExecutableMethodFileOffsets getExecutableMethodFileOffsets(
- @NonNull TargetProcess targetProcess, @NonNull MethodDescriptor methodDescriptor) {
+ @RequiresPermission(value = android.Manifest.permission.DYNAMIC_INSTRUMENTATION)
+ public void getExecutableMethodFileOffsets(
+ @NonNull TargetProcess targetProcess, @NonNull MethodDescriptor methodDescriptor,
+ @NonNull IOffsetCallback callback) {
if (!com.android.art.flags.Flags.executableMethodFileOffsets()) {
throw new UnsupportedOperationException();
}
getContext().enforceCallingOrSelfPermission(
DYNAMIC_INSTRUMENTATION, "Caller must have DYNAMIC_INSTRUMENTATION permission");
+ Objects.requireNonNull(targetProcess.processName);
- if (targetProcess.processName == null
- || !targetProcess.processName.equals("system_server")) {
- throw new UnsupportedOperationException(
- "system_server is the only supported target process");
+ if (!targetProcess.processName.equals("system_server")) {
+ try {
+ mAmInternal.getExecutableMethodFileOffsets(targetProcess.processName,
+ targetProcess.pid, targetProcess.uid, methodDescriptor,
+ new IOffsetCallback.Stub() {
+ @Override
+ public void onResult(ExecutableMethodFileOffsets result) {
+ try {
+ callback.onResult(result);
+ } catch (RemoteException e) {
+ /* ignore */
+ }
+ }
+ });
+ return;
+ } catch (NoSuchElementException e) {
+ throw new IllegalArgumentException(
+ "The specified app process cannot be found." , e);
+ }
}
- Method method = parseMethodDescriptor(
+ Method method = MethodDescriptorParser.parseMethodDescriptor(
getClass().getClassLoader(), methodDescriptor);
VMDebug.ExecutableMethodFileOffsets location =
VMDebug.getExecutableMethodFileOffsets(method);
- if (location == null) {
- return null;
- }
-
- ExecutableMethodFileOffsets ret = new ExecutableMethodFileOffsets();
- ret.containerPath = location.getContainerPath();
- ret.containerOffset = location.getContainerOffset();
- ret.methodOffset = location.getMethodOffset();
- return ret;
- }
- }
-
- @VisibleForTesting
- static Method parseMethodDescriptor(ClassLoader classLoader,
- @NonNull MethodDescriptor descriptor) {
- try {
- Class<?> javaClass = classLoader.loadClass(descriptor.fullyQualifiedClassName);
- Class<?>[] parameters = new Class[descriptor.fullyQualifiedParameters.length];
- for (int i = 0; i < descriptor.fullyQualifiedParameters.length; i++) {
- String typeName = descriptor.fullyQualifiedParameters[i];
- boolean isArrayType = typeName.endsWith("[]");
- if (isArrayType) {
- typeName = typeName.substring(0, typeName.length() - 2);
+ try {
+ if (location == null) {
+ callback.onResult(null);
+ return;
}
- switch (typeName) {
- case "boolean":
- parameters[i] = isArrayType ? boolean.class.arrayType() : boolean.class;
- break;
- case "byte":
- parameters[i] = isArrayType ? byte.class.arrayType() : byte.class;
- break;
- case "char":
- parameters[i] = isArrayType ? char.class.arrayType() : char.class;
- break;
- case "short":
- parameters[i] = isArrayType ? short.class.arrayType() : short.class;
- break;
- case "int":
- parameters[i] = isArrayType ? int.class.arrayType() : int.class;
- break;
- case "long":
- parameters[i] = isArrayType ? long.class.arrayType() : long.class;
- break;
- case "float":
- parameters[i] = isArrayType ? float.class.arrayType() : float.class;
- break;
- case "double":
- parameters[i] = isArrayType ? double.class.arrayType() : double.class;
- break;
- default:
- parameters[i] = isArrayType ? classLoader.loadClass(typeName).arrayType()
- : classLoader.loadClass(typeName);
- }
- }
- return javaClass.getDeclaredMethod(descriptor.methodName, parameters);
- } catch (ClassNotFoundException | NoSuchMethodException e) {
- throw new IllegalArgumentException(
- "The specified method cannot be found. Is this descriptor valid? "
- + descriptor, e);
+ ExecutableMethodFileOffsets ret = new ExecutableMethodFileOffsets();
+ ret.containerPath = location.getContainerPath();
+ ret.containerOffset = location.getContainerOffset();
+ ret.methodOffset = location.getMethodOffset();
+ callback.onResult(ret);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failed to invoke result callback", e);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/pm/BroadcastHelper.java b/services/core/java/com/android/server/pm/BroadcastHelper.java
index 6d54be8..67e1095 100644
--- a/services/core/java/com/android/server/pm/BroadcastHelper.java
+++ b/services/core/java/com/android/server/pm/BroadcastHelper.java
@@ -53,6 +53,7 @@
import android.os.PowerExemptionManager;
import android.os.Process;
import android.os.RemoteException;
+import android.os.Trace;
import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
@@ -78,6 +79,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.function.BiFunction;
+import java.util.function.Supplier;
/**
* Helper class to send broadcasts for various situations.
@@ -216,7 +218,7 @@
filterExtrasForReceiver, bOptions);
}
- void sendResourcesChangedBroadcast(@NonNull Computer snapshot,
+ void sendResourcesChangedBroadcast(@NonNull Supplier<Computer> snapshotSupplier,
boolean mediaStatus,
boolean replacing,
@NonNull String[] pkgNames,
@@ -236,7 +238,7 @@
null /* targetPkg */, null /* finishedReceiver */, null /* userIds */,
null /* instantUserIds */, null /* broadcastAllowList */,
(callingUid, intentExtras) -> filterExtrasChangedPackageList(
- snapshot, callingUid, intentExtras),
+ snapshotSupplier, callingUid, intentExtras),
null /* bOptions */, null /* requiredPermissions */);
}
@@ -357,9 +359,14 @@
@Nullable int[] instantUserIds,
@Nullable SparseArray<int[]> broadcastAllowList,
@NonNull AndroidPackage pkg,
- @NonNull String[] sharedUidPackages) {
+ @NonNull String[] sharedUidPackages,
+ @NonNull String reasonForTrace) {
final boolean isForWholeApp = componentNames.contains(packageName);
if (isForWholeApp || !android.content.pm.Flags.reduceBroadcastsForComponentStateChanges()) {
+ tracePackageChangedBroadcastEvent(
+ android.content.pm.Flags.reduceBroadcastsForComponentStateChanges(),
+ reasonForTrace, "all" /* targetName */, "whole" /* targetComponent */,
+ componentNames.size());
sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp, componentNames,
packageUid, reason, userIds, instantUserIds, broadcastAllowList,
null /* targetPackageName */, null /* requiredPermissions */);
@@ -381,6 +388,9 @@
// First, send the PACKAGE_CHANGED broadcast to the system.
if (!TextUtils.equals(packageName, "android")) {
+ tracePackageChangedBroadcastEvent(true /* applyFlag */, reasonForTrace,
+ "system" /* targetName */, "notExported" /* targetComponent */,
+ notExportedComponentNames.size());
sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
notExportedComponentNames, packageUid, reason, userIds, instantUserIds,
broadcastAllowList, "android" /* targetPackageName */,
@@ -389,6 +399,9 @@
}
// Second, send the PACKAGE_CHANGED broadcast to the application itself.
+ tracePackageChangedBroadcastEvent(true /* applyFlag */, reasonForTrace,
+ "applicationItself" /* targetName */, "notExported" /* targetComponent */,
+ notExportedComponentNames.size());
sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
notExportedComponentNames, packageUid, reason, userIds, instantUserIds,
broadcastAllowList, packageName /* targetPackageName */,
@@ -400,6 +413,9 @@
if (TextUtils.equals(packageName, sharedPackage)) {
continue;
}
+ tracePackageChangedBroadcastEvent(true /* applyFlag */, reasonForTrace,
+ "sharedUidPackages" /* targetName */, "notExported" /* targetComponent */,
+ notExportedComponentNames.size());
sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
notExportedComponentNames, packageUid, reason, userIds, instantUserIds,
broadcastAllowList, sharedPackage /* targetPackageName */,
@@ -409,6 +425,9 @@
}
if (!exportedComponentNames.isEmpty()) {
+ tracePackageChangedBroadcastEvent(true /* applyFlag */, reasonForTrace,
+ "all" /* targetName */, "exported" /* targetComponent */,
+ exportedComponentNames.size());
sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
exportedComponentNames, packageUid, reason, userIds, instantUserIds,
broadcastAllowList, null /* targetPackageName */,
@@ -544,7 +563,7 @@
});
}
- void sendPostInstallBroadcasts(@NonNull Computer snapshot,
+ void sendPostInstallBroadcasts(@NonNull Supplier<Computer> snapshotSupplier,
@NonNull InstallRequest request,
@NonNull String packageName,
@NonNull String requiredPermissionControllerPackage,
@@ -567,8 +586,8 @@
final int[] uids = new int[]{request.getRemovedInfo().mUid};
notifyResourcesChanged(
false /* mediaStatus */, true /* replacing */, pkgNames, uids);
- sendResourcesChangedBroadcast(
- snapshot, false /* mediaStatus */, true /* replacing */, pkgNames, uids);
+ sendResourcesChangedBroadcast(snapshotSupplier,
+ false /* mediaStatus */, true /* replacing */, pkgNames, uids);
}
sendPackageRemovedBroadcasts(
request.getRemovedInfo(), packageSender, isKillApp, false /*removedBySystem*/,
@@ -608,6 +627,7 @@
null /* broadcastAllowList */, null);
}
+ final Computer snapshot = snapshotSupplier.get();
// Send installed broadcasts if the package is not a static shared lib.
if (staticSharedLibraryName == null) {
// Send PACKAGE_ADDED broadcast for users that see the package for the first time
@@ -732,7 +752,7 @@
if (!isArchived) {
final String[] pkgNames = new String[]{packageName};
final int[] uids = new int[]{request.getPkg().getUid()};
- sendResourcesChangedBroadcast(snapshot,
+ sendResourcesChangedBroadcast(snapshotSupplier,
true /* mediaStatus */, true /* replacing */, pkgNames, uids);
notifyResourcesChanged(true /* mediaStatus */,
true /* replacing */, pkgNames, uids);
@@ -749,7 +769,8 @@
sendPackageChangedBroadcast(snapshot, pkg.getPackageName(),
dontKillApp,
new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
- pkg.getUid(), null);
+ pkg.getUid(), null /* reason */,
+ "static_shared_library_changed" /* reasonForTrace */);
}
}
}
@@ -860,8 +881,8 @@
* access all the packages in the extras.
*/
@Nullable
- private static Bundle filterExtrasChangedPackageList(@NonNull Computer snapshot, int callingUid,
- @NonNull Bundle extras) {
+ private static Bundle filterExtrasChangedPackageList(
+ @NonNull Supplier<Computer> snapshotSupplier, int callingUid, @NonNull Bundle extras) {
if (UserHandle.isCore(callingUid)) {
// see all
return extras;
@@ -873,6 +894,7 @@
final int userId = extras.getInt(
Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(callingUid));
final int[] uids = extras.getIntArray(Intent.EXTRA_CHANGED_UID_LIST);
+ final Computer snapshot = snapshotSupplier.get();
final Pair<String[], int[]> filteredPkgs =
filterPackages(snapshot, pkgs, uids, callingUid, userId);
if (ArrayUtils.isEmpty(filteredPkgs.first)) {
@@ -939,7 +961,8 @@
boolean dontKillApp,
@NonNull ArrayList<String> componentNames,
int packageUid,
- @NonNull String reason) {
+ @NonNull String reason,
+ @NonNull String reasonForTrace) {
PackageStateInternal setting = snapshot.getPackageStateInternal(packageName,
Process.SYSTEM_UID);
if (setting == null || setting.getPkg() == null) {
@@ -952,10 +975,12 @@
final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
final SparseArray<int[]> broadcastAllowList =
isInstantApp ? null : snapshot.getVisibilityAllowLists(packageName, userIds);
+ final String[] sharedUserPackages =
+ snapshot.getSharedUserPackagesForPackage(packageName, userId);
mHandler.post(() -> sendPackageChangedBroadcastInternal(
packageName, dontKillApp, componentNames, packageUid, reason, userIds,
instantUserIds, broadcastAllowList, setting.getPkg(),
- snapshot.getSharedUserPackagesForPackage(packageName, userId)));
+ sharedUserPackages, reasonForTrace));
mPackageMonitorCallbackHelper.notifyPackageChanged(packageName, dontKillApp, componentNames,
packageUid, reason, userIds, instantUserIds, broadcastAllowList, mHandler);
}
@@ -1120,7 +1145,7 @@
* @param uidList The uids of packages which have suspension changes.
* @param userId The user where packages reside.
*/
- void sendPackagesSuspendedOrUnsuspendedForUser(@NonNull Computer snapshot,
+ void sendPackagesSuspendedOrUnsuspendedForUser(@NonNull Supplier<Computer> snapshotSupplier,
@NonNull String intent,
@NonNull String[] pkgList,
@NonNull int[] uidList,
@@ -1138,7 +1163,7 @@
.toBundle();
BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver =
(callingUid, intentExtras) -> BroadcastHelper.filterExtrasChangedPackageList(
- snapshot, callingUid, intentExtras);
+ snapshotSupplier, callingUid, intentExtras);
mHandler.post(() -> sendPackageBroadcast(intent, null /* pkg */,
extras, flags, null /* targetPkg */, null /* finishedReceiver */,
new int[]{userId}, null /* instantUserIds */, null /* broadcastAllowList */,
@@ -1148,7 +1173,7 @@
null /* instantUserIds */, null /* broadcastAllowList */, filterExtrasForReceiver);
}
- void sendMyPackageSuspendedOrUnsuspended(@NonNull Computer snapshot,
+ void sendMyPackageSuspendedOrUnsuspended(@NonNull Supplier<Computer> snapshotSupplier,
@NonNull String[] affectedPackages,
boolean suspended,
int userId) {
@@ -1163,6 +1188,7 @@
return;
}
final int[] targetUserIds = new int[] {userId};
+ final Computer snapshot = snapshotSupplier.get();
for (String packageName : affectedPackages) {
final Bundle appExtras = suspended
? SuspendPackageHelper.getSuspendedPackageAppExtras(
@@ -1192,7 +1218,7 @@
* @param uidList The uids of packages which have suspension changes.
* @param userId The user where packages reside.
*/
- void sendDistractingPackagesChanged(@NonNull Computer snapshot,
+ void sendDistractingPackagesChanged(@NonNull Supplier<Computer> snapshotSupplier,
@NonNull String[] pkgList,
@NonNull int[] uidList,
int userId,
@@ -1208,11 +1234,11 @@
null /* finishedReceiver */, new int[]{userId}, null /* instantUserIds */,
null /* broadcastAllowList */,
(callingUid, intentExtras) -> filterExtrasChangedPackageList(
- snapshot, callingUid, intentExtras),
+ snapshotSupplier, callingUid, intentExtras),
null /* bOptions */, null /* requiredPermissions */));
}
- void sendResourcesChangedBroadcastAndNotify(@NonNull Computer snapshot,
+ void sendResourcesChangedBroadcastAndNotify(@NonNull Supplier<Computer> snapshotSupplier,
boolean mediaStatus,
boolean replacing,
@NonNull ArrayList<AndroidPackage> packages) {
@@ -1224,7 +1250,7 @@
packageNames[i] = pkg.getPackageName();
packageUids[i] = pkg.getUid();
}
- sendResourcesChangedBroadcast(snapshot, mediaStatus,
+ sendResourcesChangedBroadcast(snapshotSupplier, mediaStatus,
replacing, packageNames, packageUids);
notifyResourcesChanged(mediaStatus, replacing, packageNames, packageUids);
}
@@ -1247,4 +1273,22 @@
mPackageMonitorCallbackHelper.notifyResourcesChanged(mediaStatus, replacing, pkgNames,
uids, mHandler);
}
+
+ private static void tracePackageChangedBroadcastEvent(boolean applyFlag, String reasonForTrace,
+ String targetName, String targetComponent, int componentSize) {
+
+ if (!Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
+ return;
+ }
+
+ final StringBuilder builder = new StringBuilder();
+ builder.append("broadcastPackageChanged; ");
+ builder.append("af="); builder.append(applyFlag);
+ builder.append(",rft="); builder.append(reasonForTrace);
+ builder.append(",tn="); builder.append(targetName);
+ builder.append(",tc="); builder.append(targetComponent);
+ builder.append(",cs="); builder.append(componentSize);
+
+ Trace.instant(Trace.TRACE_TAG_SYSTEM_SERVER, builder.toString());
+ }
}
diff --git a/services/core/java/com/android/server/pm/DistractingPackageHelper.java b/services/core/java/com/android/server/pm/DistractingPackageHelper.java
index c5ec73b..c4e981d 100644
--- a/services/core/java/com/android/server/pm/DistractingPackageHelper.java
+++ b/services/core/java/com/android/server/pm/DistractingPackageHelper.java
@@ -123,7 +123,7 @@
if (!changedPackagesList.isEmpty()) {
final String[] changedPackages = changedPackagesList.toArray(
new String[changedPackagesList.size()]);
- mBroadcastHelper.sendDistractingPackagesChanged(mPm.snapshotComputer(),
+ mBroadcastHelper.sendDistractingPackagesChanged(mPm::snapshotComputer,
changedPackages, changedUids.toArray(), userId, restrictionFlags);
mPm.scheduleWritePackageRestrictions(userId);
}
@@ -198,7 +198,7 @@
if (!changedPackages.isEmpty()) {
final String[] packageArray = changedPackages.toArray(
new String[changedPackages.size()]);
- mBroadcastHelper.sendDistractingPackagesChanged(mPm.snapshotComputer(),
+ mBroadcastHelper.sendDistractingPackagesChanged(mPm::snapshotComputer,
packageArray, changedUids.toArray(), userId, RESTRICTION_NONE);
mPm.scheduleWritePackageRestrictions(userId);
}
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 69c6ce8..b48b39c 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -2983,7 +2983,7 @@
}
}
- public void sendPendingBroadcasts() {
+ public void sendPendingBroadcasts(String reasonForTrace) {
String[] packages;
ArrayList<String>[] components;
int numBroadcasts = 0, numUsers;
@@ -3027,7 +3027,8 @@
// Send broadcasts
for (int i = 0; i < numBroadcasts; i++) {
mBroadcastHelper.sendPackageChangedBroadcast(snapshot, packages[i],
- true /* dontKillApp */, components[i], uids[i], null /* reason */);
+ true /* dontKillApp */, components[i], uids[i], null /* reason */,
+ reasonForTrace);
}
}
@@ -3084,7 +3085,7 @@
mPm.mProcessLoggingHandler.invalidateBaseApkHash(request.getPkg().getBaseApkPath());
}
- mBroadcastHelper.sendPostInstallBroadcasts(mPm.snapshotComputer(), request, packageName,
+ mBroadcastHelper.sendPostInstallBroadcasts(mPm::snapshotComputer, request, packageName,
mPm.mRequiredPermissionControllerPackage, mPm.mRequiredVerifierPackages,
mPm.mRequiredInstallerPackage,
/* packageSender= */ mPm, launchedForRestore, killApp, update, archived);
diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java
index 4ea4054..0a06704 100644
--- a/services/core/java/com/android/server/pm/PackageHandler.java
+++ b/services/core/java/com/android/server/pm/PackageHandler.java
@@ -76,7 +76,7 @@
void doHandleMessage(Message msg) {
switch (msg.what) {
case SEND_PENDING_BROADCAST: {
- mPm.sendPendingBroadcasts();
+ mPm.sendPendingBroadcasts((String) msg.obj);
break;
}
case POST_INSTALL: {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 65bb701..aadf112 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3531,7 +3531,10 @@
mPendingBroadcasts.addComponents(userId, packageName, updatedComponents);
if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
- mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(SEND_PENDING_BROADCAST,
+ "reset_component_state_changed" /* obj */),
+ BROADCAST_DELAY);
}
}
@@ -3828,7 +3831,8 @@
mPendingBroadcasts.addComponent(userId, componentPkgName, componentName.getClassName());
if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
- mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(SEND_PENDING_BROADCAST,
+ "component_label_icon_changed" /* obj */), BROADCAST_DELAY);
}
}
@@ -4063,6 +4067,8 @@
mPendingBroadcasts.remove(userId, packageName);
} else {
mPendingBroadcasts.addComponent(userId, packageName, componentName);
+ Trace.instant(Trace.TRACE_TAG_PACKAGE_MANAGER, "setEnabledSetting broadcast: "
+ + componentName + ": " + setting.getEnabledState());
scheduleBroadcastMessage = true;
}
}
@@ -4085,7 +4091,8 @@
final long broadcastDelay = SystemClock.uptimeMillis() > mServiceStartWithDelay
? BROADCAST_DELAY
: BROADCAST_DELAY_DURING_STARTUP;
- mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, broadcastDelay);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(SEND_PENDING_BROADCAST,
+ "component_state_changed" /* obj */), broadcastDelay);
}
}
}
@@ -4103,7 +4110,8 @@
final int packageUid = UserHandle.getUid(
userId, pkgSettings.get(packageName).getAppId());
mBroadcastHelper.sendPackageChangedBroadcast(newSnapshot, packageName,
- false /* dontKillApp */, components, packageUid, null /* reason */);
+ false /* dontKillApp */, components, packageUid, null /* reason */,
+ "component_state_changed" /* reasonForTrace */);
}
} finally {
Binder.restoreCallingIdentity(callingId);
@@ -4331,7 +4339,7 @@
true /* dontKillApp */,
new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
pkg.getUid(),
- Intent.ACTION_OVERLAY_CHANGED);
+ Intent.ACTION_OVERLAY_CHANGED, "overlay_changed" /* reasonForTrace */);
}
}, overlayFilter);
@@ -6382,7 +6390,8 @@
if (pkgUserState != null && pkgUserState.isInstalled()) {
final int packageUid = UserHandle.getUid(userIds[i], appId);
mBroadcastHelper.sendPackageChangedBroadcast(snapShot, packageName,
- true /* dontKillApp */, components, packageUid, reason);
+ true /* dontKillApp */, components, packageUid, reason,
+ "mime_group_changed" /* reasonForTrace */);
}
}
});
@@ -8177,8 +8186,8 @@
mRemovePackageHelper.cleanUpForMoveInstall(volumeUuid, packageName, fromCodePath);
}
- void sendPendingBroadcasts() {
- mInstallPackageHelper.sendPendingBroadcasts();
+ void sendPendingBroadcasts(String reasonForTrace) {
+ mInstallPackageHelper.sendPendingBroadcasts(reasonForTrace);
}
void handlePackagePostInstall(@NonNull InstallRequest request, boolean launchedForRestore) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 9757582..7af39f7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -749,7 +749,7 @@
null /*abiOverride*/, false /*isIncremental*/);
} catch (IOException e) {
logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
- + "; pkg: " + packageName);
+ + "; pkg: " + packageName + "; err: " + e.getMessage());
return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
} finally {
IoUtils.closeQuietly(handle);
diff --git a/services/core/java/com/android/server/pm/SaferIntentUtils.java b/services/core/java/com/android/server/pm/SaferIntentUtils.java
index 854e142..ec91da9 100644
--- a/services/core/java/com/android/server/pm/SaferIntentUtils.java
+++ b/services/core/java/com/android/server/pm/SaferIntentUtils.java
@@ -213,6 +213,7 @@
* CTS tests. The code in this method shall properly avoid control flows using these arguments.
*/
public static void blockNullAction(IntentArgs args, List componentList) {
+ if (args.intent.getAction() != null) return;
if (ActivityManager.canAccessUnexportedComponents(args.callingUid)) return;
final Computer computer = (Computer) args.snapshot;
@@ -235,14 +236,11 @@
}
final ParsedMainComponent comp = infoToComponent(
resolveInfo.getComponentInfo(), resolver, args.isReceiver);
- if (comp != null && !comp.getIntents().isEmpty()
- && args.intent.getAction() == null) {
+ if (comp != null && !comp.getIntents().isEmpty()) {
match = false;
}
} else if (c instanceof IntentFilter) {
- if (args.intent.getAction() == null) {
- match = false;
- }
+ match = false;
}
if (!match) {
diff --git a/services/core/java/com/android/server/pm/StorageEventHelper.java b/services/core/java/com/android/server/pm/StorageEventHelper.java
index 951986f..a09d477 100644
--- a/services/core/java/com/android/server/pm/StorageEventHelper.java
+++ b/services/core/java/com/android/server/pm/StorageEventHelper.java
@@ -227,7 +227,7 @@
}
if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
- mBroadcastHelper.sendResourcesChangedBroadcastAndNotify(mPm.snapshotComputer(),
+ mBroadcastHelper.sendResourcesChangedBroadcastAndNotify(mPm::snapshotComputer,
true /* mediaStatus */, false /* replacing */, loaded);
synchronized (mLoadedVolumes) {
mLoadedVolumes.add(vol.getId());
@@ -279,7 +279,7 @@
}
if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
- mBroadcastHelper.sendResourcesChangedBroadcastAndNotify(mPm.snapshotComputer(),
+ mBroadcastHelper.sendResourcesChangedBroadcastAndNotify(mPm::snapshotComputer,
false /* mediaStatus */, false /* replacing */, unloaded);
synchronized (mLoadedVolumes) {
mLoadedVolumes.remove(vol.getId());
diff --git a/services/core/java/com/android/server/pm/SuspendPackageHelper.java b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
index 4e70cc5..88fd1aa 100644
--- a/services/core/java/com/android/server/pm/SuspendPackageHelper.java
+++ b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
@@ -192,21 +192,20 @@
}
});
- final Computer newSnapshot = mPm.snapshotComputer();
if (!notifyPackagesList.isEmpty()) {
final String[] changedPackages =
notifyPackagesList.toArray(new String[0]);
- mBroadcastHelper.sendPackagesSuspendedOrUnsuspendedForUser(newSnapshot,
+ mBroadcastHelper.sendPackagesSuspendedOrUnsuspendedForUser(mPm::snapshotComputer,
suspended ? Intent.ACTION_PACKAGES_SUSPENDED
: Intent.ACTION_PACKAGES_UNSUSPENDED,
changedPackages, notifyUids.toArray(), quarantined, targetUserId);
- mBroadcastHelper.sendMyPackageSuspendedOrUnsuspended(newSnapshot, changedPackages,
- suspended, targetUserId);
+ mBroadcastHelper.sendMyPackageSuspendedOrUnsuspended(mPm::snapshotComputer,
+ changedPackages, suspended, targetUserId);
mPm.scheduleWritePackageRestrictions(targetUserId);
}
// Send the suspension changed broadcast to ensure suspension state is not stale.
if (!changedPackagesList.isEmpty()) {
- mBroadcastHelper.sendPackagesSuspendedOrUnsuspendedForUser(newSnapshot,
+ mBroadcastHelper.sendPackagesSuspendedOrUnsuspendedForUser(mPm::snapshotComputer,
Intent.ACTION_PACKAGES_SUSPENSION_CHANGED,
changedPackagesList.toArray(new String[0]), changedUids.toArray(), quarantined,
targetUserId);
@@ -343,13 +342,12 @@
});
mPm.scheduleWritePackageRestrictions(targetUserId);
- final Computer newSnapshot = mPm.snapshotComputer();
if (!unsuspendedPackages.isEmpty()) {
final String[] packageArray = unsuspendedPackages.toArray(
new String[unsuspendedPackages.size()]);
- mBroadcastHelper.sendMyPackageSuspendedOrUnsuspended(newSnapshot, packageArray,
- false, targetUserId);
- mBroadcastHelper.sendPackagesSuspendedOrUnsuspendedForUser(newSnapshot,
+ mBroadcastHelper.sendMyPackageSuspendedOrUnsuspended(mPm::snapshotComputer,
+ packageArray, false, targetUserId);
+ mBroadcastHelper.sendPackagesSuspendedOrUnsuspendedForUser(mPm::snapshotComputer,
Intent.ACTION_PACKAGES_UNSUSPENDED,
packageArray, unsuspendedUids.toArray(), false, targetUserId);
}
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
index 041f2d3..04ce4e6 100644
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
@@ -68,6 +68,10 @@
void prepareUserData(UserInfo userInfo, int flags) {
try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
final StorageManager storage = mContext.getSystemService(StorageManager.class);
+ if (storage == null) {
+ Log.e(TAG, "prepareUserData failed due to unable get StorageManager");
+ return;
+ }
/*
* Internal storage must be prepared before adoptable storage, since the user's volume
* keys are stored in their internal storage.
@@ -159,14 +163,16 @@
void destroyUserData(int userId, int flags) {
try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
final StorageManager storage = mContext.getSystemService(StorageManager.class);
- /*
- * Volume destruction order isn't really important, but to avoid any weird issues we
- * process internal storage last, the opposite of prepareUserData.
- */
- for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
- final String volumeUuid = vol.getFsUuid();
- if (volumeUuid != null) {
- destroyUserDataLI(volumeUuid, userId, flags);
+ if (storage != null) {
+ /*
+ * Volume destruction order isn't really important, but to avoid any weird issues we
+ * process internal storage last, the opposite of prepareUserData.
+ */
+ for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
+ final String volumeUuid = vol.getFsUuid();
+ if (volumeUuid != null) {
+ destroyUserDataLI(volumeUuid, userId, flags);
+ }
}
}
destroyUserDataLI(null /* internal storage */, userId, flags);
@@ -194,9 +200,10 @@
}
}
- // All the user's data directories should be empty now, so finish the job.
- storage.destroyUserStorage(volumeUuid, userId, flags);
-
+ if (storage != null) {
+ // All the user's data directories should be empty now, so finish the job.
+ storage.destroyUserStorage(volumeUuid, userId, flags);
+ }
} catch (Exception e) {
logCriticalInfo(Log.WARN,
"Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e);
diff --git a/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java b/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java
index e989d68..e9cb279 100644
--- a/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java
+++ b/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java
@@ -40,7 +40,7 @@
import com.android.internal.util.function.DodecFunction;
import com.android.internal.util.function.HexConsumer;
import com.android.internal.util.function.HexFunction;
-import com.android.internal.util.function.NonaFunction;
+import com.android.internal.util.function.OctFunction;
import com.android.internal.util.function.QuadFunction;
import com.android.internal.util.function.TriFunction;
import com.android.internal.util.function.UndecFunction;
@@ -351,22 +351,22 @@
@Override
public SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
@Nullable String featureId, int virtualDeviceId, boolean shouldCollectAsyncNotedOp,
- @Nullable String message, boolean shouldCollectMessage, int notedCount,
- @NonNull NonaFunction<Integer, Integer, String, String, Integer, Boolean, String,
- Boolean, Integer, SyncNotedAppOp> superImpl) {
+ @Nullable String message, boolean shouldCollectMessage,
+ @NonNull OctFunction<Integer, Integer, String, String, Integer, Boolean, String,
+ Boolean, SyncNotedAppOp> superImpl) {
if (uid == mDelegateAndOwnerUid && isDelegateOp(code)) {
final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
Process.SHELL_UID);
final long identity = Binder.clearCallingIdentity();
try {
return superImpl.apply(code, shellUid, SHELL_PKG, featureId, virtualDeviceId,
- shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount);
+ shouldCollectAsyncNotedOp, message, shouldCollectMessage);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
return superImpl.apply(code, uid, packageName, featureId, virtualDeviceId,
- shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount);
+ shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
@Override
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index 33210e2..ecffd38 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -53,7 +53,7 @@
import com.android.internal.util.function.DodecFunction;
import com.android.internal.util.function.HexConsumer;
import com.android.internal.util.function.HexFunction;
-import com.android.internal.util.function.NonaFunction;
+import com.android.internal.util.function.OctFunction;
import com.android.internal.util.function.QuadFunction;
import com.android.internal.util.function.UndecFunction;
import com.android.server.LocalServices;
@@ -246,12 +246,11 @@
public SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
@Nullable String attributionTag, int virtualDeviceId,
boolean shouldCollectAsyncNotedOp, @Nullable String message,
- boolean shouldCollectMessage, int notedCount,
- @NonNull NonaFunction<Integer, Integer, String, String,
- Integer, Boolean, String, Boolean, Integer, SyncNotedAppOp> superImpl) {
+ boolean shouldCollectMessage, @NonNull OctFunction<Integer, Integer, String, String,
+ Integer, Boolean, String, Boolean, SyncNotedAppOp> superImpl) {
return superImpl.apply(resolveDatasourceOp(code, uid, packageName, attributionTag),
resolveUid(code, uid), packageName, attributionTag, virtualDeviceId,
- shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount);
+ shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
@Override
diff --git a/services/core/java/com/android/server/policy/EventLogTags.logtags b/services/core/java/com/android/server/policy/EventLogTags.logtags
index 7563382..a4b6472 100644
--- a/services/core/java/com/android/server/policy/EventLogTags.logtags
+++ b/services/core/java/com/android/server/policy/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.server.policy
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 7c4d425..f1a4811 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4081,6 +4081,7 @@
case KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS:
case KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH:
case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT:
+ case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT:
case KeyGestureEvent.KEY_GESTURE_TYPE_HOME:
case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS:
case KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN:
@@ -4164,6 +4165,7 @@
}
return true;
case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT:
+ case KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT:
if (complete) {
launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD,
deviceId, SystemClock.uptimeMillis(),
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 987a849..137ea06 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -296,7 +296,11 @@
mPowerHalVersion = 0;
mUsesFmq = false;
if (mPowerHal != null) {
- mSupportInfo = getSupportInfo();
+ try {
+ mSupportInfo = getSupportInfo();
+ } catch (RemoteException e) {
+ throw new IllegalStateException("Could not contact PowerHAL!", e);
+ }
}
mDefaultCpuHeadroomCalculationWindowMillis =
new CpuHeadroomParamsInternal().calculationWindowMillis;
@@ -314,7 +318,7 @@
}
}
- SupportInfo getSupportInfo() {
+ SupportInfo getSupportInfo() throws RemoteException {
try {
mPowerHalVersion = mPowerHal.getInterfaceVersion();
if (mPowerHalVersion >= 6) {
@@ -325,9 +329,40 @@
}
SupportInfo supportInfo = new SupportInfo();
+ supportInfo.usesSessions = isHintSessionSupported();
+ // Global boosts & modes aren't currently relevant for HMS clients
+ supportInfo.boosts = 0;
+ supportInfo.modes = 0;
+ supportInfo.sessionHints = 0;
+ supportInfo.sessionModes = 0;
+ supportInfo.sessionTags = 0;
+
supportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
supportInfo.headroom.isCpuSupported = false;
supportInfo.headroom.isGpuSupported = false;
+ if (isHintSessionSupported()) {
+ if (mPowerHalVersion == 4) {
+ // Assume we support the V4 hints & modes unless specified
+ // otherwise; this is to avoid breaking backwards compat
+ // since we historically just assumed they were.
+ supportInfo.sessionHints = 31; // first 5 bits are ones
+ }
+ if (mPowerHalVersion == 5) {
+ // Assume we support the V5 hints & modes unless specified
+ // otherwise; this is to avoid breaking backwards compat
+ // since we historically just assumed they were.
+
+ // Hal V5 has 8 modes, all of which it assumes are supported,
+ // so we represent that by having the first 8 bits set
+ supportInfo.sessionHints = 255; // first 8 bits are ones
+ // Hal V5 has 1 mode which it assumes is supported, so we
+ // represent that by having the first bit set
+ supportInfo.sessionModes = 1;
+ // Hal V5 has 5 tags, all of which it assumes are supported,
+ // so we represent that by having the first 5 bits set
+ supportInfo.sessionTags = 31;
+ }
+ }
return supportInfo;
}
@@ -1228,7 +1263,7 @@
@SessionTag int tag, SessionCreationConfig creationConfig,
SessionConfig config) {
if (!isHintSessionSupported()) {
- throw new UnsupportedOperationException("PowerHAL is not supported!");
+ throw new UnsupportedOperationException("PowerHintSessions are not supported!");
}
java.util.Objects.requireNonNull(token);
@@ -1424,12 +1459,6 @@
removeChannelItem(callingTgid, callingUid);
};
- @Override
- public long getHintSessionPreferredRate() {
- return mHintSessionPreferredRate;
- }
-
- @Override
public int getMaxGraphicsPipelineThreadsCount() {
return MAX_GRAPHICS_PIPELINE_THREADS_COUNT;
}
@@ -1561,6 +1590,16 @@
mSessionManager = ISessionManager.Stub.asInterface(sessionManager);
}
+ public IHintManager.HintManagerClientData
+ registerClient(@NonNull IHintManager.IHintManagerClient clientBinder) {
+ IHintManager.HintManagerClientData out = new IHintManager.HintManagerClientData();
+ out.preferredRateNanos = mHintSessionPreferredRate;
+ out.maxGraphicsPipelineThreads = getMaxGraphicsPipelineThreadsCount();
+ out.powerHalVersion = mPowerHalVersion;
+ out.supportInfo = mSupportInfo;
+ return out;
+ }
+
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
@@ -1568,7 +1607,7 @@
}
pw.println("HintSessionPreferredRate: " + mHintSessionPreferredRate);
pw.println("MaxGraphicsPipelineThreadsCount: " + MAX_GRAPHICS_PIPELINE_THREADS_COUNT);
- pw.println("HAL Support: " + isHintSessionSupported());
+ pw.println("Hint Session Support: " + isHintSessionSupported());
pw.println("Active Sessions:");
synchronized (mLock) {
for (int i = 0; i < mActiveSessions.size(); i++) {
diff --git a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
index 8c588b4..63e8d99 100644
--- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
+++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
@@ -195,22 +195,23 @@
mLastAccumulationMonotonicHistorySize = historySize;
}
- // No need to store the accumulated stats asynchronously, as the entire accumulation
- // operation is async
- handler.post(() -> accumulateBatteryUsageStats(stats, false));
+ handler.post(() -> accumulateBatteryUsageStats(stats));
}
/**
* Computes BatteryUsageStats for the period since the last accumulated stats were stored,
- * adds them to the accumulated stats and asynchronously saves the result.
+ * adds them to the accumulated stats and saves the result.
*/
public void accumulateBatteryUsageStats(BatteryStatsImpl stats) {
- accumulateBatteryUsageStats(stats, true);
- }
-
- private void accumulateBatteryUsageStats(BatteryStatsImpl stats, boolean storeAsync) {
AccumulatedBatteryUsageStats accumulatedStats = loadAccumulatedBatteryUsageStats();
- updateAccumulatedBatteryUsageStats(accumulatedStats, stats);
+
+ final BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder()
+ .setMaxStatsAgeMs(0)
+ .includeProcessStateData()
+ .includePowerStateData()
+ .includeScreenStateData()
+ .build();
+ updateAccumulatedBatteryUsageStats(accumulatedStats, stats, query);
PowerStatsSpan powerStatsSpan = new PowerStatsSpan(AccumulatedBatteryUsageStatsSection.ID);
powerStatsSpan.addSection(
@@ -219,13 +220,8 @@
accumulatedStats.startWallClockTime,
accumulatedStats.endMonotonicTime - accumulatedStats.startMonotonicTime);
mMonotonicClock.write();
- if (storeAsync) {
- mPowerStatsStore.storePowerStatsSpanAsync(powerStatsSpan,
- accumulatedStats.builder::discard);
- } else {
- mPowerStatsStore.storePowerStatsSpan(powerStatsSpan);
- accumulatedStats.builder.discard();
- }
+ mPowerStatsStore.storePowerStatsSpanAsync(powerStatsSpan,
+ accumulatedStats.builder::discard);
}
/**
@@ -273,7 +269,7 @@
BatteryUsageStats batteryUsageStats;
if ((query.getFlags()
& BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_ACCUMULATED) != 0) {
- batteryUsageStats = getAccumulatedBatteryUsageStats(stats, query);
+ batteryUsageStats = getAccumulatedBatteryUsageStats(stats, query, currentTimeMs);
} else if (query.getAggregatedToTimestamp() == 0) {
BatteryUsageStats.Builder builder = computeBatteryUsageStats(stats, query,
query.getMonotonicStartTime(),
@@ -292,13 +288,9 @@
}
private BatteryUsageStats getAccumulatedBatteryUsageStats(BatteryStatsImpl stats,
- BatteryUsageStatsQuery query) {
+ BatteryUsageStatsQuery query, long currentTimeMs) {
AccumulatedBatteryUsageStats accumulatedStats = loadAccumulatedBatteryUsageStats();
- if (accumulatedStats.endMonotonicTime == MonotonicClock.UNDEFINED
- || mMonotonicClock.monotonicTime() - accumulatedStats.endMonotonicTime
- > query.getMaxStatsAge()) {
- updateAccumulatedBatteryUsageStats(accumulatedStats, stats);
- }
+ updateAccumulatedBatteryUsageStats(accumulatedStats, stats, query);
return accumulatedStats.builder.build();
}
@@ -329,7 +321,7 @@
}
private void updateAccumulatedBatteryUsageStats(AccumulatedBatteryUsageStats accumulatedStats,
- BatteryStatsImpl stats) {
+ BatteryStatsImpl stats, BatteryUsageStatsQuery query) {
long startMonotonicTime = accumulatedStats.endMonotonicTime;
if (startMonotonicTime == MonotonicClock.UNDEFINED) {
startMonotonicTime = stats.getMonotonicStartTime();
@@ -341,7 +333,6 @@
accumulatedStats.builder = new BatteryUsageStats.Builder(
stats.getCustomEnergyConsumerNames(), true, true, true, 0);
accumulatedStats.startWallClockTime = stats.getStartClockTime();
- accumulatedStats.startMonotonicTime = stats.getMonotonicStartTime();
accumulatedStats.builder.setStatsStartTimestamp(accumulatedStats.startWallClockTime);
}
@@ -351,7 +342,7 @@
accumulatedStats.builder.setStatsDuration(endWallClockTime - startMonotonicTime);
mPowerAttributor.estimatePowerConsumption(accumulatedStats.builder, stats.getHistory(),
- startMonotonicTime, endMonotonicTime);
+ startMonotonicTime, MonotonicClock.UNDEFINED);
populateGeneralInfo(accumulatedStats.builder, stats);
}
diff --git a/services/core/java/com/android/server/power/stats/processor/PowerStatsAggregator.java b/services/core/java/com/android/server/power/stats/processor/PowerStatsAggregator.java
index 2609cf7..dcdd3bd 100644
--- a/services/core/java/com/android/server/power/stats/processor/PowerStatsAggregator.java
+++ b/services/core/java/com/android/server/power/stats/processor/PowerStatsAggregator.java
@@ -23,7 +23,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BatteryStatsHistory;
import com.android.internal.os.BatteryStatsHistoryIterator;
-import com.android.internal.os.MonotonicClock;
import java.util.function.Consumer;
@@ -170,9 +169,6 @@
}
}
}
- if (endTimeMs != MonotonicClock.UNDEFINED) {
- lastTime = endTimeMs;
- }
if (lastTime > baseTime) {
mStats.setDuration(lastTime - baseTime);
mStats.finish(lastTime);
diff --git a/services/core/java/com/android/server/wm/ActivitySnapshotController.java b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
index 24ed1bb..57a0bb5 100644
--- a/services/core/java/com/android/server/wm/ActivitySnapshotController.java
+++ b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
@@ -18,6 +18,8 @@
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static com.android.server.wm.SnapshotPersistQueue.MAX_STORE_QUEUE_DEPTH;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -343,6 +345,11 @@
if (DEBUG) {
Slog.d(TAG, "ActivitySnapshotController#recordSnapshot " + activity);
}
+ if (mPersister.mSnapshotPersistQueue.peekWriteQueueSize() >= MAX_STORE_QUEUE_DEPTH
+ || mPersister.mSnapshotPersistQueue.peekQueueSize() > MAX_PERSIST_SNAPSHOT_COUNT) {
+ Slog.w(TAG, "Skipping recording activity snapshot, too many requests!");
+ return;
+ }
final int size = activity.size();
final int[] mixedCode = new int[size];
if (size == 1) {
@@ -432,7 +439,7 @@
addBelowActivityIfExist(ar, mPendingLoadActivity, false, "load-snapshot");
} else {
// remove the snapshot for the one below close
- addBelowActivityIfExist(ar, mPendingRemoveActivity, true, "remove-snapshot");
+ addBelowActivityIfExist(ar, mPendingRemoveActivity, false, "remove-snapshot");
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 90d3834..2781592 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -27,6 +27,7 @@
import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.ActivityManager.isStartResultSuccessful;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
import static android.app.PendingIntent.FLAG_ONE_SHOT;
@@ -891,7 +892,10 @@
final ActivityOptions originalOptions = mRequest.activityOptions != null
? mRequest.activityOptions.getOriginalOptions() : null;
// Only track the launch time of activity that will be resumed.
- launchingRecord = mDoResume ? mLastStartActivityRecord : null;
+ if (mDoResume || (isStartResultSuccessful(res)
+ && mLastStartActivityRecord.getTask().isVisibleRequested())) {
+ launchingRecord = mLastStartActivityRecord;
+ }
// If the new record is the one that started, a new activity has created.
final boolean newActivityCreated = mStartActivity == launchingRecord;
// Notify ActivityMetricsLogger that the activity has launched.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 0ebdaed..afa7ea1 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1555,7 +1555,8 @@
final ActivityRecord[] outActivity = new ActivityRecord[1];
- getActivityStartController().obtainStarter(intent, "dream")
+ final int res = getActivityStartController()
+ .obtainStarter(intent, "dream")
.setCallingUid(callingUid)
.setCallingPid(callingPid)
.setCallingPackage(intent.getPackage())
@@ -1569,9 +1570,11 @@
.execute();
final ActivityRecord started = outActivity[0];
- final IAppTask appTask = started == null ? null :
- new AppTaskImpl(this, started.getTask().mTaskId, callingUid);
- return appTask;
+ if (started == null || !ActivityManager.isStartResultSuccessful(res)) {
+ // start the dream activity failed.
+ return null;
+ }
+ return new AppTaskImpl(this, started.getTask().mTaskId, callingUid);
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0b66158..c2141a7 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -260,6 +260,7 @@
import com.android.server.wm.utils.RegionUtils;
import com.android.server.wm.utils.RotationCache;
import com.android.server.wm.utils.WmDisplayCutout;
+import com.android.window.flags.Flags;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -1390,11 +1391,16 @@
mTokenMap.put(binder, token);
if (token.asActivityRecord() == null) {
- // Set displayContent for non-app token to prevent same token will add twice after
- // onDisplayChanged.
- // TODO: Check if it's fine that super.onDisplayChanged of WindowToken
- // (WindowsContainer#onDisplayChanged) may skipped when token.mDisplayContent assigned.
- token.mDisplayContent = this;
+ // Setting the mDisplayContent to the token is not needed: it is done by da.addChild
+ // below, that also calls onDisplayChanged once moved.
+ if (!Flags.reparentWindowTokenApi()) {
+ // Set displayContent for non-app token to prevent same token will add twice after
+ // onDisplayChanged.
+ // TODO: Check if it's fine that super.onDisplayChanged of WindowToken
+ // (WindowsContainer#onDisplayChanged) may skipped when token.mDisplayContent
+ // assigned.
+ token.mDisplayContent = this;
+ }
// Add non-app token to container hierarchy on the display. App tokens are added through
// the parent container managing them (e.g. Tasks).
final DisplayArea.Tokens da = findAreaForToken(token).asTokens();
diff --git a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
index 8b63ecf7..a545454 100644
--- a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
+++ b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
@@ -50,7 +50,7 @@
class SnapshotPersistQueue {
private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskSnapshotPersister" : TAG_WM;
private static final long DELAY_MS = 100;
- private static final int MAX_STORE_QUEUE_DEPTH = 2;
+ static final int MAX_STORE_QUEUE_DEPTH = 2;
private static final int COMPRESS_QUALITY = 95;
@GuardedBy("mLock")
@@ -154,7 +154,12 @@
}
}
- @VisibleForTesting
+ int peekWriteQueueSize() {
+ synchronized (mLock) {
+ return mStoreQueueItems.size();
+ }
+ }
+
int peekQueueSize() {
synchronized (mLock) {
return mWriteQueue.size();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 4ed1206..c8befb2 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -3864,6 +3864,9 @@
if (mLaunchAdjacentDisabled) {
pw.println(prefix + "mLaunchAdjacentDisabled=true");
}
+ if (mReparentLeafTaskIfRelaunch) {
+ pw.println(prefix + "mReparentLeafTaskIfRelaunch=true");
+ }
}
@Override
@@ -4489,7 +4492,7 @@
}
void onPictureInPictureParamsChanged() {
- if (inPinnedWindowingMode()) {
+ if (inPinnedWindowingMode() || Flags.enableDesktopWindowingPip()) {
dispatchTaskInfoChangedIfNeeded(true /* force */);
}
}
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 2c71c1a..c1a33c4 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -31,6 +31,7 @@
import static android.view.Display.INVALID_DISPLAY;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_ORIENTATION;
+import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_TASKS;
import static com.android.server.wm.ActivityRecord.State.RESUMED;
import static com.android.server.wm.ActivityTaskManagerService.TAG_ROOT_TASK;
import static com.android.server.wm.DisplayContent.alwaysCreateRootTask;
@@ -918,6 +919,10 @@
if (candidateTask.getParent() == null) {
addChild(candidateTask, position);
} else {
+ if (candidateTask.getRootTask().mReparentLeafTaskIfRelaunch) {
+ ProtoLog.d(WM_DEBUG_TASKS, "Reparenting to display area on relaunch: "
+ + "rootTaskId=%d toTop=%b", candidateTask.mTaskId, onTop);
+ }
candidateTask.reparent(this, onTop);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java
index 809745e..6d0da1f 100644
--- a/services/core/java/com/android/server/wm/WindowContextListenerController.java
+++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java
@@ -167,6 +167,22 @@
return true;
}
+ boolean assertCallerCanReparentListener(@NonNull IBinder clientToken,
+ boolean callerCanManageAppTokens, int callingUid, int displayId) {
+ if (!assertCallerCanModifyListener(clientToken, callerCanManageAppTokens, callingUid)) {
+ return false;
+ }
+
+ final WindowContainer<?> container = getContainer(clientToken);
+ if (container != null && container.getDisplayContent() != null
+ && container.getDisplayContent().mDisplayId == displayId) {
+ ProtoLog.i(WM_DEBUG_ADD_REMOVE,
+ "The listener has already been attached to the same display id");
+ return false;
+ }
+ return true;
+ }
+
boolean hasListener(IBinder clientToken) {
return mListeners.containsKey(clientToken);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b42ce64f..0b6ca75 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -358,6 +358,7 @@
import com.android.server.power.ShutdownThread;
import com.android.server.utils.PriorityDump;
import com.android.server.wallpaper.WallpaperCropper.WallpaperCropUtils;
+import com.android.window.flags.Flags;
import dalvik.annotation.optimization.NeverCompile;
@@ -3042,6 +3043,81 @@
}
}
+ @Override
+ public boolean reparentWindowContextToDisplayArea(
+ @NonNull IApplicationThread appThread, @NonNull IBinder clientToken, int displayId) {
+ if (!Flags.reparentWindowTokenApi()) {
+ return false;
+ }
+ Objects.requireNonNull(appThread);
+ Objects.requireNonNull(clientToken);
+ final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
+ "reparentWindowContextToDisplayArea", false /* printLog */);
+ final int callingPid = Binder.getCallingPid();
+ final int callingUid = Binder.getCallingUid();
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final WindowProcessController wpc = mAtmService.getProcessController(appThread);
+ if (wpc == null) {
+ ProtoLog.w(WM_ERROR, "reparentWindowContextToDisplayArea: calling from"
+ + " non-existing process pid=%d uid=%d", callingPid, callingUid);
+ return false;
+ }
+ final DisplayContent dc = mRoot.getDisplayContentOrCreate(displayId);
+ if (dc == null) {
+ ProtoLog.w(WM_ERROR, "reparentWindowContextToDisplayArea: trying to attach"
+ + " to a non-existing display:%d", displayId);
+ return false;
+ }
+
+ if (!mWindowContextListenerController.assertCallerCanReparentListener(clientToken,
+ callerCanManageAppTokens, callingUid, displayId)) {
+ return false;
+ }
+ final WindowContainer<?> container = mWindowContextListenerController.getContainer(
+ clientToken);
+
+ final WindowToken token = container != null ? container.asWindowToken() : null;
+ if (token != null && token.isFromClient()) {
+ ProtoLog.d(WM_DEBUG_ADD_REMOVE, "Reparenting from dc to displayId=%d",
+ displayId);
+ // Reparent the window created for this window context.
+ dc.reParentWindowToken(token);
+ hideUntilNextDraw(token);
+ // This makes sure there is a traversal scheduled that will eventually report
+ // the window resize to the client.
+ dc.setLayoutNeeded();
+ requestTraversal();
+ return true;
+ }
+
+ final int type = mWindowContextListenerController.getWindowType(clientToken);
+ final Bundle options = mWindowContextListenerController.getOptions(clientToken);
+ // No window yet, switch listening DA.
+ final DisplayArea<?> da = dc.findAreaForWindowType(type, options,
+ callerCanManageAppTokens, false /* roundedCornerOverlay */);
+ mWindowContextListenerController.registerWindowContainerListener(wpc, clientToken,
+ da, type, options, true /* shouldDispatchConfigWhenRegistering */);
+ return true;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ private void hideUntilNextDraw(@NonNull WindowToken token) {
+ final WindowState topChild = token.getTopChild();
+ if (topChild != null) {
+ mTransactionFactory.get().hide(token.mSurfaceControl).apply();
+ topChild.applyWithNextDraw(t -> {
+ if (token.mSurfaceControl != null) {
+ t.show(token.mSurfaceControl);
+ }
+ });
+ }
+ }
+
/** Returns {@code true} if this binder is a registered window token. */
@Override
public boolean isWindowToken(IBinder binder) {
@@ -9020,16 +9096,19 @@
clearPointerDownOutsideFocusRunnable();
+ final InputTarget focusedInputTarget = mFocusedInputTarget;
if (shouldDelayTouchOutside(t)) {
- mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
+ mPointerDownOutsideFocusRunnable =
+ () -> handlePointerDownOutsideFocus(t, focusedInputTarget);
mH.postDelayed(mPointerDownOutsideFocusRunnable, POINTER_DOWN_OUTSIDE_FOCUS_TIMEOUT_MS);
} else if (!fromHandler) {
// Still post the runnable to handler thread in case there is already a runnable
// in execution, but still waiting to hold the wm lock.
- mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
+ mPointerDownOutsideFocusRunnable =
+ () -> handlePointerDownOutsideFocus(t, focusedInputTarget);
mH.post(mPointerDownOutsideFocusRunnable);
} else {
- handlePointerDownOutsideFocus(t);
+ handlePointerDownOutsideFocus(t, focusedInputTarget);
}
}
@@ -9061,8 +9140,15 @@
return shouldDelayTouchForEmbeddedActivity || shouldDelayTouchForFreeform;
}
- private void handlePointerDownOutsideFocus(InputTarget t) {
+ private void handlePointerDownOutsideFocus(InputTarget t, InputTarget focusedInputTarget) {
synchronized (mGlobalLock) {
+ if (mFocusedInputTarget != focusedInputTarget) {
+ // Skip if the mFocusedInputTarget is already changed. This is possible if the
+ // pointer-down-outside-focus event is delayed to be handled.
+ ProtoLog.i(WM_DEBUG_FOCUS_LIGHT,
+ "Skip onPointerDownOutsideFocusLocked due to input target changed %s", t);
+ return;
+ }
if (mPointerDownOutsideFocusRunnable != null
&& mH.hasCallbacks(mPointerDownOutsideFocusRunnable)) {
// Skip if there's another pending pointer-down-outside-focus event.
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 832295a..cca73c57 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -49,6 +49,7 @@
import com.android.internal.protolog.ProtoLog;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.window.flags.Flags;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -386,7 +387,15 @@
@Override
void onDisplayChanged(DisplayContent dc) {
- dc.reParentWindowToken(this);
+ if (!Flags.reparentWindowTokenApi()) {
+ dc.reParentWindowToken(this);
+ } else {
+ // This check is needed to break recursion, as DisplayContent#reparentWindowToken also
+ // triggers a WindowToken#onDisplayChanged.
+ if (dc.getWindowToken(token) == null) {
+ dc.reParentWindowToken(this);
+ }
+ }
// TODO(b/36740756): One day this should perhaps be hooked
// up with goodToGo, so we don't move a window
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 4d318f90..2627895 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -9089,7 +9089,7 @@
CallerIdentity caller = getCallerIdentity(who);
if (Flags.setAutoTimeEnabledCoexistence()) {
- Preconditions.checkCallAuthorization(hasPermission(SET_TIME, caller.getPackageName()));
+ Preconditions.checkCallAuthorization(hasPermission(SET_TIME, callerPackageName));
} else {
Objects.requireNonNull(who, "ComponentName is null");
Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller)
@@ -9152,7 +9152,7 @@
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
/* who */ null,
SET_TIME,
- caller.getPackageName(),
+ callerPackageName,
UserHandle.USER_ALL
);
Integer state = mDevicePolicyEngine.getGlobalPolicySetByAdmin(
@@ -9197,7 +9197,7 @@
CallerIdentity caller = getCallerIdentity(who);
if (Flags.setAutoTimeZoneEnabledCoexistence()) {
Preconditions.checkCallAuthorization(
- hasPermission(SET_TIME_ZONE, caller.getPackageName()));
+ hasPermission(SET_TIME_ZONE, callerPackageName));
} else {
Objects.requireNonNull(who, "ComponentName is null");
Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller)
@@ -9255,7 +9255,7 @@
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
/* who */ null,
SET_TIME_ZONE,
- caller.getPackageName(),
+ callerPackageName,
UserHandle.USER_ALL
);
Integer state = mDevicePolicyEngine.getGlobalPolicySetByAdmin(
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 65315af..92dbf63 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2933,7 +2933,7 @@
t.traceEnd();
// UprobeStats DynamicInstrumentationManager
- if (com.android.art.flags.Flags.executableMethodFileOffsets()) {
+ if (android.uprobestats.flags.Flags.executableMethodFileOffsets()) {
t.traceBegin("StartDynamicInstrumentationManager");
mSystemServiceManager.startService(DynamicInstrumentationManagerService.class);
t.traceEnd();
diff --git a/services/java/com/android/server/flags.aconfig b/services/java/com/android/server/flags.aconfig
index 4412968..0d222fb 100644
--- a/services/java/com/android/server/flags.aconfig
+++ b/services/java/com/android/server/flags.aconfig
@@ -10,14 +10,6 @@
}
flag {
- name: "remove_java_service_manager_cache"
- namespace: "system_performance"
- description: "This flag turns off Java's Service Manager caching mechanism."
- bug: "333854840"
- is_fixed_read_only: true
-}
-
-flag {
name: "remove_text_service"
namespace: "wear_frameworks"
description: "Remove TextServiceManagerService on Wear"
diff --git a/services/tests/DynamicInstrumentationManagerServiceTests/src/com/android/server/os/instrumentation/ParseMethodDescriptorTest.java b/services/tests/DynamicInstrumentationManagerServiceTests/src/com/android/server/os/instrumentation/ParseMethodDescriptorTest.java
index 5492ba6..6e14bad 100644
--- a/services/tests/DynamicInstrumentationManagerServiceTests/src/com/android/server/os/instrumentation/ParseMethodDescriptorTest.java
+++ b/services/tests/DynamicInstrumentationManagerServiceTests/src/com/android/server/os/instrumentation/ParseMethodDescriptorTest.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertThrows;
import android.os.instrumentation.MethodDescriptor;
+import android.os.instrumentation.MethodDescriptorParser;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
@@ -37,7 +38,7 @@
/**
* Test class for
- * {@link DynamicInstrumentationManagerService#parseMethodDescriptor(ClassLoader,
+ * {@link MethodDescriptorParser#parseMethodDescriptor(ClassLoader,
* MethodDescriptor)}.
* <p>
* Build/Install/Run:
@@ -119,13 +120,13 @@
}
private Method parseMethodDescriptor(String fqcn, String methodName) {
- return DynamicInstrumentationManagerService.parseMethodDescriptor(
+ return MethodDescriptorParser.parseMethodDescriptor(
getClass().getClassLoader(),
getMethodDescriptor(fqcn, methodName, new String[]{}));
}
private Method parseMethodDescriptor(String fqcn, String methodName, String[] fqParameters) {
- return DynamicInstrumentationManagerService.parseMethodDescriptor(
+ return MethodDescriptorParser.parseMethodDescriptor(
getClass().getClassLoader(),
getMethodDescriptor(fqcn, methodName, fqParameters));
}
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/BroadcastHelperTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/BroadcastHelperTest.java
index acd34e3..0ae7699 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/BroadcastHelperTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/BroadcastHelperTest.java
@@ -233,6 +233,6 @@
mBroadcastHelper.sendPackageChangedBroadcast(mMockSnapshot,
PACKAGE_CHANGED_TEST_PACKAGE_NAME, true /* dontKillApp */, componentNames,
- UserHandle.USER_SYSTEM, "test" /* reason */);
+ UserHandle.USER_SYSTEM, "test" /* reason */, "test" /* reasonForTrace */);
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt
index de029e0..90e1263 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt
@@ -56,8 +56,8 @@
testHandler.flush()
verify(pms).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
- verify(broadcastHelper).sendDistractingPackagesChanged(any(Computer::class.java),
- pkgListCaptor.capture(), any(), any(), flagsCaptor.capture())
+ verify(broadcastHelper).sendDistractingPackagesChanged(
+ any(), pkgListCaptor.capture(), any(), any(), flagsCaptor.capture())
val modifiedPackages = pkgListCaptor.value
val distractionFlags = flagsCaptor.value
@@ -158,8 +158,7 @@
verify(pms).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
verify(broadcastHelper).sendDistractingPackagesChanged(
- any(Computer::class.java), pkgListCaptor.capture(), any(), eq(TEST_USER_ID),
- flagsCaptor.capture())
+ any(), pkgListCaptor.capture(), any(), eq(TEST_USER_ID), flagsCaptor.capture())
val modifiedPackages = pkgListCaptor.value
val distractionFlags = flagsCaptor.value
assertThat(modifiedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2)
@@ -198,12 +197,12 @@
@Test
fun sendDistractingPackagesChanged() {
- broadcastHelper.sendDistractingPackagesChanged(pms.snapshotComputer(),
+ broadcastHelper.sendDistractingPackagesChanged(pms::snapshotComputer,
packagesToChange, uidsToChange, TEST_USER_ID,
PackageManager.RESTRICTION_HIDE_NOTIFICATIONS)
testHandler.flush()
- verify(broadcastHelper).sendDistractingPackagesChanged(any(Computer::class.java),
- pkgListCaptor.capture(), uidsCaptor.capture(), eq(TEST_USER_ID), any())
+ verify(broadcastHelper).sendDistractingPackagesChanged(
+ any(), pkgListCaptor.capture(), uidsCaptor.capture(), eq(TEST_USER_ID), any())
var changedPackages = pkgListCaptor.value
var changedUids = uidsCaptor.value
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
index 7444403..60e8250 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
@@ -58,8 +58,8 @@
testHandler.flush()
verify(pms).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
- verify(broadcastHelper).sendPackagesSuspendedOrUnsuspendedForUser(any(Computer::class.java),
- eq(Intent.ACTION_PACKAGES_SUSPENDED), pkgListCaptor.capture(), any(), any(), any())
+ verify(broadcastHelper).sendPackagesSuspendedOrUnsuspendedForUser(any(),
+ eq(Intent.ACTION_PACKAGES_SUSPENDED), pkgListCaptor.capture(), any(), any(), any())
var modifiedPackages = pkgListCaptor.value
assertThat(modifiedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2)
@@ -149,11 +149,11 @@
testHandler.flush()
verify(pms, times(2)).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
- verify(broadcastHelper).sendPackagesSuspendedOrUnsuspendedForUser(any(Computer::class.java),
- eq(Intent.ACTION_PACKAGES_UNSUSPENDED), pkgListCaptor.capture(), any(), any(),
- any())
- verify(broadcastHelper).sendMyPackageSuspendedOrUnsuspended(any(Computer::class.java),
- any(), any(), any())
+ verify(broadcastHelper).sendPackagesSuspendedOrUnsuspendedForUser(
+ any(), eq(Intent.ACTION_PACKAGES_UNSUSPENDED),
+ pkgListCaptor.capture(), any(), any(), any())
+ verify(broadcastHelper).sendMyPackageSuspendedOrUnsuspended(
+ any(), any(), any(), any())
var modifiedPackages = pkgListCaptor.value
assertThat(modifiedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2)
@@ -230,10 +230,10 @@
testHandler.flush()
verify(pms, times(2)).scheduleWritePackageRestrictions(eq(TEST_USER_ID))
- verify(broadcastHelper).sendPackagesSuspendedOrUnsuspendedForUser(any(Computer::class.java),
- eq(Intent.ACTION_PACKAGES_UNSUSPENDED), any(), any(), any(), any())
- verify(broadcastHelper).sendMyPackageSuspendedOrUnsuspended(any(Computer::class.java),
- any(), any(), any())
+ verify(broadcastHelper).sendPackagesSuspendedOrUnsuspendedForUser(
+ any(), eq(Intent.ACTION_PACKAGES_UNSUSPENDED), any(), any(), any(), any())
+ verify(broadcastHelper).sendMyPackageSuspendedOrUnsuspended(
+ any(), any(), any(), any())
assertThat(suspendPackageHelper.getSuspendingPackage(pms.snapshotComputer(),
TEST_PACKAGE_1, TEST_USER_ID, deviceOwnerUid)).isNull()
diff --git a/services/tests/ondeviceintelligencetests/Android.bp b/services/tests/ondeviceintelligencetests/Android.bp
index a31a3fb..f235da2 100644
--- a/services/tests/ondeviceintelligencetests/Android.bp
+++ b/services/tests/ondeviceintelligencetests/Android.bp
@@ -44,14 +44,18 @@
"truth",
"frameworks-base-testutils",
"androidx.test.rules",
- ],
+ ] + select(soong_config_variable("ANDROID", "release_ondevice_intelligence_module"), {
+ "true": [
+ "service-ondeviceintelligence.impl",
+ ],
+ default: [],
+ }),
libs: [
"android.test.mock.stubs.system",
"android.test.base.stubs.system",
"android.test.runner.stubs.system",
],
-
certificate: "platform",
platform_apis: true,
test_suites: ["device-tests"],
diff --git a/services/tests/ondeviceintelligencetests/OWNERS b/services/tests/ondeviceintelligencetests/OWNERS
index 09774f7..a4fc758 100644
--- a/services/tests/ondeviceintelligencetests/OWNERS
+++ b/services/tests/ondeviceintelligencetests/OWNERS
@@ -1 +1,3 @@
-file:/core/java/android/app/ondeviceintelligence/OWNERS
+shiqing@google.com
+sandeepbandaru@google.com
+shivanker@google.com
diff --git a/services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java b/services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java
index d12579c..28ccb84 100644
--- a/services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java
+++ b/services/tests/ondeviceintelligencetests/src/com/android/server/ondeviceintelligence/InferenceInfoStoreTest.java
@@ -21,7 +21,6 @@
import android.app.ondeviceintelligence.InferenceInfo;
import android.os.Bundle;
import android.os.PersistableBundle;
-import android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService;
import android.util.Base64;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -38,6 +37,8 @@
public class InferenceInfoStoreTest {
InferenceInfoStore inferenceInfoStore;
+ public static final String INFERENCE_INFO_BUNDLE_KEY = "inference_info";
+
@Before
public void setUp() {
inferenceInfoStore = new InferenceInfoStore(1000);
@@ -46,7 +47,7 @@
@Test
public void testInferenceInfoParsesFromBundleSuccessfully() throws Exception {
Bundle bundle = new Bundle();
- bundle.putByteArray(OnDeviceSandboxedInferenceService.INFERENCE_INFO_BUNDLE_KEY,
+ bundle.putByteArray(INFERENCE_INFO_BUNDLE_KEY,
getInferenceInfoBytes(1, 1, 100));
inferenceInfoStore.addInferenceInfoFromBundle(bundle);
List<InferenceInfo> inferenceInfos = inferenceInfoStore.getLatestInferenceInfo(0);
@@ -59,7 +60,7 @@
@Test
public void testInferenceInfoParsesFromPersistableBundleSuccessfully() throws Exception {
PersistableBundle bundle = new PersistableBundle();
- bundle.putString(OnDeviceSandboxedInferenceService.INFERENCE_INFO_BUNDLE_KEY,
+ bundle.putString(INFERENCE_INFO_BUNDLE_KEY,
Base64.encodeToString(getInferenceInfoBytes(1, 1, 100), Base64.DEFAULT));
inferenceInfoStore.addInferenceInfoFromBundle(bundle);
List<InferenceInfo> inferenceInfos = inferenceInfoStore.getLatestInferenceInfo(0);
@@ -74,11 +75,11 @@
public void testEvictionAfterMaxAge() throws Exception {
PersistableBundle bundle = new PersistableBundle();
long testStartTime = System.currentTimeMillis();
- bundle.putString(OnDeviceSandboxedInferenceService.INFERENCE_INFO_BUNDLE_KEY,
+ bundle.putString(INFERENCE_INFO_BUNDLE_KEY,
Base64.encodeToString(getInferenceInfoBytes(1, testStartTime - 10,
testStartTime + 100), Base64.DEFAULT));
inferenceInfoStore.addInferenceInfoFromBundle(bundle);
- bundle.putString(OnDeviceSandboxedInferenceService.INFERENCE_INFO_BUNDLE_KEY,
+ bundle.putString(INFERENCE_INFO_BUNDLE_KEY,
Base64.encodeToString(getInferenceInfoBytes(1, testStartTime - 5,
testStartTime + 100), Base64.DEFAULT));
inferenceInfoStore.addInferenceInfoFromBundle(bundle);
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 7248833..b166514 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
@@ -64,6 +64,7 @@
import android.os.CpuHeadroomParamsInternal;
import android.os.GpuHeadroomParamsInternal;
import android.os.IBinder;
+import android.os.IHintManager;
import android.os.IHintSession;
import android.os.PerformanceHintManager;
import android.os.Process;
@@ -154,6 +155,8 @@
private ActivityManagerInternal mAmInternalMock;
@Mock
private PackageManager mMockPackageManager;
+ @Mock
+ private IHintManager.IHintManagerClient mClientCallback;
@Rule
public final CheckFlagsRule mCheckFlagsRule =
DeviceFlagsValueProvider.createCheckFlagsRule();
@@ -171,6 +174,23 @@
};
}
+ private SupportInfo makeDefaultSupportInfo() {
+ mSupportInfo = new SupportInfo();
+ mSupportInfo.usesSessions = true;
+ // By default, mark everything as fully supported
+ mSupportInfo.sessionHints = -1;
+ mSupportInfo.sessionModes = -1;
+ mSupportInfo.modes = -1;
+ mSupportInfo.boosts = -1;
+ mSupportInfo.sessionTags = -1;
+ mSupportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
+ mSupportInfo.headroom.isCpuSupported = true;
+ mSupportInfo.headroom.cpuMinIntervalMillis = 2000;
+ mSupportInfo.headroom.isGpuSupported = true;
+ mSupportInfo.headroom.gpuMinIntervalMillis = 2000;
+ return mSupportInfo;
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -181,12 +201,7 @@
mConfig.eventFlagDescriptor = new MQDescriptor<Byte, Byte>();
ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.category = ApplicationInfo.CATEGORY_GAME;
- mSupportInfo = new SupportInfo();
- mSupportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
- mSupportInfo.headroom.isCpuSupported = true;
- mSupportInfo.headroom.cpuMinIntervalMillis = 2000;
- mSupportInfo.headroom.isGpuSupported = true;
- mSupportInfo.headroom.gpuMinIntervalMillis = 2000;
+ mSupportInfo = makeDefaultSupportInfo();
when(mContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockPackageManager.getNameForUid(anyInt())).thenReturn(TEST_APP_NAME);
when(mMockPackageManager.getApplicationInfo(eq(TEST_APP_NAME), anyInt()))
@@ -215,6 +230,7 @@
when(mIPowerMock.getInterfaceVersion()).thenReturn(6);
when(mIPowerMock.getSupportInfo()).thenReturn(mSupportInfo);
when(mIPowerMock.getSessionChannel(anyInt(), anyInt())).thenReturn(mConfig);
+ when(mIPowerMock.getSupportInfo()).thenReturn(mSupportInfo);
LocalServices.removeServiceForTest(ActivityManagerInternal.class);
LocalServices.addService(ActivityManagerInternal.class, mAmInternalMock);
}
@@ -409,8 +425,11 @@
HintManagerService service = createService();
IBinder token = new Binder();
- final int threadCount =
- service.getBinderServiceInstance().getMaxGraphicsPipelineThreadsCount();
+ IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
+ .registerClient(mClientCallback);
+
+ final int threadCount = data.maxGraphicsPipelineThreads;
+
long sessionPtr1 = 1111L;
long sessionId1 = 11111L;
CountDownLatch stopLatch1 = new CountDownLatch(1);
@@ -1400,4 +1419,67 @@
verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams1));
verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams2));
}
+
+ @Test
+ public void testRegisteringClient() throws Exception {
+ HintManagerService service = createService();
+ IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
+ .registerClient(mClientCallback);
+ assertNotNull(data);
+ assertEquals(data.supportInfo, mSupportInfo);
+ }
+
+ @Test
+ public void testRegisteringClientOnV4() throws Exception {
+ when(mIPowerMock.getInterfaceVersion()).thenReturn(4);
+ HintManagerService service = createService();
+ IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
+ .registerClient(mClientCallback);
+ assertNotNull(data);
+ assertEquals(data.supportInfo.usesSessions, true);
+ assertEquals(data.supportInfo.boosts, 0);
+ assertEquals(data.supportInfo.modes, 0);
+ assertEquals(data.supportInfo.sessionHints, 31);
+ assertEquals(data.supportInfo.sessionModes, 0);
+ assertEquals(data.supportInfo.sessionTags, 0);
+ assertEquals(data.powerHalVersion, 4);
+ assertEquals(data.preferredRateNanos, DEFAULT_HINT_PREFERRED_RATE);
+ }
+
+ @Test
+ public void testRegisteringClientOnV5() throws Exception {
+ when(mIPowerMock.getInterfaceVersion()).thenReturn(5);
+ HintManagerService service = createService();
+ IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
+ .registerClient(mClientCallback);
+ assertNotNull(data);
+ assertEquals(data.supportInfo.usesSessions, true);
+ assertEquals(data.supportInfo.boosts, 0);
+ assertEquals(data.supportInfo.modes, 0);
+ assertEquals(data.supportInfo.sessionHints, 255);
+ assertEquals(data.supportInfo.sessionModes, 1);
+ assertEquals(data.supportInfo.sessionTags, 31);
+ assertEquals(data.powerHalVersion, 5);
+ assertEquals(data.preferredRateNanos, DEFAULT_HINT_PREFERRED_RATE);
+ }
+
+ @Test
+ public void testSettingUpOldClientWhenUnsupported() throws Exception {
+ when(mIPowerMock.getInterfaceVersion()).thenReturn(5);
+ // Mock unsupported to modify the default support behavior
+ when(mNativeWrapperMock.halGetHintSessionPreferredRate())
+ .thenReturn(-1L);
+ HintManagerService service = createService();
+ IHintManager.HintManagerClientData data = service.getBinderServiceInstance()
+ .registerClient(mClientCallback);
+ assertNotNull(data);
+ assertEquals(data.supportInfo.usesSessions, false);
+ assertEquals(data.supportInfo.boosts, 0);
+ assertEquals(data.supportInfo.modes, 0);
+ assertEquals(data.supportInfo.sessionHints, 0);
+ assertEquals(data.supportInfo.sessionModes, 0);
+ assertEquals(data.supportInfo.sessionTags, 0);
+ assertEquals(data.powerHalVersion, 5);
+ assertEquals(data.preferredRateNanos, -1);
+ }
}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
index 73dcfe7..709f83b 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
@@ -36,7 +36,6 @@
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.ConditionVariable;
-import android.os.Handler;
import android.os.Parcel;
import android.os.Process;
import android.os.UidBatteryConsumer;
@@ -82,9 +81,8 @@
.setAveragePower(PowerProfile.POWER_BATTERY_CAPACITY, 4000.0);
private MockClock mMockClock = mStatsRule.getMockClock();
- private MonotonicClock mMonotonicClock = mStatsRule.getMonotonicClock();
+ private MonotonicClock mMonotonicClock = new MonotonicClock(666777, mMockClock);
private Context mContext;
- private PowerStatsStore mPowerStatsStore;
@Before
public void setup() throws IOException {
@@ -95,9 +93,6 @@
} else {
mContext = InstrumentationRegistry.getContext();
}
- mPowerStatsStore = spy(new PowerStatsStore(
- new File(mStatsRule.getHistoryDir(), getClass().getSimpleName()),
- mStatsRule.getHandler()));
}
@Test
@@ -279,7 +274,10 @@
powerAttributor.setPowerComponentSupported(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT,
true);
- BatteryUsageStatsProvider provider = createBatteryUsageStatsProvider(0);
+ BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(mContext,
+ powerAttributor, mStatsRule.getPowerProfile(),
+ mStatsRule.getCpuScalingPolicies(), mock(PowerStatsStore.class), 0, mMockClock,
+ mMonotonicClock);
return provider.getBatteryUsageStats(batteryStats, BatteryUsageStatsQuery.DEFAULT);
}
@@ -333,30 +331,30 @@
BatteryStats.HistoryItem item;
assertThat(item = iterator.next()).isNotNull();
- assertHistoryItem(batteryStats, item,
+ assertHistoryItem(item,
BatteryStats.HistoryItem.CMD_RESET, BatteryStats.HistoryItem.EVENT_NONE,
null, 0, 3_600_000, 90, 1_000_000);
assertThat(item = iterator.next()).isNotNull();
- assertHistoryItem(batteryStats, item,
+ assertHistoryItem(item,
BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE,
null, 0, 3_600_000, 90, 1_000_000);
assertThat(item.states & BatteryStats.HistoryItem.STATE_CPU_RUNNING_FLAG).isNotEqualTo(0);
assertThat(item = iterator.next()).isNotNull();
- assertHistoryItem(batteryStats, item,
+ assertHistoryItem(item,
BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE,
null, 0, 3_600_000, 90, 2_000_000);
assertThat(item.states & BatteryStats.HistoryItem.STATE_CPU_RUNNING_FLAG).isEqualTo(0);
assertThat(item = iterator.next()).isNotNull();
- assertHistoryItem(batteryStats, item,
+ assertHistoryItem(item,
BatteryStats.HistoryItem.CMD_UPDATE,
BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_START,
"foo", APP_UID, 3_600_000, 90, 3_000_000);
assertThat(item = iterator.next()).isNotNull();
- assertHistoryItem(batteryStats, item,
+ assertHistoryItem(item,
BatteryStats.HistoryItem.CMD_UPDATE,
BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_FINISH,
"foo", APP_UID, 3_600_000, 90, 3_001_000);
@@ -443,15 +441,14 @@
assertThat(item.eventTag.string).startsWith(uid + " ");
assertThat(item.batteryChargeUah).isEqualTo(3_600_000);
assertThat(item.batteryLevel).isEqualTo(90);
- assertThat(item.time).isEqualTo(batteryStats.getMonotonicStartTime() + 1_000_000);
+ assertThat(item.time).isEqualTo((long) 1_000_000);
}
assertThat(expectedUid).isEqualTo(200);
}
- private void assertHistoryItem(MockBatteryStatsImpl batteryStats, BatteryStats.HistoryItem item,
- int command, int eventCode, String tag, int uid, int batteryChargeUah, int batteryLevel,
- long elapsedTimeMs) {
+ private void assertHistoryItem(BatteryStats.HistoryItem item, int command, int eventCode,
+ String tag, int uid, int batteryChargeUah, int batteryLevel, long elapsedTimeMs) {
assertThat(item.cmd).isEqualTo(command);
assertThat(item.eventCode).isEqualTo(eventCode);
if (tag == null) {
@@ -463,7 +460,7 @@
assertThat(item.batteryChargeUah).isEqualTo(batteryChargeUah);
assertThat(item.batteryLevel).isEqualTo(batteryLevel);
- assertThat(item.time).isEqualTo(batteryStats.getMonotonicStartTime() + elapsedTimeMs);
+ assertThat(item.time).isEqualTo(elapsedTimeMs);
}
@Test
@@ -569,66 +566,38 @@
assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
assertThat(stats.getStatsEndTimestamp()).isEqualTo(55 * MINUTE_IN_MS);
- assertBatteryConsumer(stats, 180.0, (10 + 20) * MINUTE_IN_MS);
- assertBatteryConsumer(stats, APP_UID, 180.0, (10 + 20) * MINUTE_IN_MS);
+ assertThat(stats.getAggregateBatteryConsumer(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
+ .getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
+ .isWithin(0.0001)
+ .of(180.0); // 360 mA * 0.5 hours
+ assertThat(stats.getAggregateBatteryConsumer(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
+ .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
+ .isEqualTo((10 + 20) * MINUTE_IN_MS);
+ final UidBatteryConsumer uidBatteryConsumer = stats.getUidBatteryConsumers().stream()
+ .filter(uid -> uid.getUid() == APP_UID).findFirst().get();
+ assertThat(uidBatteryConsumer
+ .getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
+ .isWithin(0.1)
+ .of(180.0);
stats.close();
}
@Test
public void accumulateBatteryUsageStats() throws Throwable {
- MockBatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
- accumulateBatteryUsageStats(batteryStats, 10000000, 0);
+ accumulateBatteryUsageStats(10000000, 1);
// Accumulate every 200 bytes of battery history
- accumulateBatteryUsageStats(batteryStats, 200, 2);
- accumulateBatteryUsageStats(batteryStats, 50, 4);
+ accumulateBatteryUsageStats(200, 2);
+ accumulateBatteryUsageStats(50, 5);
// Accumulate on every invocation of accumulateBatteryUsageStats
- accumulateBatteryUsageStats(batteryStats, 0, 7);
+ accumulateBatteryUsageStats(0, 7);
}
- @Test
- public void getAccumulatedBatteryUsageStats() throws Throwable {
- MockBatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
-
- // Only accumulate the first 25 minutes
- accumulateBatteryUsageStats(batteryStats, 200, 1);
-
- BatteryUsageStatsProvider batteryUsageStatsProvider = createBatteryUsageStatsProvider(200);
-
- // At this point the last stored accumulated stats are `115 - 30 = 85` minutes old
- BatteryUsageStats stats = batteryUsageStatsProvider.getBatteryUsageStats(batteryStats,
- new BatteryUsageStatsQuery.Builder()
- .accumulated()
- .setMaxStatsAgeMs(90 * MINUTE_IN_MS)
- .build());
-
- assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
- assertThat(stats.getStatsEndTimestamp()).isEqualTo(30 * MINUTE_IN_MS);
- assertBatteryConsumer(stats, 60.0, 10 * MINUTE_IN_MS);
- assertBatteryConsumer(stats, APP_UID, 60.0, 10 * MINUTE_IN_MS);
-
- stats.close();
-
- // Now force the usage stats to catch up to the current time
- stats = batteryUsageStatsProvider.getBatteryUsageStats(batteryStats,
- new BatteryUsageStatsQuery.Builder()
- .accumulated()
- .setMaxStatsAgeMs(5 * MINUTE_IN_MS)
- .build());
-
- assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
- assertThat(stats.getStatsEndTimestamp()).isEqualTo(115 * MINUTE_IN_MS);
- assertBatteryConsumer(stats, 360.0, 60 * MINUTE_IN_MS);
- assertBatteryConsumer(stats, APP_UID, 360.0, 60 * MINUTE_IN_MS);
-
- stats.close();
- }
-
- private void accumulateBatteryUsageStats(MockBatteryStatsImpl batteryStatsImpl,
- int accumulatedBatteryUsageStatsSpanSize, int expectedNumberOfUpdates)
- throws Throwable {
- Handler handler = mStatsRule.getHandler();
- MockBatteryStatsImpl batteryStats = spy(batteryStatsImpl);
+ private void accumulateBatteryUsageStats(int accumulatedBatteryUsageStatsSpanSize,
+ int expectedNumberOfUpdates) throws Throwable {
+ BatteryStatsImpl batteryStats = spy(mStatsRule.getBatteryStats());
// Note - these two are in microseconds
when(batteryStats.computeBatteryTimeRemaining(anyLong())).thenReturn(111_000L);
when(batteryStats.computeChargeTimeRemaining(anyLong())).thenReturn(777_000L);
@@ -641,76 +610,82 @@
batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND);
}
- mPowerStatsStore.reset();
+ PowerStatsStore powerStatsStore = spy(new PowerStatsStore(
+ new File(mStatsRule.getHistoryDir(), getClass().getSimpleName()),
+ mStatsRule.getHandler()));
+ powerStatsStore.reset();
int[] count = new int[1];
doAnswer(inv -> {
count[0]++;
- return inv.callRealMethod();
- }).when(mPowerStatsStore).storePowerStatsSpan(any(PowerStatsSpan.class));
+ return null;
+ }).when(powerStatsStore).storePowerStatsSpan(any(PowerStatsSpan.class));
- BatteryUsageStatsProvider batteryUsageStatsProvider = createBatteryUsageStatsProvider(
- accumulatedBatteryUsageStatsSpanSize);
+ MultiStatePowerAttributor powerAttributor = new MultiStatePowerAttributor(mContext,
+ powerStatsStore, mStatsRule.getPowerProfile(), mStatsRule.getCpuScalingPolicies(),
+ () -> 3500);
+ for (int powerComponentId = 0; powerComponentId < BatteryConsumer.POWER_COMPONENT_COUNT;
+ powerComponentId++) {
+ powerAttributor.setPowerComponentSupported(powerComponentId, true);
+ }
+ powerAttributor.setPowerComponentSupported(BatteryConsumer.POWER_COMPONENT_ANY, true);
- batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
+ BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(mContext,
+ powerAttributor, mStatsRule.getPowerProfile(),
+ mStatsRule.getCpuScalingPolicies(), powerStatsStore,
+ accumulatedBatteryUsageStatsSpanSize, mMockClock, mMonotonicClock);
- setTime(10 * MINUTE_IN_MS);
+ provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());
+
synchronized (batteryStats) {
batteryStats.noteFlashlightOnLocked(APP_UID,
10 * MINUTE_IN_MS, 10 * MINUTE_IN_MS);
}
- batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
+ provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());
- setTime(20 * MINUTE_IN_MS);
synchronized (batteryStats) {
batteryStats.noteFlashlightOffLocked(APP_UID,
20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
}
- batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
+ provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());
- setTime(30 * MINUTE_IN_MS);
synchronized (batteryStats) {
batteryStats.noteFlashlightOnLocked(APP_UID,
30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS);
}
- batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
+ provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());
- // Make sure the accumulated stats are computed and saved before generating more history
- mStatsRule.waitForBackgroundThread();
-
- setTime(50 * MINUTE_IN_MS);
synchronized (batteryStats) {
batteryStats.noteFlashlightOffLocked(APP_UID,
50 * MINUTE_IN_MS, 50 * MINUTE_IN_MS);
}
setTime(55 * MINUTE_IN_MS);
- batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
+ provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());
// This section has not been saved yet, but should be added to the accumulated totals
- setTime(80 * MINUTE_IN_MS);
synchronized (batteryStats) {
batteryStats.noteFlashlightOnLocked(APP_UID,
80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
}
- batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
+ provider.accumulateBatteryUsageStatsAsync(batteryStats, mStatsRule.getHandler());
- setTime(110 * MINUTE_IN_MS);
synchronized (batteryStats) {
batteryStats.noteFlashlightOffLocked(APP_UID,
110 * MINUTE_IN_MS, 110 * MINUTE_IN_MS);
}
setTime(115 * MINUTE_IN_MS);
- batteryUsageStatsProvider.accumulateBatteryUsageStatsAsync(batteryStats, handler);
+ // Pick up the remainder of battery history that has not yet been accumulated
+ provider.accumulateBatteryUsageStats(batteryStats);
mStatsRule.waitForBackgroundThread();
- BatteryUsageStats stats = batteryUsageStatsProvider.getBatteryUsageStats(batteryStats,
+ BatteryUsageStats stats = provider.getBatteryUsageStats(batteryStats,
new BatteryUsageStatsQuery.Builder().accumulated().build());
assertThat(stats.getStatsStartTimestamp()).isEqualTo(5 * MINUTE_IN_MS);
@@ -721,55 +696,29 @@
assertThat(stats.getBatteryCapacity()).isEqualTo(4000); // from PowerProfile
// Total: 10 + 20 + 30 = 60
- assertBatteryConsumer(stats, 360.0, 60 * MINUTE_IN_MS);
- assertBatteryConsumer(stats, APP_UID, 360.0, 60 * MINUTE_IN_MS);
- stats.close();
-
- mStatsRule.waitForBackgroundThread();
-
- assertThat(count[0]).isEqualTo(expectedNumberOfUpdates);
- }
-
- private BatteryUsageStatsProvider createBatteryUsageStatsProvider(
- int accumulatedBatteryUsageStatsSpanSize) {
- MultiStatePowerAttributor powerAttributor = new MultiStatePowerAttributor(mContext,
- mPowerStatsStore, mStatsRule.getPowerProfile(), mStatsRule.getCpuScalingPolicies(),
- () -> 3500);
- for (int powerComponentId = 0; powerComponentId < BatteryConsumer.POWER_COMPONENT_COUNT;
- powerComponentId++) {
- powerAttributor.setPowerComponentSupported(powerComponentId, true);
- }
- powerAttributor.setPowerComponentSupported(BatteryConsumer.POWER_COMPONENT_ANY, true);
-
- return new BatteryUsageStatsProvider(mContext, powerAttributor,
- mStatsRule.getPowerProfile(), mStatsRule.getCpuScalingPolicies(), mPowerStatsStore,
- accumulatedBatteryUsageStatsSpanSize, mMockClock, mMonotonicClock);
- }
-
- private static void assertBatteryConsumer(BatteryUsageStats stats, double expectedPowerMah,
- long expectedDurationMs) {
- AggregateBatteryConsumer aggregatedConsumer = stats.getAggregateBatteryConsumer(
- BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
- assertThat(aggregatedConsumer
+ assertThat(stats.getAggregateBatteryConsumer(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
.getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
.isWithin(0.0001)
- .of(expectedPowerMah);
- assertThat(aggregatedConsumer
+ .of(360.0); // 360 mA * 1.0 hour
+ assertThat(stats.getAggregateBatteryConsumer(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
- .isEqualTo(expectedDurationMs);
- }
+ .isEqualTo(60 * MINUTE_IN_MS);
- private static void assertBatteryConsumer(BatteryUsageStats stats, int uid,
- double expectedPowerMah, long expectedDurationMs) {
final UidBatteryConsumer uidBatteryConsumer = stats.getUidBatteryConsumers().stream()
- .filter(u -> u.getUid() == uid).findFirst().get();
+ .filter(uid -> uid.getUid() == APP_UID).findFirst().get();
assertThat(uidBatteryConsumer
.getConsumedPower(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
.isWithin(0.1)
- .of(expectedPowerMah);
+ .of(360.0);
assertThat(uidBatteryConsumer
.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT))
- .isEqualTo(expectedDurationMs);
+ .isEqualTo(60 * MINUTE_IN_MS);
+
+ assertThat(count[0]).isEqualTo(expectedNumberOfUpdates);
+
+ stats.close();
}
private void setTime(long timeMs) {
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java
index 9e7e0b6..a3c7ece 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java
@@ -41,7 +41,6 @@
import android.util.Xml;
import com.android.internal.os.CpuScalingPolicies;
-import com.android.internal.os.MonotonicClock;
import com.android.internal.os.PowerProfile;
import com.android.internal.power.EnergyConsumerStats;
@@ -66,7 +65,6 @@
private final PowerProfile mPowerProfile;
private final MockClock mMockClock = new MockClock();
- private final MonotonicClock mMonotonicClock = new MonotonicClock(666777, mMockClock);
private String mTestName;
private boolean mCreateTempDirectory;
private File mHistoryDir;
@@ -120,7 +118,7 @@
clearDirectory();
}
mBatteryStats = new MockBatteryStatsImpl(mBatteryStatsConfigBuilder.build(),
- mMockClock, mMonotonicClock, mHistoryDir, mHandler, new PowerStatsUidResolver());
+ mMockClock, mHistoryDir, mHandler, new PowerStatsUidResolver());
mBatteryStats.setPowerProfile(mPowerProfile);
mBatteryStats.setCpuScalingPolicies(new CpuScalingPolicies(mCpusByPolicy, mFreqsByPolicy));
synchronized (mBatteryStats) {
@@ -146,10 +144,6 @@
return mMockClock;
}
- public MonotonicClock getMonotonicClock() {
- return mMonotonicClock;
- }
-
public Handler getHandler() {
return mHandler;
}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
index 9a38209..b374a32 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java
@@ -77,15 +77,9 @@
new PowerStatsUidResolver());
}
- MockBatteryStatsImpl(BatteryStatsConfig config, Clock clock,
- File historyDirectory, Handler handler, PowerStatsUidResolver powerStatsUidResolver) {
- this(config, clock, new MonotonicClock(0, clock), historyDirectory, handler,
- powerStatsUidResolver);
- }
-
- MockBatteryStatsImpl(BatteryStatsConfig config, Clock clock, MonotonicClock monotonicClock,
- File historyDirectory, Handler handler, PowerStatsUidResolver powerStatsUidResolver) {
- super(config, clock, monotonicClock, historyDirectory, handler,
+ MockBatteryStatsImpl(BatteryStatsConfig config, Clock clock, File historyDirectory,
+ Handler handler, PowerStatsUidResolver powerStatsUidResolver) {
+ super(config, clock, new MonotonicClock(0, clock), historyDirectory, handler,
mock(PlatformIdleStateCallback.class), mock(EnergyStatsRetriever.class),
mock(UserInfoProvider.class), mockPowerProfile(),
new CpuScalingPolicies(new SparseArray<>(), new SparseArray<>()),
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java
index d243f92..38fe613 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java
@@ -408,7 +408,7 @@
BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
new String[]{"cu570m"},
/* includeProcessStateData */ true, true, true, /* powerThreshold */ 0);
- exportAggregatedPowerStats(builder, 3700, 7500);
+ exportAggregatedPowerStats(builder, 3700, 6700);
BatteryUsageStats actual = builder.build();
String message = "Actual BatteryUsageStats: " + actual;
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
index 5127b2d..c6df146 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -22,6 +22,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
@@ -921,6 +923,41 @@
});
}
+ @Test
+ public void shouldShowRdmEduDialog1() {
+ // RDM V1 Cases
+ assertTrue(DeviceStateManagerService.shouldShowRdmEduDialog(
+ false /* hasControlDeviceStatePermission */,
+ false /* requestingRdmOuterDefault */,
+ false /* isDeviceClosed (no-op) */));
+
+ assertFalse(DeviceStateManagerService.shouldShowRdmEduDialog(
+ true /* hasControlDeviceStatePermission */,
+ false /* requestingRdmOuterDefault */,
+ true /* isDeviceClosed (no-op) */));
+
+ // RDM V2 Cases
+ // hasControlDeviceStatePermission = false
+ assertFalse(DeviceStateManagerService.shouldShowRdmEduDialog(
+ false /* hasControlDeviceStatePermission */,
+ true /* requestingRdmOuterDefault */,
+ false /* isDeviceClosed */));
+ assertTrue(DeviceStateManagerService.shouldShowRdmEduDialog(
+ false /* hasControlDeviceStatePermission */,
+ true /* requestingRdmOuterDefault */,
+ true /* isDeviceClosed */));
+
+ // hasControlDeviceStatePermission = true
+ assertFalse(DeviceStateManagerService.shouldShowRdmEduDialog(
+ true /* hasControlDeviceStatePermission */,
+ true /* requestingRdmOuterDefault */,
+ false /* isDeviceClosed */));
+ assertFalse(DeviceStateManagerService.shouldShowRdmEduDialog(
+ true /* hasControlDeviceStatePermission */,
+ true /* requestingRdmOuterDefault */,
+ true /* isDeviceClosed */));
+ }
+
/**
* Common code to verify the handling of FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP flag.
*
diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
index 0404b82..c4b8599 100644
--- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
@@ -118,6 +118,7 @@
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
@@ -232,7 +233,8 @@
any(AlarmManager.OnAlarmListener.class), any(Handler.class));
doAnswer(inv -> {
- mCustomListener = () -> {};
+ mCustomListener = () -> {
+ };
return null;
}).when(mAlarmManager).cancel(eq(mCustomListener));
when(mContext.getSystemService(eq(Context.POWER_SERVICE)))
@@ -1321,7 +1323,7 @@
@Test
public void enableCarMode_failsForBogusPackageName() throws Exception {
when(mPackageManager.getPackageUidAsUser(eq(PACKAGE_NAME), anyInt()))
- .thenReturn(TestInjector.DEFAULT_CALLING_UID + 1);
+ .thenReturn(TestInjector.DEFAULT_CALLING_UID + 1);
assertThrows(SecurityException.class, () -> mService.enableCarMode(0, 0, PACKAGE_NAME));
assertThat(mService.getCurrentModeType()).isNotEqualTo(Configuration.UI_MODE_TYPE_CAR);
@@ -1343,19 +1345,19 @@
@Test
public void disableCarMode_failsForBogusPackageName() throws Exception {
when(mPackageManager.getPackageUidAsUser(eq(PACKAGE_NAME), anyInt()))
- .thenReturn(TestInjector.DEFAULT_CALLING_UID);
+ .thenReturn(TestInjector.DEFAULT_CALLING_UID);
mService.enableCarMode(0, 0, PACKAGE_NAME);
assertThat(mService.getCurrentModeType()).isEqualTo(Configuration.UI_MODE_TYPE_CAR);
when(mPackageManager.getPackageUidAsUser(eq(PACKAGE_NAME), anyInt()))
- .thenReturn(TestInjector.DEFAULT_CALLING_UID + 1);
+ .thenReturn(TestInjector.DEFAULT_CALLING_UID + 1);
assertThrows(SecurityException.class,
- () -> mService.disableCarModeByCallingPackage(0, PACKAGE_NAME));
+ () -> mService.disableCarModeByCallingPackage(0, PACKAGE_NAME));
assertThat(mService.getCurrentModeType()).isEqualTo(Configuration.UI_MODE_TYPE_CAR);
// Clean up
when(mPackageManager.getPackageUidAsUser(eq(PACKAGE_NAME), anyInt()))
- .thenReturn(TestInjector.DEFAULT_CALLING_UID);
+ .thenReturn(TestInjector.DEFAULT_CALLING_UID);
mService.disableCarModeByCallingPackage(0, PACKAGE_NAME);
assertThat(mService.getCurrentModeType()).isNotEqualTo(Configuration.UI_MODE_TYPE_CAR);
}
@@ -1473,12 +1475,13 @@
assertFalse(mUiManagerService.getConfiguration().isNightModeActive());
}
- // attention modes with expected night modes
- Map<Integer, Boolean> modes = Map.of(
- MODE_ATTENTION_THEME_OVERLAY_OFF, initialNightMode,
- MODE_ATTENTION_THEME_OVERLAY_DAY, false,
- MODE_ATTENTION_THEME_OVERLAY_NIGHT, true
- );
+ // Attention modes with expected night modes.
+ // Important to keep modes.put(MODE_ATTENTION_THEME_OVERLAY_OFF, initialNightMode) in the
+ // first position, hence LinkedHashMap.
+ Map<Integer, Boolean> modes = new LinkedHashMap<>();
+ modes.put(MODE_ATTENTION_THEME_OVERLAY_OFF, initialNightMode);
+ modes.put(MODE_ATTENTION_THEME_OVERLAY_DAY, false);
+ modes.put(MODE_ATTENTION_THEME_OVERLAY_NIGHT, true);
// test
for (int attentionMode : modes.keySet()) {
@@ -1562,7 +1565,7 @@
private final int callingUid;
public TestInjector() {
- this(DEFAULT_CALLING_UID);
+ this(DEFAULT_CALLING_UID);
}
public TestInjector(int callingUid) {
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 41b5fde..074cbb5 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -49,10 +49,14 @@
import static android.app.NotificationChannel.RECS_ID;
import static android.app.NotificationChannel.SOCIAL_MEDIA_ID;
import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE;
+import static android.app.NotificationManager.ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED;
import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED;
+import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_ACTIVATED;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
+import static android.app.NotificationManager.EXTRA_AUTOMATIC_ZEN_RULE_ID;
+import static android.app.NotificationManager.EXTRA_AUTOMATIC_ZEN_RULE_STATUS;
import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
@@ -369,6 +373,7 @@
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
@@ -11273,19 +11278,71 @@
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)), eq(UserHandle.of(102)));
}
+ @Test
+ @EnableFlags(android.app.Flags.FLAG_MODES_API)
+ public void onAutomaticRuleStatusChanged_sendsBroadcastToRuleOwner() throws Exception {
+ mService.mZenModeHelper.getCallbacks().forEach(c -> c.onAutomaticRuleStatusChanged(
+ mUserId, "rule.owner.pkg", "rule_id", AUTOMATIC_RULE_STATUS_ACTIVATED));
+
+ Intent expected = new Intent(ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED)
+ .setPackage("rule.owner.pkg")
+ .putExtra(EXTRA_AUTOMATIC_ZEN_RULE_ID, "rule_id")
+ .putExtra(EXTRA_AUTOMATIC_ZEN_RULE_STATUS, AUTOMATIC_RULE_STATUS_ACTIVATED)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+
+ verify(mContext).sendBroadcastAsUser(eqIntent(expected), eq(UserHandle.of(mUserId)));
+ }
+
private static Intent eqIntent(Intent wanted) {
return ArgumentMatchers.argThat(
new ArgumentMatcher<Intent>() {
@Override
public boolean matches(Intent argument) {
return wanted.filterEquals(argument)
- && wanted.getFlags() == argument.getFlags();
+ && wanted.getFlags() == argument.getFlags()
+ && equalBundles(wanted.getExtras(), argument.getExtras());
}
@Override
public String toString() {
return wanted.toString();
}
+
+ private boolean equalBundles(Bundle one, Bundle two) {
+ if (one == null && two == null) {
+ return true;
+ }
+ if ((one == null) != (two == null)) {
+ return false;
+ }
+ if (one.size() != two.size()) {
+ return false;
+ }
+
+ HashSet<String> setOne = new HashSet<>(one.keySet());
+ setOne.addAll(two.keySet());
+
+ for (String key : setOne) {
+ if (!one.containsKey(key) || !two.containsKey(key)) {
+ return false;
+ }
+
+ Object valueOne = one.get(key);
+ Object valueTwo = two.get(key);
+ if (valueOne instanceof Bundle
+ && valueTwo instanceof Bundle
+ && !equalBundles((Bundle) valueOne, (Bundle) valueTwo)) {
+ return false;
+ } else if (valueOne == null) {
+ if (valueTwo != null) {
+ return false;
+ }
+ } else if (!valueOne.equals(valueTwo)) {
+ return false;
+ }
+ }
+ return true;
+ }
});
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java
index 65ed7b6..934c33b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java
@@ -19,6 +19,8 @@
import static java.util.concurrent.TimeUnit.HOURS;
+import android.service.notification.RateEstimator;
+
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
diff --git a/services/tests/wmtests/res/xml/bookmarks.xml b/services/tests/wmtests/res/xml/bookmarks.xml
index 787f4e8..cbbbc73 100644
--- a/services/tests/wmtests/res/xml/bookmarks.xml
+++ b/services/tests/wmtests/res/xml/bookmarks.xml
@@ -22,7 +22,7 @@
androidprv:modifierState="META" />
<bookmark
category="android.intent.category.APP_CONTACTS"
- androidprv:keycode="KEYCODE_C"
+ androidprv:keycode="KEYCODE_P"
androidprv:modifierState="META" />
<bookmark
category="android.intent.category.APP_EMAIL"
@@ -30,21 +30,13 @@
androidprv:modifierState="META" />
<bookmark
category="android.intent.category.APP_CALENDAR"
- androidprv:keycode="KEYCODE_K"
+ androidprv:keycode="KEYCODE_C"
androidprv:modifierState="META" />
<bookmark
category="android.intent.category.APP_MAPS"
androidprv:keycode="KEYCODE_M"
androidprv:modifierState="META" />
<bookmark
- category="android.intent.category.APP_MUSIC"
- androidprv:keycode="KEYCODE_P"
- androidprv:modifierState="META" />
- <bookmark
- role="android.app.role.SMS"
- androidprv:keycode="KEYCODE_S"
- androidprv:modifierState="META" />
- <bookmark
category="android.intent.category.APP_CALCULATOR"
androidprv:keycode="KEYCODE_U"
androidprv:modifierState="META" />
@@ -56,7 +48,7 @@
<bookmark
category="android.intent.category.APP_CONTACTS"
- androidprv:keycode="KEYCODE_C"
+ androidprv:keycode="KEYCODE_P"
androidprv:modifierState="META|SHIFT" />
<bookmark
diff --git a/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
index 1e9038e..41865b20 100644
--- a/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
@@ -258,9 +258,9 @@
{"EXPLORER key -> Launch Default Browser", new int[]{KeyEvent.KEYCODE_EXPLORER},
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER,
KeyEvent.KEYCODE_EXPLORER, 0},
- {"Meta + C -> Launch Default Contacts", new int[]{META_KEY, KeyEvent.KEYCODE_C},
+ {"Meta + P -> Launch Default Contacts", new int[]{META_KEY, KeyEvent.KEYCODE_P},
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS,
- KeyEvent.KEYCODE_C, META_ON},
+ KeyEvent.KEYCODE_P, META_ON},
{"CONTACTS key -> Launch Default Contacts", new int[]{KeyEvent.KEYCODE_CONTACTS},
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS,
KeyEvent.KEYCODE_CONTACTS, 0},
@@ -270,15 +270,12 @@
{"ENVELOPE key -> Launch Default Email", new int[]{KeyEvent.KEYCODE_ENVELOPE},
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL,
KeyEvent.KEYCODE_ENVELOPE, 0},
- {"Meta + K -> Launch Default Calendar", new int[]{META_KEY, KeyEvent.KEYCODE_K},
+ {"Meta + C -> Launch Default Calendar", new int[]{META_KEY, KeyEvent.KEYCODE_C},
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR,
- KeyEvent.KEYCODE_K, META_ON},
+ KeyEvent.KEYCODE_C, META_ON},
{"CALENDAR key -> Launch Default Calendar", new int[]{KeyEvent.KEYCODE_CALENDAR},
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR,
KeyEvent.KEYCODE_CALENDAR, 0},
- {"Meta + P -> Launch Default Music", new int[]{META_KEY, KeyEvent.KEYCODE_P},
- KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC,
- KeyEvent.KEYCODE_P, META_ON},
{"MUSIC key -> Launch Default Music", new int[]{KeyEvent.KEYCODE_MUSIC},
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC,
KeyEvent.KEYCODE_MUSIC, 0},
@@ -291,11 +288,7 @@
KeyEvent.KEYCODE_CALCULATOR, 0},
{"Meta + M -> Launch Default Maps", new int[]{META_KEY, KeyEvent.KEYCODE_M},
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS,
- KeyEvent.KEYCODE_M, META_ON},
- {"Meta + S -> Launch Default Messaging App",
- new int[]{META_KEY, KeyEvent.KEYCODE_S},
- KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING,
- KeyEvent.KEYCODE_S, META_ON}};
+ KeyEvent.KEYCODE_M, META_ON}};
}
@Keep
@@ -468,6 +461,14 @@
}
@Test
+ public void testKeyGestureLaunchVoiceAssistant() {
+ Assert.assertTrue(
+ sendKeyGestureEventComplete(
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT));
+ mPhoneWindowManager.assertSearchManagerLaunchAssist();
+ }
+
+ @Test
public void testKeyGestureGoHome() {
Assert.assertTrue(
sendKeyGestureEventComplete(KeyGestureEvent.KEY_GESTURE_TYPE_HOME));
diff --git a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
index cf5323e..35b077e 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java
@@ -26,7 +26,6 @@
import static android.view.KeyEvent.KEYCODE_ENTER;
import static android.view.KeyEvent.KEYCODE_H;
import static android.view.KeyEvent.KEYCODE_J;
-import static android.view.KeyEvent.KEYCODE_K;
import static android.view.KeyEvent.KEYCODE_M;
import static android.view.KeyEvent.KEYCODE_META_LEFT;
import static android.view.KeyEvent.KEYCODE_N;
@@ -67,14 +66,12 @@
// These shortcuts should align with those defined in
// services/tests/wmtests/res/xml/bookmarks.xml
INTENT_SHORTCUTS.append(KEYCODE_U, Intent.CATEGORY_APP_CALCULATOR);
- INTENT_SHORTCUTS.append(KEYCODE_C, Intent.CATEGORY_APP_CONTACTS);
+ INTENT_SHORTCUTS.append(KEYCODE_P, Intent.CATEGORY_APP_CONTACTS);
INTENT_SHORTCUTS.append(KEYCODE_E, Intent.CATEGORY_APP_EMAIL);
- INTENT_SHORTCUTS.append(KEYCODE_K, Intent.CATEGORY_APP_CALENDAR);
+ INTENT_SHORTCUTS.append(KEYCODE_C, Intent.CATEGORY_APP_CALENDAR);
INTENT_SHORTCUTS.append(KEYCODE_M, Intent.CATEGORY_APP_MAPS);
- INTENT_SHORTCUTS.append(KEYCODE_P, Intent.CATEGORY_APP_MUSIC);
ROLE_SHORTCUTS.append(KEYCODE_B, RoleManager.ROLE_BROWSER);
- ROLE_SHORTCUTS.append(KEYCODE_S, RoleManager.ROLE_SMS);
}
private static final int ANY_DISPLAY_ID = 123;
@@ -109,7 +106,7 @@
sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_SHIFT_LEFT, KEYCODE_B}, 0);
mPhoneWindowManager.assertLaunchRole(RoleManager.ROLE_BROWSER);
- sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_SHIFT_LEFT, KEYCODE_C}, 0);
+ sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_SHIFT_LEFT, KEYCODE_P}, 0);
mPhoneWindowManager.assertLaunchCategory(Intent.CATEGORY_APP_CONTACTS);
sendKeyCombination(new int[]{KEYCODE_META_LEFT, KEYCODE_SHIFT_LEFT, KEYCODE_J}, 0);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
index 2a53df9..a7fc10f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
@@ -17,30 +17,23 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.SnapshotPersistQueue.MAX_STORE_QUEUE_DEPTH;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
-import android.content.ComponentName;
-import android.graphics.ColorSpace;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.hardware.HardwareBuffer;
import android.platform.test.annotations.Presubmit;
import android.util.ArraySet;
-import android.view.Surface;
import android.window.TaskSnapshot;
import androidx.test.filters.SmallTest;
@@ -61,14 +54,20 @@
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
-public class ActivitySnapshotControllerTests extends WindowTestsBase {
+public class ActivitySnapshotControllerTests extends TaskSnapshotPersisterTestBase {
private ActivitySnapshotController mActivitySnapshotController;
+ public ActivitySnapshotControllerTests() {
+ super(0.8f /* highResScale */, 0.5f /* lowResScale */);
+ }
+
+ @Override
@Before
- public void setUp() throws Exception {
- spyOn(mWm.mSnapshotController.mActivitySnapshotController);
- mActivitySnapshotController = mWm.mSnapshotController.mActivitySnapshotController;
+ public void setUp() {
+ super.setUp();
+ mActivitySnapshotController = new ActivitySnapshotController(mWm, mSnapshotPersistQueue);
+ spyOn(mActivitySnapshotController);
doReturn(false).when(mActivitySnapshotController).shouldDisableSnapshots();
mActivitySnapshotController.resetTmpFields();
}
@@ -92,12 +91,11 @@
assertEquals(0, mActivitySnapshotController.mPendingRemoveActivity.size());
mActivitySnapshotController.resetTmpFields();
- // simulate three activity
+ // simulate three activity, the bottom activity won't participate in transition
final WindowState belowClose = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
"belowClose");
belowClose.mActivityRecord.commitVisibility(
false /* visible */, true /* performLayout */);
- windows.add(belowClose.mActivityRecord);
mActivitySnapshotController.handleTransitionFinish(windows);
assertEquals(1, mActivitySnapshotController.mPendingRemoveActivity.size());
assertEquals(belowClose.mActivityRecord,
@@ -249,15 +247,28 @@
assertEquals(taskSnapshot, mActivitySnapshotController.getSnapshot(activities));
}
- private TaskSnapshot createSnapshot() {
- HardwareBuffer buffer = mock(HardwareBuffer.class);
- doReturn(100).when(buffer).getWidth();
- doReturn(100).when(buffer).getHeight();
- return new TaskSnapshot(1, 0 /* captureTime */, new ComponentName("", ""), buffer,
- ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
- Surface.ROTATION_0, new Point(100, 100), new Rect() /* contentInsets */,
- new Rect() /* letterboxInsets*/, false /* isLowResolution */,
- true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN, 0 /* mSystemUiVisibility */,
- false /* isTranslucent */, false /* hasImeSurface */, 0 /* uiMode */);
+ /**
+ * Verifies that activity snapshot is skipped if the persister queue has too many pending write
+ * items.
+ */
+ @Test
+ public void testSkipRecordActivity() {
+ doReturn(createSnapshot()).when(mActivitySnapshotController).recordSnapshotInner(any());
+ final Task task = createTask(mDisplayContent);
+
+ mSnapshotPersistQueue.setPaused(true);
+ final ArrayList<ActivityRecord> tmpList = new ArrayList<>();
+ for (int i = 0; i < MAX_STORE_QUEUE_DEPTH; ++i) {
+ tmpList.clear();
+ final ActivityRecord activity = createActivityRecord(task);
+ tmpList.add(activity);
+ mActivitySnapshotController.recordSnapshot(tmpList);
+ assertNotNull(mActivitySnapshotController.findSavedFile(activity));
+ }
+ tmpList.clear();
+ final ActivityRecord activity = createActivityRecord(task);
+ tmpList.add(activity);
+ mActivitySnapshotController.recordSnapshot(tmpList);
+ assertNull(mActivitySnapshotController.findSavedFile(activity));
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
index d183cf7..f3a2e86 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java
@@ -46,6 +46,7 @@
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Bundle;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.view.Display;
import android.view.DisplayInfo;
@@ -54,7 +55,12 @@
import androidx.test.filters.SmallTest;
+import com.android.window.flags.Flags;
+
+import com.google.common.truth.Expect;
+
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -65,6 +71,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+
/**
* Build/Install/Run:
* atest WmTests:WindowContextListenerControllerTests
@@ -86,6 +93,9 @@
private WindowProcessController mWpc;
private WindowContainer<?> mContainer;
+ @Rule
+ public final Expect mExpect = Expect.create();
+
@Before
public void setUp() {
initMocks(this);
@@ -341,6 +351,30 @@
assertThat(clientToken.mDisplayId).isEqualTo(mDisplayContent.mDisplayId);
}
+ @Test
+ @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+ public void assertCallerCanReparentListener_returnsTrueWhenExpected() {
+ mController.registerWindowContainerListener(mWpc, mClientToken, mContainer,
+ TYPE_APPLICATION_OVERLAY, null /* options */);
+
+ // Here there are several checks in one test as wm tests are expensive.
+
+ // Correct conditions -> returns true
+ mExpect.that(mController.assertCallerCanReparentListener(mClientToken,
+ /* callerCanManageAppTokens= */ true,
+ /* callingUid= */ mWpc.mUid,
+ /* displayId= */ DEFAULT_DISPLAY + 1
+ )).isTrue();
+
+ // sameDisplayId (so, container already attached) -> returnsFalse
+ mExpect.that(mController.assertCallerCanReparentListener(
+ mClientToken,
+ /* callerCanManageAppTokens= */ true,
+ /* callingUid= */ mWpc.mUid,
+ /* displayId= */ DEFAULT_DISPLAY // <- same display ID
+ )).isFalse();
+ }
+
private static class TestWindowTokenClient extends WindowTokenClient {
private Configuration mConfiguration;
private int mDisplayId;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index bfa6cb8..69df66e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -39,6 +39,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.flags.Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION;
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
@@ -70,6 +71,7 @@
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.description;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -86,10 +88,10 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
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.util.ArraySet;
import android.util.MergedConfiguration;
import android.view.ContentRecordingSession;
@@ -151,9 +153,6 @@
@Rule
public Expect mExpect = Expect.create();
- @Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
@After
public void tearDown() {
mWm.mSensitiveContentPackages.clearBlockedApps();
@@ -1412,6 +1411,84 @@
assertThat(result).isEqualTo(WindowManagerGlobal.ADD_INVALID_DISPLAY);
}
+ /** Mocks some deps to associate a display content to a specific display id. */
+ private void setupReparentWindowContextToDisplayAreaTest(WindowToken windowToken,
+ DisplayContent dc, int displayId) {
+ spyOn(mWm.mWindowContextListenerController);
+ doReturn(dc).when(mWm.mRoot).getDisplayContentOrCreate(displayId);
+ doReturn(true).when(mWm.mWindowContextListenerController).assertCallerCanReparentListener(
+ any(), anyBoolean(), anyInt(), eq(displayId));
+ doReturn(windowToken).when(mWm.mWindowContextListenerController).getContainer(
+ eq(windowToken.token));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+ public void reparentWindowContextToDisplayArea_newDisplay_reparented() {
+ final WindowToken windowToken = createTestClientWindowToken(TYPE_NOTIFICATION_SHADE,
+ mDisplayContent);
+ final int newDisplayId = 1;
+ final DisplayContent dc = createNewDisplay();
+ setupReparentWindowContextToDisplayAreaTest(windowToken, dc, newDisplayId);
+
+ assertThat(windowToken.getDisplayContent()).isEqualTo(mDisplayContent);
+
+ assertThat(mWm.reparentWindowContextToDisplayArea(mAppThread, windowToken.token,
+ newDisplayId)).isTrue();
+
+ assertThat(windowToken.getDisplayContent()).isNotEqualTo(mDisplayContent);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+ public void reparentWindowContextToDisplayArea_newDisplayButFlagDisabled_notReparented() {
+ final WindowToken windowToken = createTestClientWindowToken(TYPE_NOTIFICATION_SHADE,
+ mDisplayContent);
+ final int newDisplayId = 1;
+ final DisplayContent dc = createNewDisplay();
+ setupReparentWindowContextToDisplayAreaTest(windowToken, dc, newDisplayId);
+
+ assertThat(mWm.reparentWindowContextToDisplayArea(mAppThread, windowToken.token,
+ newDisplayId)).isFalse();
+
+ assertThat(windowToken.getDisplayContent()).isEqualTo(mDisplayContent);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+ public void reparentWindowContext_afterReparent_DCNeedsLayout() {
+ final WindowToken windowToken = createTestClientWindowToken(TYPE_NOTIFICATION_SHADE,
+ mDisplayContent);
+ final int newDisplayId = 1;
+ final DisplayContent dc = createNewDisplay();
+ setupReparentWindowContextToDisplayAreaTest(windowToken, dc, newDisplayId);
+
+ assertThat(mWm.reparentWindowContextToDisplayArea(mAppThread, windowToken.token,
+ newDisplayId)).isTrue();
+
+ assertThat(dc.isLayoutNeeded()).isTrue();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+ public void reparentWindowContext_afterReparent_traversalScheduled() {
+ final WindowToken windowToken = createTestClientWindowToken(TYPE_NOTIFICATION_SHADE,
+ mDisplayContent);
+ final int newDisplayId = 1;
+ final DisplayContent dc = createNewDisplay();
+ setupReparentWindowContextToDisplayAreaTest(windowToken, dc, newDisplayId);
+ spyOn(mWm.mWindowPlacerLocked);
+ reset(mWm.mWindowPlacerLocked);
+
+ verify(mWm.mWindowPlacerLocked, never()).requestTraversal();
+
+ assertThat(mWm.reparentWindowContextToDisplayArea(mAppThread, windowToken.token,
+ newDisplayId)).isTrue();
+
+ verify(mWm.mWindowPlacerLocked).requestTraversal();
+ }
+
+
class TestResultReceiver implements IResultReceiver {
public android.os.Bundle resultData;
private final IBinder mBinder = mock(IBinder.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 78e6cbf..3a97cc6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -2039,9 +2039,22 @@
return new TestWindowToken(type, dc, persistOnEmpty);
}
+ static TestWindowToken createTestClientWindowToken(int type, DisplayContent dc) {
+ SystemServicesTestRule.checkHoldsLock(dc.mWmService.mGlobalLock);
+
+ return new TestWindowToken(type, dc, false /* persistOnEmpty */, true /* fromClient */);
+ }
+
/** Used so we can gain access to some protected members of the {@link WindowToken} class */
static class TestWindowToken extends WindowToken {
+ private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty,
+ boolean fromClient) {
+ super(dc.mWmService, mock(IBinder.class), type, persistOnEmpty, dc,
+ false /* ownerCanManageAppTokens */, false /* roundedCornerOverlay */,
+ fromClient /* fromClientToken */, null /* options */);
+ }
+
private TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
super(dc.mWmService, mock(IBinder.class), type, persistOnEmpty, dc,
false /* ownerCanManageAppTokens */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index 35328a0e..f226b9d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -33,21 +33,27 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.view.WindowInsets;
import android.window.WindowContext;
import androidx.test.filters.SmallTest;
+import com.android.window.flags.Flags;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mockito;
import java.util.function.BiFunction;
@@ -304,14 +310,39 @@
// immediately. verify the window will hide without applying exit animation.
mWm.removeWindowToken(win.mToken.token, false /* removeWindows */, false /* animateExit */,
mDisplayContent.mDisplayId);
- verify(win).onSetAppExiting(Mockito.eq(false) /* animateExit */);
+ verify(win).onSetAppExiting(eq(false) /* animateExit */);
verify(win).hide(false /* doAnimation */, false /* requestAnim */);
assertFalse(win.isOnScreen());
- verify(win.mWinAnimator, Mockito.never()).applyAnimationLocked(TRANSIT_EXIT, false);
+ verify(win.mWinAnimator, never()).applyAnimationLocked(TRANSIT_EXIT, false);
assertTrue(win.mToken.hasChild());
// Even though the window is being removed afterwards, it won't apply exit animation.
win.removeIfPossible();
- verify(win.mWinAnimator, Mockito.never()).applyAnimationLocked(TRANSIT_EXIT, false);
+ verify(win.mWinAnimator, never()).applyAnimationLocked(TRANSIT_EXIT, false);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+ public void onDisplayChanged_differentDisplay_reparented() {
+ final TestWindowToken token = createTestWindowToken(0, mDisplayContent);
+ final DisplayContent dc = mock(DisplayContent.class);
+ when(dc.getWindowToken(any())).thenReturn(null); // dc doesn't have this window token.
+
+ token.onDisplayChanged(dc);
+
+ verify(dc).reParentWindowToken(eq(token));
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
+ public void onDisplayChanged_samedisplay_notReparented() {
+
+ final TestWindowToken token = createTestWindowToken(0, mDisplayContent);
+ final DisplayContent dc = mock(DisplayContent.class);
+ when(dc.getWindowToken(any())).thenReturn(mock(WindowToken.class));
+
+ token.onDisplayChanged(dc);
+
+ verify(dc, never()).reParentWindowToken(eq(token));
}
}
diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.java b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
index a69dfb0b..cdb3eaf 100644
--- a/telecomm/java/android/telecom/ParcelableCallAnalytics.java
+++ b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
@@ -16,12 +16,12 @@
package android.telecom;
+import android.annotation.FlaggedApi;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
-import java.util.LinkedList;
import java.util.List;
/**
@@ -255,6 +255,11 @@
public static final int CALLTYPE_OUTGOING = 2;
// Constants for call technology
+ /**
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(com.android.internal.telephony.flags.Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_PHONE = 0x1;
public static final int GSM_PHONE = 0x2;
public static final int IMS_PHONE = 0x4;
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 8fe107c..09b18b6 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -109,6 +109,7 @@
//TelephonyManager.NETWORK_TYPE_LTE_CA,
TelephonyManager.NETWORK_TYPE_NR,
+ TelephonyManager.NETWORK_TYPE_NB_IOT_NTN,
})
@Retention(RetentionPolicy.SOURCE)
public @interface NetworkType {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index e5f1841..478ec5c 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -317,8 +317,10 @@
* If this is set as false and the supplementary service menu is visible, the associated setting
* will be enabled and disabled based on the availability of supplementary services over UT. See
* {@link #KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL}.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final String KEY_SUPPORT_SS_OVER_CDMA_BOOL = "support_ss_over_cdma_bool";
/**
@@ -536,7 +538,11 @@
*/
public static final String KEY_4G_ONLY_BOOL = "4g_only_bool";
- /** Show cdma network mode choices 1x, 3G, global etc. */
+ /** Show cdma network mode choices 1x, 3G, global etc.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @Deprecated
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
public static final String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
/** CDMA activation goes through HFA */
@@ -544,9 +550,12 @@
/**
* CDMA activation goes through OTASP.
+ * @deprecated Legacy CDMA is unsupported.
*/
// TODO: This should be combined with config_use_hfa_for_provisioning and implemented as an enum
// (NONE, HFA, OTASP).
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL =
"use_otasp_for_provisioning_bool";
@@ -556,10 +565,20 @@
/** Does not display additional call setting for IMS phone based on GSM Phone */
public static final String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
- /** Show APN Settings for some CDMA carriers */
+ /**
+ * Show APN Settings for some CDMA carriers
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @Deprecated
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
- /** After a CDMA conference call is merged, the swap button should be displayed. */
+ /**
+ * After a CDMA conference call is merged, the swap button should be displayed.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @Deprecated
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
/**
@@ -597,7 +616,10 @@
/**
* Disables dialing "*228" (OTASP provisioning) on CDMA carriers where it is not supported or is
* potentially harmful by locking the SIM to 3G.
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @Deprecated
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
public static final String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL =
"disable_cdma_activation_code_bool";
@@ -675,14 +697,20 @@
/**
* Override the platform's notion of a network operator being considered roaming.
* Value is string array of SIDs to be considered roaming for 3GPP2 RATs.
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final String
KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
/**
* Override the platform's notion of a network operator being considered non roaming.
* Value is string array of SIDs to be considered not roaming for 3GPP2 RATs.
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final String
KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
@@ -1243,8 +1271,10 @@
/**
* CDMA carrier ERI (Enhanced Roaming Indicator) file name
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final String KEY_CARRIER_ERI_FILE_NAME_STRING = "carrier_eri_file_name_string";
/* The following 3 fields are related to carrier visual voicemail. */
@@ -1386,7 +1416,10 @@
* Specifies the amount of gap to be added in millis between postdial DTMF tones. When a
* non-zero value is specified, the UE shall wait for the specified amount of time before it
* sends out successive DTMF tones on the network.
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
/**
@@ -1804,8 +1837,10 @@
* If this bit is not set, the carrier name display string will be selected from the carrier
* display name resolver which doesn't apply the ERI rules.
*
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final String KEY_ALLOW_ERI_BOOL = "allow_cdma_eri_bool";
/**
@@ -1849,8 +1884,10 @@
* If true, then the registered PLMN name (only for CDMA/CDMA-LTE and only when not roaming)
* will be #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING. If false, or if phone type is not
* CDMA/CDMA-LTE or if roaming, then #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING will be ignored.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final String KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL =
"cdma_home_registered_plmn_name_override_bool";
@@ -1858,8 +1895,10 @@
* String to identify registered PLMN name in CarrierConfig app. This string overrides
* registered PLMN name if #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL is true, phone type
* is CDMA/CDMA-LTE and device is not in roaming state; otherwise, it will be ignored.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final String KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING =
"cdma_home_registered_plmn_name_string";
@@ -2440,7 +2479,10 @@
* For carriers which require an empty flash to be sent before sending the normal 3-way calling
* flash, the duration in milliseconds of the empty flash to send. When {@code 0}, no empty
* flash is sent.
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final String KEY_CDMA_3WAYCALL_FLASH_DELAY_INT = "cdma_3waycall_flash_delay_int";
/**
@@ -2454,14 +2496,21 @@
* @see TelephonyManager#CDMA_ROAMING_MODE_HOME
* @see TelephonyManager#CDMA_ROAMING_MODE_AFFILIATED
* @see TelephonyManager#CDMA_ROAMING_MODE_ANY
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final String KEY_CDMA_ROAMING_MODE_INT = "cdma_roaming_mode_int";
/**
* Determines whether 1X voice calls is supported for some CDMA carriers.
* Default value is true.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL =
"support_cdma_1x_voice_calls_bool";
@@ -2483,8 +2532,10 @@
/**
* Report IMEI as device id even if it's a CDMA/LTE phone.
*
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final String KEY_FORCE_IMEI_BOOL = "force_imei_bool";
/**
@@ -3217,8 +3268,10 @@
* on a 3GPP network. Specifically *67<number> will be converted to #31#<number> and
* *82<number> will be converted to *31#<number> before dialing a call when this key is
* set TRUE and device is roaming on a 3GPP network.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final String KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL =
"convert_cdma_caller_id_mmi_codes_while_roaming_on_3gpp_bool";
@@ -3621,8 +3674,11 @@
/**
* Support for the original string display of CDMA MO call.
* By default, it is disabled.
+ *
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final String KEY_CONFIG_SHOW_ORIG_DIAL_STRING_FOR_CDMA_BOOL =
"config_show_orig_dial_string_for_cdma";
@@ -5070,8 +5126,10 @@
* The default values come from 3GPP2 C.R1001 table 8.1-1.
* Enhanced Roaming Indicator Number Assignments
*
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final String KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY =
"cdma_enhanced_roaming_indicator_for_home_network_int_array";
diff --git a/telephony/java/android/telephony/CellBroadcastService.java b/telephony/java/android/telephony/CellBroadcastService.java
index 14de2f2..60f986c 100644
--- a/telephony/java/android/telephony/CellBroadcastService.java
+++ b/telephony/java/android/telephony/CellBroadcastService.java
@@ -17,6 +17,7 @@
package android.telephony;
import android.annotation.CallSuper;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -28,6 +29,7 @@
import android.os.RemoteCallback;
import android.telephony.cdma.CdmaSmsCbProgramData;
+import com.android.internal.telephony.flags.Flags;
import com.android.internal.util.FastPrintWriter;
import java.io.FileDescriptor;
@@ -88,9 +90,12 @@
* @param slotIndex the index of the slot which received the message
* @param bearerData the CDMA SMS bearer data
* @param serviceCategory the CDMA SCPT service category
+ * @deprecated Legacy CDMA is unsupported.
*/
- public abstract void onCdmaCellBroadcastSms(int slotIndex, @NonNull byte[] bearerData,
- @CdmaSmsCbProgramData.Category int serviceCategory);
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
+ public void onCdmaCellBroadcastSms(int slotIndex, @NonNull byte[] bearerData,
+ @CdmaSmsCbProgramData.Category int serviceCategory) {}
/**
* Handle a CDMA cell broadcast SMS message forwarded from the system.
@@ -102,10 +107,13 @@
* @param callback a callback to run after each cell broadcast receiver has handled
* the SCP message. The bundle will contain a non-separated
* dial string as and an ArrayList of {@link CdmaSmsCbProgramResults}.
+ * @deprecated Legacy CDMA is unsupported.
*/
- public abstract void onCdmaScpMessage(int slotIndex,
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
+ public void onCdmaScpMessage(int slotIndex,
@NonNull List<CdmaSmsCbProgramData> smsCbProgramData,
- @NonNull String originatingAddress, @NonNull Consumer<Bundle> callback);
+ @NonNull String originatingAddress, @NonNull Consumer<Bundle> callback) {}
/**
* Get broadcasted area information.
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index 5eace54..4e5a246 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -18,11 +18,13 @@
import static android.text.TextUtils.formatSimple;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.telephony.cdma.CdmaCellLocation;
+import com.android.internal.telephony.flags.Flags;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.telephony.Rlog;
@@ -30,7 +32,11 @@
/**
* CellIdentity is to represent a unique CDMA cell
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+@FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+@Deprecated
public final class CellIdentityCdma extends CellIdentity {
private static final String TAG = CellIdentityCdma.class.getSimpleName();
private static final boolean DBG = false;
@@ -124,7 +130,11 @@
return new CellIdentityCdma(this);
}
- /** @hide */
+ /** @hide
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@Override
public @NonNull CellIdentityCdma sanitizeLocationInfo() {
return new CellIdentityCdma(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
@@ -157,7 +167,11 @@
/**
* @return Network Id 0..65535, {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE}
* if unavailable.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public int getNetworkId() {
return mNetworkId;
}
@@ -165,7 +179,11 @@
/**
* @return System Id 0..32767, {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE}
* if unavailable.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public int getSystemId() {
return mSystemId;
}
@@ -173,7 +191,10 @@
/**
* @return Base Station Id 0..65535, {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE}
* if unavailable.
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public int getBasestationId() {
return mBasestationId;
}
@@ -184,7 +205,11 @@
* of 0.25 seconds and ranges from -2592000 to 2592000, both
* values inclusive (corresponding to a range of -180
* to +180 degrees). {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public int getLongitude() {
return mLongitude;
}
@@ -195,7 +220,11 @@
* of 0.25 seconds and ranges from -1296000 to 1296000, both
* values inclusive (corresponding to a range of -90
* to +90 degrees). {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public int getLatitude() {
return mLatitude;
}
@@ -206,7 +235,11 @@
super.hashCode());
}
- /** @hide */
+ /** @hide
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@NonNull
@Override
public CdmaCellLocation asCellLocation() {
@@ -277,7 +310,13 @@
if (DBG) log(toString());
}
- /** Implement the Parcelable interface */
+ /**
+ * Implement the Parcelable interface
+ *
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SuppressWarnings("hiding")
public static final @android.annotation.NonNull Creator<CellIdentityCdma> CREATOR =
new Creator<CellIdentityCdma>() {
diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java
index aa8cff5..3c4bb51 100644
--- a/telephony/java/android/telephony/CellInfoCdma.java
+++ b/telephony/java/android/telephony/CellInfoCdma.java
@@ -16,17 +16,23 @@
package android.telephony;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.telephony.flags.Flags;
import com.android.telephony.Rlog;
/**
* A {@link CellInfo} representing a CDMA cell that provides identity and measurement info.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+@FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+@Deprecated
public final class CellInfoCdma extends CellInfo implements Parcelable {
private static final String LOG_TAG = "CellInfoCdma";
@@ -61,7 +67,10 @@
/**
* @return a {@link CellIdentityCdma} instance.
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@Override
public @NonNull CellIdentityCdma getCellIdentity() {
return mCellIdentityCdma;
@@ -75,7 +84,10 @@
/**
* @return a {@link CellSignalStrengthCdma} instance.
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@Override
public @NonNull CellSignalStrengthCdma getCellSignalStrength() {
return mCellSignalStrengthCdma;
@@ -135,7 +147,12 @@
return 0;
}
- /** Implement the Parcelable interface */
+ /**
+ * Implement the Parcelable interface
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags, TYPE_CDMA);
@@ -154,7 +171,12 @@
if (DBG) log("CellInfoCdma(Parcel): " + toString());
}
- /** Implement the Parcelable interface */
+ /**
+ * Implement the Parcelable interface
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final @android.annotation.NonNull Creator<CellInfoCdma> CREATOR = new Creator<CellInfoCdma>() {
@Override
public CellInfoCdma createFromParcel(Parcel in) {
diff --git a/telephony/java/android/telephony/PreciseDisconnectCause.java b/telephony/java/android/telephony/PreciseDisconnectCause.java
index d9437ab..2d650ab2 100644
--- a/telephony/java/android/telephony/PreciseDisconnectCause.java
+++ b/telephony/java/android/telephony/PreciseDisconnectCause.java
@@ -255,25 +255,75 @@
@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE)
public static final int EMERGENCY_PERM_FAILURE = 326;
- /** Mobile station (MS) is locked until next power cycle. */
+ /**
+ * Mobile station (MS) is locked until next power cycle.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000;
- /** Drop call. */
+ /**
+ * Drop call.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_DROP = 1001;
- /** INTERCEPT order received, Mobile station (MS) state idle entered. */
+ /**
+ * INTERCEPT order received, Mobile station (MS) state idle entered.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_INTERCEPT = 1002;
- /** Mobile station (MS) has been redirected, call is cancelled. */
+ /**
+ * Mobile station (MS) has been redirected, call is cancelled.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_REORDER = 1003;
- /** Service option rejection. */
+ /**
+ * Service option rejection.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_SO_REJECT = 1004;
- /** Requested service is rejected, retry delay is set. */
+ /**
+ * Requested service is rejected, retry delay is set.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_RETRY_ORDER = 1005;
- /** Unable to obtain access to the CDMA system. */
+ /**
+ * Unable to obtain access to the CDMA system.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_ACCESS_FAILURE = 1006;
- /** Not a preempted call. */
+ /**
+ * Not a preempted call.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_PREEMPTED = 1007;
- /** Not an emergency call. */
+ /**
+ * Not an emergency call.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_NOT_EMERGENCY = 1008;
- /** Access Blocked by CDMA network. */
+ /**
+ * Access Blocked by CDMA network.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_ACCESS_BLOCKED = 1009;
/* OEM specific error codes. To be used by OEMs when they don't want to
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index 90d6f89..8b52f07 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -66,6 +66,9 @@
// 5G
public static final int RAF_NR = (int) TelephonyManager.NETWORK_TYPE_BITMASK_NR;
+ /** NB-IOT (Narrowband Internet of Things) over Non-Terrestrial-Networks technology. */
+ public static final int RAF_NB_IOT_NTN = (int) TelephonyManager.NETWORK_TYPE_BITMASK_NB_IOT_NTN;
+
// Grouping of RAFs
// 2G
private static final int GSM = RAF_GSM | RAF_GPRS | RAF_EDGE;
@@ -80,6 +83,9 @@
// 5G
private static final int NR = RAF_NR;
+ /** Non-Terrestrial Network. */
+ private static final int NB_IOT_NTN = RAF_NB_IOT_NTN;
+
/* Phone ID of phone */
private int mPhoneId;
@@ -258,7 +264,7 @@
raf = ((EVDO & raf) > 0) ? (EVDO | raf) : raf;
raf = ((LTE & raf) > 0) ? (LTE | raf) : raf;
raf = ((NR & raf) > 0) ? (NR | raf) : raf;
-
+ raf = ((NB_IOT_NTN & raf) > 0) ? (NB_IOT_NTN | raf) : raf;
return raf;
}
@@ -364,6 +370,7 @@
case "WCDMA": return WCDMA;
case "LTE_CA": return RAF_LTE_CA;
case "NR": return RAF_NR;
+ case "NB_IOT_NTN": return RAF_NB_IOT_NTN;
default: return RAF_UNKNOWN;
}
}
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 127bbff..f8c3287 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -233,6 +233,12 @@
public static final int RIL_RADIO_TECHNOLOGY_NR = 20;
/**
+ * 3GPP NB-IOT (Narrowband Internet of Things) over Non-Terrestrial-Networks technology.
+ * @hide
+ */
+ public static final int RIL_RADIO_TECHNOLOGY_NB_IOT_NTN = 21;
+
+ /**
* RIL Radio Annotation
* @hide
*/
@@ -258,14 +264,16 @@
ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA,
ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN,
ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA,
- ServiceState.RIL_RADIO_TECHNOLOGY_NR})
+ ServiceState.RIL_RADIO_TECHNOLOGY_NR,
+ ServiceState.RIL_RADIO_TECHNOLOGY_NB_IOT_NTN
+ })
public @interface RilRadioTechnology {}
/**
* The number of the radio technologies.
*/
- private static final int NEXT_RIL_RADIO_TECHNOLOGY = 21;
+ private static final int NEXT_RIL_RADIO_TECHNOLOGY = 22;
/** @hide */
public static final int RIL_RADIO_CDMA_TECHNOLOGY_BITMASK =
@@ -1125,6 +1133,9 @@
case RIL_RADIO_TECHNOLOGY_NR:
rtString = "NR_SA";
break;
+ case RIL_RADIO_TECHNOLOGY_NB_IOT_NTN:
+ rtString = "NB_IOT_NTN";
+ break;
default:
rtString = "Unexpected";
Rlog.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
@@ -1668,6 +1679,8 @@
return TelephonyManager.NETWORK_TYPE_LTE_CA;
case RIL_RADIO_TECHNOLOGY_NR:
return TelephonyManager.NETWORK_TYPE_NR;
+ case RIL_RADIO_TECHNOLOGY_NB_IOT_NTN:
+ return TelephonyManager.NETWORK_TYPE_NB_IOT_NTN;
default:
return TelephonyManager.NETWORK_TYPE_UNKNOWN;
}
@@ -1697,6 +1710,7 @@
return AccessNetworkType.CDMA2000;
case RIL_RADIO_TECHNOLOGY_LTE:
case RIL_RADIO_TECHNOLOGY_LTE_CA:
+ case RIL_RADIO_TECHNOLOGY_NB_IOT_NTN:
return AccessNetworkType.EUTRAN;
case RIL_RADIO_TECHNOLOGY_NR:
return AccessNetworkType.NGRAN;
@@ -1757,6 +1771,8 @@
return RIL_RADIO_TECHNOLOGY_LTE_CA;
case TelephonyManager.NETWORK_TYPE_NR:
return RIL_RADIO_TECHNOLOGY_NR;
+ case TelephonyManager.NETWORK_TYPE_NB_IOT_NTN:
+ return RIL_RADIO_TECHNOLOGY_NB_IOT_NTN;
default:
return RIL_RADIO_TECHNOLOGY_UNKNOWN;
}
@@ -1866,7 +1882,8 @@
|| radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA
|| radioTechnology == RIL_RADIO_TECHNOLOGY_IWLAN
|| radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA
- || radioTechnology == RIL_RADIO_TECHNOLOGY_NR;
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_NR
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_NB_IOT_NTN;
}
@@ -1886,7 +1903,8 @@
public static boolean isPsOnlyTech(int radioTechnology) {
return radioTechnology == RIL_RADIO_TECHNOLOGY_LTE
|| radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA
- || radioTechnology == RIL_RADIO_TECHNOLOGY_NR;
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_NR
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_NB_IOT_NTN;
}
/** @hide */
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 65a52da..3f8e066 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1397,25 +1397,44 @@
/**
* Value for {@link CarrierConfigManager#KEY_CDMA_ROAMING_MODE_INT} which leaves the roaming
* mode set to the radio default or to the user's preference if they've indicated one.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_ROAMING_MODE_RADIO_DEFAULT = -1;
/**
* Value for {@link CarrierConfigManager#KEY_CDMA_ROAMING_MODE_INT} which only permits
* connections on home networks.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_ROAMING_MODE_HOME = 0;
/**
* Value for {@link CarrierConfigManager#KEY_CDMA_ROAMING_MODE_INT} which permits roaming on
* affiliated networks.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_ROAMING_MODE_AFFILIATED = 1;
/**
* Value for {@link CarrierConfigManager#KEY_CDMA_ROAMING_MODE_INT} which permits roaming on
* any network.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CDMA_ROAMING_MODE_ANY = 2;
- /** @hide */
+ /** @hide
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @Deprecated
@IntDef(prefix = { "CDMA_ROAMING_MODE_" }, value = {
CDMA_ROAMING_MODE_RADIO_DEFAULT,
CDMA_ROAMING_MODE_HOME,
@@ -1802,12 +1821,17 @@
* to indicate if the SIM combination in DSDS has limitation or compatible issue.
* e.g. two CDMA SIMs may disrupt each other's voice call in certain scenarios.
*
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final String EXTRA_SIM_COMBINATION_WARNING_TYPE =
"android.telephony.extra.SIM_COMBINATION_WARNING_TYPE";
- /** @hide */
+ /** @hide
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @Deprecated
@IntDef({
EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE,
EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA
@@ -1818,15 +1842,21 @@
/**
* Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
* to indicate there's no SIM combination warning.
+ *
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE = 0;
/**
* Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
* to indicate two active SIMs are both CDMA hence there might be functional limitation.
+ *
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA = 1;
/**
@@ -1835,6 +1865,7 @@
* e.g. two CDMA SIMs may disrupt each other's voice call in certain scenarios, and the
* name will be "operator1 & operator2".
*
+ * TODO(b/379356026): Deprecate if this is CDMA specific
* @hide
*/
public static final String EXTRA_SIM_COMBINATION_NAMES =
@@ -2414,13 +2445,17 @@
* higher, then a SecurityException is thrown.</li>
* </ul>
*
+ * @deprecated Legacy CDMA is unsupported.
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
public String getMeid() {
+ if (Flags.cleanupCdma()) return null;
return getMeid(getSlotIndex());
}
@@ -2456,13 +2491,17 @@
*
* @param slotIndex of which MEID is returned
*
+ * @deprecated Legacy CDMA is unsupported.
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
public String getMeid(int slotIndex) {
+ if (Flags.cleanupCdma()) return null;
ITelephony telephony = getITelephony();
if (telephony == null) return null;
@@ -2485,12 +2524,16 @@
* Returns the Manufacturer Code from the MEID. Return null if Manufacturer Code is not
* available.
*
+ * @deprecated Legacy CDMA is unsupported.
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
@Nullable
public String getManufacturerCode() {
+ if (Flags.cleanupCdma()) return null;
return getManufacturerCode(getSlotIndex());
}
@@ -2500,12 +2543,16 @@
*
* @param slotIndex of which Type Allocation Code is returned
*
+ * @deprecated Legacy CDMA is unsupported.
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
@Nullable
public String getManufacturerCode(int slotIndex) {
+ if (Flags.cleanupCdma()) return null;
ITelephony telephony = getITelephony();
if (telephony == null) return null;
@@ -2648,7 +2695,13 @@
public static final int PHONE_TYPE_NONE = PhoneConstants.PHONE_TYPE_NONE;
/** Phone radio is GSM. */
public static final int PHONE_TYPE_GSM = PhoneConstants.PHONE_TYPE_GSM;
- /** Phone radio is CDMA. */
+ /**
+ * Phone radio is CDMA.
+ *
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int PHONE_TYPE_CDMA = PhoneConstants.PHONE_TYPE_CDMA;
/** Phone is via SIP. */
public static final int PHONE_TYPE_SIP = PhoneConstants.PHONE_TYPE_SIP;
@@ -3070,13 +3123,33 @@
public static final int NETWORK_TYPE_EDGE = TelephonyProtoEnums.NETWORK_TYPE_EDGE; // = 2.
/** Current network is UMTS */
public static final int NETWORK_TYPE_UMTS = TelephonyProtoEnums.NETWORK_TYPE_UMTS; // = 3.
- /** Current network is CDMA: Either IS95A or IS95B*/
+ /**
+ * Current network is CDMA: Either IS95A or IS95B
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int NETWORK_TYPE_CDMA = TelephonyProtoEnums.NETWORK_TYPE_CDMA; // = 4.
- /** Current network is EVDO revision 0*/
+ /**
+ * Current network is EVDO revision 0
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int NETWORK_TYPE_EVDO_0 = TelephonyProtoEnums.NETWORK_TYPE_EVDO_0; // = 5.
- /** Current network is EVDO revision A*/
+ /**
+ * Current network is EVDO revision A
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int NETWORK_TYPE_EVDO_A = TelephonyProtoEnums.NETWORK_TYPE_EVDO_A; // = 6.
- /** Current network is 1xRTT*/
+ /**
+ * Current network is 1xRTT
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int NETWORK_TYPE_1xRTT = TelephonyProtoEnums.NETWORK_TYPE_1XRTT; // = 7.
/** Current network is HSDPA */
public static final int NETWORK_TYPE_HSDPA = TelephonyProtoEnums.NETWORK_TYPE_HSDPA; // = 8.
@@ -3090,11 +3163,21 @@
*/
@Deprecated
public static final int NETWORK_TYPE_IDEN = TelephonyProtoEnums.NETWORK_TYPE_IDEN; // = 11.
- /** Current network is EVDO revision B*/
+ /**
+ * Current network is EVDO revision B
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int NETWORK_TYPE_EVDO_B = TelephonyProtoEnums.NETWORK_TYPE_EVDO_B; // = 12.
/** Current network is LTE */
public static final int NETWORK_TYPE_LTE = TelephonyProtoEnums.NETWORK_TYPE_LTE; // = 13.
- /** Current network is eHRPD */
+ /**
+ * Current network is eHRPD
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int NETWORK_TYPE_EHRPD = TelephonyProtoEnums.NETWORK_TYPE_EHRPD; // = 14.
/** Current network is HSPA+ */
public static final int NETWORK_TYPE_HSPAP = TelephonyProtoEnums.NETWORK_TYPE_HSPAP; // = 15.
@@ -3114,6 +3197,12 @@
* For 5G NSA, the network type will be {@link #NETWORK_TYPE_LTE}.
*/
public static final int NETWORK_TYPE_NR = TelephonyProtoEnums.NETWORK_TYPE_NR; // 20.
+ /**
+ * 3GPP NB-IOT (Narrowband Internet of Things) over Non-Terrestrial-Networks technology.
+ */
+ @FlaggedApi(Flags.FLAG_SATELLITE_SYSTEM_APIS)
+ public static final int NETWORK_TYPE_NB_IOT_NTN =
+ TelephonyProtoEnums.NETWORK_TYPE_NB_IOT_NTN; // 21
private static final @NetworkType int[] NETWORK_TYPES = {
NETWORK_TYPE_GPRS,
@@ -3190,6 +3279,7 @@
* @see #NETWORK_TYPE_EHRPD
* @see #NETWORK_TYPE_HSPAP
* @see #NETWORK_TYPE_NR
+ * @see #NETWORK_TYPE_NB_IOT_NTN
*
* @hide
*/
@@ -3250,6 +3340,7 @@
* @see #NETWORK_TYPE_EHRPD
* @see #NETWORK_TYPE_HSPAP
* @see #NETWORK_TYPE_NR
+ * @see #NETWORK_TYPE_NB_IOT_NTN
*
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_RADIO_ACCESS}.
@@ -3400,6 +3491,8 @@
return "LTE_CA";
case NETWORK_TYPE_NR:
return "NR";
+ case NETWORK_TYPE_NB_IOT_NTN:
+ return "NB_IOT_NTN";
case NETWORK_TYPE_UNKNOWN:
return "UNKNOWN";
default:
@@ -3450,6 +3543,8 @@
return NETWORK_TYPE_BITMASK_LTE;
case NETWORK_TYPE_NR:
return NETWORK_TYPE_BITMASK_NR;
+ case NETWORK_TYPE_NB_IOT_NTN:
+ return NETWORK_TYPE_BITMASK_NB_IOT_NTN;
case NETWORK_TYPE_IWLAN:
return NETWORK_TYPE_BITMASK_IWLAN;
case NETWORK_TYPE_IDEN:
@@ -6761,9 +6856,13 @@
}
}
- /** @hide */
+ /** @hide
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @Deprecated
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"ERI_"}, value = {
+ -1,
ERI_ON,
ERI_OFF,
ERI_FLASH
@@ -6773,24 +6872,37 @@
/**
* ERI (Enhanced Roaming Indicator) is ON i.e value 0 defined by
* 3GPP2 C.R1001-H v1.0 Table 8.1-1.
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int ERI_ON = 0;
/**
* ERI (Enhanced Roaming Indicator) is OFF i.e value 1 defined by
* 3GPP2 C.R1001-H v1.0 Table 8.1-1.
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int ERI_OFF = 1;
/**
* ERI (Enhanced Roaming Indicator) is FLASH i.e value 2 defined by
* 3GPP2 C.R1001-H v1.0 Table 8.1-1.
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int ERI_FLASH = 2;
- /** @hide */
+ /** @hide
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @Deprecated
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"ERI_ICON_MODE_"}, value = {
+ -1,
ERI_ICON_MODE_NORMAL,
ERI_ICON_MODE_FLASH
})
@@ -6802,7 +6914,9 @@
*
* Note: ERI is defined 3GPP2 C.R1001-H Table 8.1-1
* @hide
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @Deprecated
public static final int ERI_ICON_MODE_NORMAL = 0;
/**
@@ -6811,7 +6925,9 @@
*
* Note: ERI is defined 3GPP2 C.R1001-H Table 8.1-1
* @hide
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @Deprecated
public static final int ERI_ICON_MODE_FLASH = 1;
/**
@@ -6819,24 +6935,31 @@
* 3GPP2 C.R1001-H v1.0 Table 8.1-1. Additionally carriers define their own ERI display numbers.
* Defined values are {@link #ERI_ON}, {@link #ERI_OFF}, and {@link #ERI_FLASH}.
*
+ * @deprecated Legacy CDMA is unsupported.
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
public @EriIconIndex int getCdmaEnhancedRoamingIndicatorDisplayNumber() {
+ if (Flags.cleanupCdma()) return -1;
return getCdmaEriIconIndex(getSubId());
}
/**
* Returns the CDMA ERI icon index to display for a subscription.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@UnsupportedAppUsage
public @EriIconIndex int getCdmaEriIconIndex(int subId) {
+ if (Flags.cleanupCdma()) return -1;
try {
ITelephony telephony = getITelephony();
if (telephony == null)
@@ -6856,11 +6979,14 @@
* 0 - ON
* 1 - FLASHING
*
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@UnsupportedAppUsage
public @EriIconMode int getCdmaEriIconMode(int subId) {
+ if (Flags.cleanupCdma()) return -1;
try {
ITelephony telephony = getITelephony();
if (telephony == null)
@@ -6878,21 +7004,27 @@
/**
* Returns the CDMA ERI text,
*
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
public String getCdmaEriText() {
+ if (Flags.cleanupCdma()) return null;
return getCdmaEriText(getSubId());
}
/**
* Returns the CDMA ERI text, of a subscription
*
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
@UnsupportedAppUsage
public String getCdmaEriText(int subId) {
+ if (Flags.cleanupCdma()) return null;
try {
ITelephony telephony = getITelephony();
if (telephony == null)
@@ -8166,10 +8298,13 @@
* @param itemID the ID of the item to read.
* @return the NV item as a String, or null on any failure.
*
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
@UnsupportedAppUsage
public String nvReadItem(int itemID) {
+ if (Flags.cleanupCdma()) return "";
try {
ITelephony telephony = getITelephony();
if (telephony != null)
@@ -8194,9 +8329,12 @@
* @param itemValue the value to write, as a String.
* @return true on success; false on any failure.
*
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public boolean nvWriteItem(int itemID, String itemValue) {
+ if (Flags.cleanupCdma()) return false;
try {
ITelephony telephony = getITelephony();
if (telephony != null)
@@ -8220,9 +8358,12 @@
* @param preferredRoamingList byte array containing the new PRL.
* @return true on success; false on any failure.
*
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
+ if (Flags.cleanupCdma()) return false;
try {
ITelephony telephony = getITelephony();
if (telephony != null)
@@ -8248,12 +8389,19 @@
* {@link #resetRadioConfig()} for reset type 3 (b/116476729)
*
* @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
+ * @deprecated NV APIs are deprecated starting from Android U.
* @return true on success; false on any failure.
*
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @Deprecated
public boolean nvResetConfig(int resetType) {
+ if (Flags.cleanupCdma()) {
+ if (resetType != 1) { // 1: reload NV reset (reboot modem)
+ return false;
+ }
+ }
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
@@ -8283,14 +8431,20 @@
*
* @return {@code true} on success; {@code false} on any failure.
*
+ * @deprecated NV APIs are deprecated starting from Android U.
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_RADIO_ACCESS}.
* @hide
*/
+ @Deprecated
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
@SystemApi
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
public boolean resetRadioConfig() {
+ if (Flags.cleanupCdma()) {
+ return false;
+ }
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
@@ -8319,6 +8473,7 @@
* {@link PackageManager#FEATURE_TELEPHONY_RADIO_ACCESS}.
* @hide
*/
+ @Deprecated
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
@SystemApi
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
@@ -9272,20 +9427,26 @@
/**
* Preferred network mode is CDMA and EvDo (auto mode, according to PRL).
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final int NETWORK_MODE_CDMA_EVDO = RILConstants.NETWORK_MODE_CDMA;
/**
* Preferred network mode is CDMA only.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final int NETWORK_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO;
/**
* Preferred network mode is EvDo only.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final int NETWORK_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA;
/**
@@ -9296,8 +9457,10 @@
/**
* Preferred network mode is LTE, CDMA and EvDo.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final int NETWORK_MODE_LTE_CDMA_EVDO = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO;
/**
@@ -9308,8 +9471,10 @@
/**
* Preferred network mode is LTE, CDMA, EvDo, GSM/WCDMA.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA =
RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
@@ -9379,14 +9544,18 @@
/**
* Preferred network mode is TD-SCDMA,EvDo,CDMA,GSM/WCDMA.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA =
RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
/**
* Preferred network mode is TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA =
RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
@@ -9404,8 +9573,10 @@
/**
* Preferred network mode is NR 5G, LTE, CDMA and EvDo.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final int NETWORK_MODE_NR_LTE_CDMA_EVDO =
RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO;
@@ -9418,8 +9589,10 @@
/**
* Preferred network mode is NR 5G, LTE, CDMA, EvDo, GSM and WCDMA.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final int NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA =
RILConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA;
@@ -9458,8 +9631,10 @@
/**
* Preferred network mode is NR 5G, LTE, TD-SCDMA, CDMA, EVDO, GSM and WCDMA.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public static final int NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA =
RILConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
@@ -10160,6 +10335,9 @@
* This API will result in allowing an intersection of allowed network types for all reasons,
* including the configuration done through other reasons.
*
+ * If device supports satellite service, then
+ * {@link #NETWORK_TYPE_NB_IOT_NTN} is added to allowed network types for reason by default.
+ *
* @param reason the reason the allowed network type change is taking place
* @param allowedNetworkTypes The bitmask of allowed network type
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -10209,6 +10387,10 @@
* <p>Requires permission: android.Manifest.READ_PRIVILEGED_PHONE_STATE or
* that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
+ * If device supports satellite service, then
+ * {@link #NETWORK_TYPE_NB_IOT_NTN} is added to allowed network types for reason by
+ * default.
+ *
* @param reason the reason the allowed network type change is taking place
* @return the allowed network type bitmask
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -10275,7 +10457,7 @@
*/
public static String convertNetworkTypeBitmaskToString(
@NetworkTypeBitMask long networkTypeBitmask) {
- String networkTypeName = IntStream.rangeClosed(NETWORK_TYPE_GPRS, NETWORK_TYPE_NR)
+ String networkTypeName = IntStream.rangeClosed(NETWORK_TYPE_GPRS, NETWORK_TYPE_NB_IOT_NTN)
.filter(x -> {
return (networkTypeBitmask & getBitMaskForNetworkType(x))
== getBitMaskForNetworkType(x);
@@ -10533,24 +10715,32 @@
/**
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
public String getCdmaMdn() {
+ if (Flags.cleanupCdma()) return null;
return getCdmaMdn(getSubId());
}
/**
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
public String getCdmaMdn(int subId) {
+ if (Flags.cleanupCdma()) return null;
try {
ITelephony telephony = getITelephony();
if (telephony == null)
@@ -10566,24 +10756,32 @@
/**
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
public String getCdmaMin() {
+ if (Flags.cleanupCdma()) return null;
return getCdmaMin(getSubId());
}
/**
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
public String getCdmaMin(int subId) {
+ if (Flags.cleanupCdma()) return null;
try {
ITelephony telephony = getITelephony();
if (telephony == null)
@@ -11868,12 +12066,16 @@
*
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
public @CdmaRoamingMode int getCdmaRoamingMode() {
+ if (Flags.cleanupCdma()) return CDMA_ROAMING_MODE_RADIO_DEFAULT;
int mode = CDMA_ROAMING_MODE_RADIO_DEFAULT;
try {
ITelephony telephony = getITelephony();
@@ -11912,12 +12114,16 @@
*
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
public void setCdmaRoamingMode(@CdmaRoamingMode int mode) {
+ if (Flags.cleanupCdma()) return;
if (getPhoneType() != PHONE_TYPE_CDMA) {
throw new IllegalStateException("Phone does not support CDMA.");
}
@@ -11935,7 +12141,10 @@
}
}
- /** @hide */
+ /** @hide
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @Deprecated
@IntDef(prefix = { "CDMA_SUBSCRIPTION_" }, value = {
CDMA_SUBSCRIPTION_UNKNOWN,
CDMA_SUBSCRIPTION_RUIM_SIM,
@@ -11946,22 +12155,31 @@
/**
* Used for CDMA subscription mode, it'll be UNKNOWN if there is no Subscription source.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
public static final int CDMA_SUBSCRIPTION_UNKNOWN = -1;
/**
* Used for CDMA subscription mode: RUIM/SIM (default)
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0;
/**
* Used for CDMA subscription mode: NV -> non-volatile memory
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
public static final int CDMA_SUBSCRIPTION_NV = 1;
@@ -11982,12 +12200,16 @@
*
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
public @CdmaSubscription int getCdmaSubscriptionMode() {
+ if (Flags.cleanupCdma()) return CDMA_SUBSCRIPTION_UNKNOWN;
int mode = CDMA_SUBSCRIPTION_RUIM_SIM;
try {
ITelephony telephony = getITelephony();
@@ -12022,12 +12244,16 @@
*
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
public void setCdmaSubscriptionMode(@CdmaSubscription int mode) {
+ if (Flags.cleanupCdma()) return;
if (getPhoneType() != PHONE_TYPE_CDMA) {
throw new IllegalStateException("Phone does not support CDMA.");
}
@@ -13747,11 +13973,15 @@
*
* @throws UnsupportedOperationException If the device does not have
* {@link PackageManager#FEATURE_TELEPHONY_CDMA}.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_CDMA)
public String getCdmaPrlVersion() {
+ if (Flags.cleanupCdma()) return null;
return getCdmaPrlVersion(getSubId());
}
@@ -13762,9 +13992,12 @@
*
* @param subId the subscription ID that this request applies to.
* @return PRLVersion or null if error.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @Deprecated
public String getCdmaPrlVersion(int subId) {
+ if (Flags.cleanupCdma()) return null;
try {
ITelephony service = getITelephony();
if (service != null) {
@@ -14905,7 +15138,8 @@
NETWORK_TYPE_BITMASK_LTE_CA,
NETWORK_TYPE_BITMASK_NR,
NETWORK_TYPE_BITMASK_IWLAN,
- NETWORK_TYPE_BITMASK_IDEN
+ NETWORK_TYPE_BITMASK_IDEN,
+ NETWORK_TYPE_BITMASK_NB_IOT_NTN
})
public @interface NetworkTypeBitMask {}
@@ -14928,7 +15162,10 @@
public static final long NETWORK_TYPE_BITMASK_EDGE = (1 << (NETWORK_TYPE_EDGE -1));
/**
* network type bitmask indicating the support of radio tech CDMA(IS95A/IS95B).
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final long NETWORK_TYPE_BITMASK_CDMA = (1 << (NETWORK_TYPE_CDMA -1));
/**
* network type bitmask indicating the support of radio tech 1xRTT.
@@ -14950,7 +15187,10 @@
public static final long NETWORK_TYPE_BITMASK_EVDO_B = (1 << (NETWORK_TYPE_EVDO_B -1));
/**
* network type bitmask indicating the support of radio tech EHRPD.
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final long NETWORK_TYPE_BITMASK_EHRPD = (1 << (NETWORK_TYPE_EHRPD -1));
/**
* network type bitmask indicating the support of radio tech HSUPA.
@@ -15006,6 +15246,12 @@
*/
public static final long NETWORK_TYPE_BITMASK_IWLAN = (1 << (NETWORK_TYPE_IWLAN -1));
+ /**
+ * network type bitmask indicating the support of readio tech NB IOT NTN.
+ */
+ @FlaggedApi(Flags.FLAG_SATELLITE_SYSTEM_APIS)
+ public static final long NETWORK_TYPE_BITMASK_NB_IOT_NTN = (1 << (NETWORK_TYPE_NB_IOT_NTN - 1));
+
/** @hide */
public static final long NETWORK_CLASS_BITMASK_2G = NETWORK_TYPE_BITMASK_GSM
| NETWORK_TYPE_BITMASK_GPRS
@@ -15034,6 +15280,9 @@
public static final long NETWORK_CLASS_BITMASK_5G = NETWORK_TYPE_BITMASK_NR;
/** @hide */
+ public static final long NETWORK_CLASS_BITMASK_NTN = NETWORK_TYPE_BITMASK_NB_IOT_NTN;
+
+ /** @hide */
public static final long NETWORK_STANDARDS_FAMILY_BITMASK_3GPP = NETWORK_TYPE_BITMASK_GSM
| NETWORK_TYPE_BITMASK_GPRS
| NETWORK_TYPE_BITMASK_EDGE
@@ -15045,9 +15294,13 @@
| NETWORK_TYPE_BITMASK_TD_SCDMA
| NETWORK_TYPE_BITMASK_LTE
| NETWORK_TYPE_BITMASK_LTE_CA
- | NETWORK_TYPE_BITMASK_NR;
+ | NETWORK_TYPE_BITMASK_NR
+ | NETWORK_TYPE_BITMASK_NB_IOT_NTN;
- /** @hide */
+ /** @hide
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @Deprecated
public static final long NETWORK_STANDARDS_FAMILY_BITMASK_3GPP2 = NETWORK_TYPE_BITMASK_CDMA
| NETWORK_TYPE_BITMASK_1xRTT
| NETWORK_TYPE_BITMASK_EVDO_0
@@ -18083,7 +18336,7 @@
*/
public static boolean isNetworkTypeValid(@NetworkType int networkType) {
return networkType >= TelephonyManager.NETWORK_TYPE_UNKNOWN &&
- networkType <= TelephonyManager.NETWORK_TYPE_NR;
+ networkType <= TelephonyManager.NETWORK_TYPE_NB_IOT_NTN;
}
/**
diff --git a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java
index 02429b5..8fccf65 100644
--- a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java
+++ b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.java
@@ -16,12 +16,15 @@
package android.telephony.cdma;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.telephony.flags.Flags;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -34,18 +37,36 @@
* containing an array of these objects to update its list of cell broadcast service categories
* to display.
*
+ * @deprecated Legacy CDMA is unsupported.
* {@hide}
*/
+@FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+@Deprecated
@SystemApi
public final class CdmaSmsCbProgramData implements Parcelable {
- /** Delete the specified service category from the list of enabled categories. */
+ /**
+ * Delete the specified service category from the list of enabled categories.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int OPERATION_DELETE_CATEGORY = 0;
- /** Add the specified service category to the list of enabled categories. */
+ /**
+ * Add the specified service category to the list of enabled categories.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int OPERATION_ADD_CATEGORY = 1;
- /** Clear all service categories from the list of enabled categories. */
+ /**
+ * Clear all service categories from the list of enabled categories.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int OPERATION_CLEAR_CATEGORIES = 2;
/** @hide */
@@ -59,23 +80,53 @@
public @interface Operation {}
// CMAS alert service category assignments, see 3GPP2 C.R1001 table 9.3.3-1
- /** Indicates a presidential-level alert */
+ /**
+ * Indicates a presidential-level alert
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 0x1000;
- /** Indicates an extreme threat to life and property */
+ /**
+ * Indicates an extreme threat to life and property
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CATEGORY_CMAS_EXTREME_THREAT = 0x1001;
- /** Indicates an severe threat to life and property */
+ /**
+ * Indicates an severe threat to life and property
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CATEGORY_CMAS_SEVERE_THREAT = 0x1002;
- /** Indicates an AMBER child abduction emergency */
+ /**
+ * Indicates an AMBER child abduction emergency
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 0x1003;
- /** Indicates a CMAS test message */
+ /**
+ * Indicates a CMAS test message
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CATEGORY_CMAS_TEST_MESSAGE = 0x1004;
- /** The last reserved value of a CMAS service category according to 3GPP C.R1001 table
- * 9.3.3-1. */
+ /**
+ * The last reserved value of a CMAS service category according to 3GPP C.R1001 table
+ * 9.3.3-1.
+ * @deprecated Legacy CDMA is unsupported.
+ */
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 0x10ff;
/** @hide */
@@ -177,7 +228,10 @@
*
* @param dest The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written (ignored).
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mOperation);
@@ -192,7 +246,10 @@
* Returns the service category operation, e.g. {@link #OPERATION_ADD_CATEGORY}.
*
* @return the service category operation
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public @Operation int getOperation() {
return mOperation;
}
@@ -203,7 +260,10 @@
* 0x10FF are supported.
*
* @return a 16-bit CDMA service category value
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
public @Category int getCategory() {
return mCategory;
}
@@ -255,7 +315,11 @@
/**
* Describe the kinds of special objects contained in the marshalled representation.
* @return a bitmask indicating this Parcelable contains no special objects
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@Override
public int describeContents() {
return 0;
@@ -263,7 +327,11 @@
/**
* Creator for unparcelling objects.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@NonNull
public static final Parcelable.Creator<CdmaSmsCbProgramData>
CREATOR = new Parcelable.Creator<CdmaSmsCbProgramData>() {
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 8925a9e..76f83ee 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -18,6 +18,7 @@
import android.Manifest;
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -37,6 +38,8 @@
import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
import android.util.Log;
+import com.android.internal.telephony.flags.Flags;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -226,8 +229,11 @@
/**
* A capability update has been requested due to moving to eHRPD.
+ * @deprecated Legacy CDMA is unsupported.
* @hide
*/
+ @FlaggedApi(Flags.FLAG_DEPRECATE_CDMA)
+ @Deprecated
@SystemApi
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 4;
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index da7669f..74d9204 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -416,6 +416,8 @@
* Returns the CDMA ERI icon index to display
* @param callingPackage package making the call.
* @param callingFeatureId The feature in the package.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
int getCdmaEriIconIndex(String callingPackage, String callingFeatureId);
@@ -424,6 +426,8 @@
* @param subId user preferred subId.
* @param callingPackage package making the call.
* @param callingFeatureId The feature in the package.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
String callingFeatureId);
@@ -434,6 +438,8 @@
* 1 - FLASHING
* @param callingPackage package making the call.
* @param callingFeatureId The feature in the package.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
int getCdmaEriIconMode(String callingPackage, String callingFeatureId);
@@ -444,6 +450,8 @@
* @param subId user preferred subId.
* @param callingPackage package making the call.
* @param callingFeatureId The feature in the package.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
String callingFeatureId);
@@ -452,6 +460,8 @@
* Returns the CDMA ERI text,
* @param callingPackage package making the call.
* @param callingFeatureId The feature in the package.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
String getCdmaEriText(String callingPackage, String callingFeatureId);
@@ -460,6 +470,8 @@
* @param subId user preferred subId.
* @param callingPackage package making the call.
* @param callingFeatureId The feature in the package.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
String getCdmaEriTextForSubscriber(int subId, String callingPackage, String callingFeatureId);
@@ -779,6 +791,8 @@
*
* @param itemID the ID of the item to read.
* @return the NV item as a String, or null on any failure.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
String nvReadItem(int itemID);
@@ -789,6 +803,8 @@
* @param itemID the ID of the item to read.
* @param itemValue the value to write, as a String.
* @return true on success; false on any failure.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
boolean nvWriteItem(int itemID, String itemValue);
@@ -798,6 +814,8 @@
*
* @param preferredRoamingList byte array containing the new PRL.
* @return true on success; false on any failure.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
boolean nvWriteCdmaPrl(in byte[] preferredRoamingList);
@@ -811,6 +829,8 @@
*
* @param slotIndex - device slot.
* @return {@code true} on success; {@code false} on any failure.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
boolean resetModemConfig(int slotIndex);
@@ -1041,12 +1061,16 @@
/**
* Return MDN string for CDMA phone.
* @param subId user preferred subId.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
String getCdmaMdn(int subId);
/**
* Return MIN string for CDMA phone.
* @param subId user preferred subId.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
String getCdmaMin(int subId);
@@ -1495,13 +1519,14 @@
String getEsn(int subId);
/**
- * Return the Preferred Roaming List Version
- *
- * Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission
- * @param subId the subscription ID that this request applies to.
- * @return PRLVersion or null if error.
- * @hide
- */
+ * Return the Preferred Roaming List Version
+ *
+ * Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission
+ * @param subId the subscription ID that this request applies to.
+ * @return PRLVersion or null if error.
+ * @hide
+ * @deprecated Legacy CDMA is unsupported.
+ */
String getCdmaPrlVersion(int subId);
/**
@@ -1804,6 +1829,8 @@
*
* @param the subscription id.
* @return the roaming mode for CDMA phone.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
int getCdmaRoamingMode(int subId);
@@ -1814,6 +1841,8 @@
* @param subId the subscription id.
* @param mode the roaming mode should be set.
* @return {@code true} if successed.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
boolean setCdmaRoamingMode(int subId, int mode);
@@ -1822,6 +1851,8 @@
*
* @param the subscription id.
* @return the subscription mode for CDMA phone.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
int getCdmaSubscriptionMode(int subId);
@@ -1832,6 +1863,8 @@
* @param subId the subscription id.
* @param mode the subscription mode should be set.
* @return {@code true} if successed.
+ *
+ * @deprecated Legacy CDMA is unsupported.
*/
boolean setCdmaSubscriptionMode(int subId, int mode);
diff --git a/tests/AppJankTest/Android.bp b/tests/AppJankTest/Android.bp
index acf8dc9..c3cda6a 100644
--- a/tests/AppJankTest/Android.bp
+++ b/tests/AppJankTest/Android.bp
@@ -30,6 +30,7 @@
"androidx.test.core",
"platform-test-annotations",
"flag-junit",
+ "androidx.test.uiautomator_uiautomator",
],
platform_apis: true,
test_suites: ["device-tests"],
diff --git a/tests/AppJankTest/AndroidManifest.xml b/tests/AppJankTest/AndroidManifest.xml
index abed179..861a79c 100644
--- a/tests/AppJankTest/AndroidManifest.xml
+++ b/tests/AppJankTest/AndroidManifest.xml
@@ -19,22 +19,31 @@
package="android.app.jank.tests">
<application android:appCategory="news">
- <uses-library android:name="android.test.runner" />
- <activity android:name=".EmptyActivity"
- android:label="EmptyActivity"
- android:exported="true">
+ <activity android:name=".JankTrackerActivity"
+ android:exported="true"
+ android:label="JankTrackerActivity"
+ android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.VIEW_PERMISSION_USAGE"/>
</intent-filter>
</activity>
+ <activity android:name=".EmptyActivity"
+ android:exported="true"
+ android:label="EmptyActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <action android:name="android.intent.action.VIEW_PERMISSION_USAGE"/>
+ </intent-filter>
+ </activity>
+ <uses-library android:name="android.test.runner"/>
</application>
<!-- self-instrumenting test package. -->
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.app.jank.tests"
- android:label="Core tests of App Jank Tracking">
+ android:label="Core tests of App Jank Tracking"
+ android:targetPackage="android.app.jank.tests">
</instrumentation>
</manifest>
\ No newline at end of file
diff --git a/tests/AppJankTest/res/layout/jank_tracker_activity_layout.xml b/tests/AppJankTest/res/layout/jank_tracker_activity_layout.xml
new file mode 100644
index 0000000..65def7f
--- /dev/null
+++ b/tests/AppJankTest/res/layout/jank_tracker_activity_layout.xml
@@ -0,0 +1,47 @@
+<?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.
+ -->
+
+
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fitsSystemWindows="true">
+
+ <LinearLayout
+ android:id="@+id/linear_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ <EditText
+ android:id="@+id/edit_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textEnableTextConversionSuggestions"
+ android:text="Edit Text"/>
+ <TextView android:id="@+id/text_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Text View"
+ />
+ <android.app.jank.tests.TestWidget
+ android:id="@+id/jank_tracker_widget"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+ </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java b/tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java
new file mode 100644
index 0000000..34f0c19
--- /dev/null
+++ b/tests/AppJankTest/src/android/app/jank/tests/IntegrationTests.java
@@ -0,0 +1,215 @@
+/*
+ * 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.jank.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.app.jank.AppJankStats;
+import android.app.jank.Flags;
+import android.app.jank.JankDataProcessor;
+import android.app.jank.JankTracker;
+import android.app.jank.StateTracker;
+import android.content.Intent;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.widget.EditText;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * This file contains tests that verify the proper functionality of the Jank Tracking feature.
+ * All tests should obtain references to necessary objects through View type interfaces, rather
+ * than direct instantiation. When operating outside of a testing environment, the expected
+ * behavior is to retrieve the necessary objects using View type interfaces. This approach ensures
+ * that calls are correctly routed down to the activity level. Any modifications to the call
+ * routing should result in test failures, which might happen with direct instantiations.
+ */
+@RunWith(AndroidJUnit4.class)
+public class IntegrationTests {
+ public static final int WAIT_FOR_TIMEOUT_MS = 5000;
+
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+ private Activity mEmptyActivity;
+
+ public UiDevice mDevice;
+ private Instrumentation mInstrumentation;
+ private ActivityTestRule<JankTrackerActivity> mJankTrackerActivityRule =
+ new ActivityTestRule<>(
+ JankTrackerActivity.class,
+ false,
+ false);
+
+ private ActivityTestRule<EmptyActivity> mEmptyActivityRule =
+ new ActivityTestRule<>(EmptyActivity.class, false , true);
+
+ @Before
+ public void setUp() {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mDevice = UiDevice.getInstance(mInstrumentation);
+ }
+
+
+ /**
+ * Get a JankTracker object from a view and confirm it's not null.
+ */
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+ public void getJankTacker_confirmNotNull() {
+ Activity jankTrackerActivity = mJankTrackerActivityRule.launchActivity(null);
+ EditText editText = jankTrackerActivity.findViewById(R.id.edit_text);
+
+ mDevice.wait(Until.findObject(By.text("Edit Text")), WAIT_FOR_TIMEOUT_MS);
+
+ JankTracker jankTracker = editText.getJankTracker();
+ assertTrue(jankTracker != null);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+ public void reportJankStats_confirmPendingStatsIncreases() {
+ Activity jankTrackerActivity = mJankTrackerActivityRule.launchActivity(null);
+ EditText editText = jankTrackerActivity.findViewById(R.id.edit_text);
+ JankTracker jankTracker = editText.getJankTracker();
+
+ HashMap<String, JankDataProcessor.PendingJankStat> pendingStats =
+ jankTracker.getPendingJankStats();
+ assertEquals(0, pendingStats.size());
+
+ editText.reportAppJankStats(JankUtils.getAppJankStats());
+
+ // reportAppJankStats performs the work on a background thread, check periodically to see
+ // if the work is complete.
+ for (int i = 0; i < 10; i++) {
+ try {
+ Thread.sleep(100);
+ if (jankTracker.getPendingJankStats().size() > 0) {
+ break;
+ }
+ } catch (InterruptedException exception) {
+ //do nothing and continue
+ }
+ }
+
+ pendingStats = jankTracker.getPendingJankStats();
+
+ assertEquals(1, pendingStats.size());
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+ public void simulateWidgetStateChanges_confirmStateChangesAreTracked() {
+ JankTrackerActivity jankTrackerActivity =
+ mJankTrackerActivityRule.launchActivity(null);
+ TestWidget testWidget = jankTrackerActivity.findViewById(R.id.jank_tracker_widget);
+ JankTracker jankTracker = testWidget.getJankTracker();
+ jankTracker.forceListenerRegistration();
+
+ ArrayList<StateTracker.StateData> uiStates = new ArrayList<>();
+ // Get the current UI states, at this point only the activity name should be in the UI
+ // states list.
+ jankTracker.getAllUiStates(uiStates);
+
+ assertEquals(1, uiStates.size());
+
+ // This should add a UI state to be tracked.
+ testWidget.simulateAnimationStarting();
+ uiStates.clear();
+ jankTracker.getAllUiStates(uiStates);
+
+ assertEquals(2, uiStates.size());
+
+ // Stop the animation
+ testWidget.simulateAnimationEnding();
+ uiStates.clear();
+ jankTracker.getAllUiStates(uiStates);
+
+ assertEquals(2, uiStates.size());
+
+ // Confirm the Animation state has a VsyncIdEnd that is not default, indicating the end
+ // of that state.
+ for (int i = 0; i < uiStates.size(); i++) {
+ StateTracker.StateData stateData = uiStates.get(i);
+ if (stateData.mWidgetCategory.equals(AppJankStats.ANIMATION)) {
+ assertNotEquals(Long.MAX_VALUE, stateData.mVsyncIdEnd);
+ }
+ }
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+ public void jankTrackingPaused_whenActivityNoLongerVisible() {
+ JankTrackerActivity jankTrackerActivity =
+ mJankTrackerActivityRule.launchActivity(null);
+ TestWidget testWidget = jankTrackerActivity.findViewById(R.id.jank_tracker_widget);
+ JankTracker jankTracker = testWidget.getJankTracker();
+ jankTracker.forceListenerRegistration();
+
+ assertTrue(jankTracker.shouldTrack());
+
+ // Send jankTrackerActivity to the background
+ mDevice.pressHome();
+ mDevice.waitForIdle(WAIT_FOR_TIMEOUT_MS);
+
+ assertFalse(jankTracker.shouldTrack());
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
+ public void jankTrackingResumed_whenActivityBecomesVisibleAgain() {
+ mEmptyActivityRule.launchActivity(null);
+ mEmptyActivity = mEmptyActivityRule.getActivity();
+ JankTrackerActivity jankTrackerActivity =
+ mJankTrackerActivityRule.launchActivity(null);
+ TestWidget testWidget = jankTrackerActivity.findViewById(R.id.jank_tracker_widget);
+ JankTracker jankTracker = testWidget.getJankTracker();
+ jankTracker.forceListenerRegistration();
+
+ // Send jankTrackerActivity to the background
+ mDevice.pressHome();
+ mDevice.waitForIdle(WAIT_FOR_TIMEOUT_MS);
+
+ assertFalse(jankTracker.shouldTrack());
+
+ Intent resumeJankTracker = new Intent(mInstrumentation.getContext(),
+ JankTrackerActivity.class);
+ resumeJankTracker.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+ mEmptyActivity.startActivity(resumeJankTracker);
+ mDevice.wait(Until.findObject(By.text("Edit Text")), WAIT_FOR_TIMEOUT_MS);
+
+ assertTrue(jankTracker.shouldTrack());
+ }
+}
diff --git a/tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java b/tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java
index 4d495ad..30c568b 100644
--- a/tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java
+++ b/tests/AppJankTest/src/android/app/jank/tests/JankDataProcessorTest.java
@@ -20,7 +20,6 @@
import android.app.jank.AppJankStats;
import android.app.jank.Flags;
-import android.app.jank.FrameOverrunHistogram;
import android.app.jank.JankDataProcessor;
import android.app.jank.StateTracker;
import android.platform.test.annotations.RequiresFlagsEnabled;
@@ -165,7 +164,7 @@
assertEquals(pendingStats.size(), 0);
- AppJankStats jankStats = getAppJankStats();
+ AppJankStats jankStats = JankUtils.getAppJankStats();
mJankDataProcessor.mergeJankStats(jankStats, sActivityName);
pendingStats = mJankDataProcessor.getPendingJankStats();
@@ -182,14 +181,14 @@
@Test
@RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
public void mergeAppJankStats_confirmStatsWithMatchingStatesAreCombinedIntoOnePendingStat() {
- AppJankStats jankStats = getAppJankStats();
+ AppJankStats jankStats = JankUtils.getAppJankStats();
mJankDataProcessor.mergeJankStats(jankStats, sActivityName);
HashMap<String, JankDataProcessor.PendingJankStat> pendingStats =
mJankDataProcessor.getPendingJankStats();
assertEquals(pendingStats.size(), 1);
- AppJankStats secondJankStat = getAppJankStats();
+ AppJankStats secondJankStat = JankUtils.getAppJankStats();
mJankDataProcessor.mergeJankStats(secondJankStat, sActivityName);
pendingStats = mJankDataProcessor.getPendingJankStats();
@@ -200,7 +199,7 @@
@Test
@RequiresFlagsEnabled(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
public void mergeAppJankStats_whenStatsWithMatchingStatesMerge_confirmFrameCountsAdded() {
- AppJankStats jankStats = getAppJankStats();
+ AppJankStats jankStats = JankUtils.getAppJankStats();
mJankDataProcessor.mergeJankStats(jankStats, sActivityName);
mJankDataProcessor.mergeJankStats(jankStats, sActivityName);
@@ -345,27 +344,4 @@
return mockData;
}
-
- private AppJankStats getAppJankStats() {
- AppJankStats jankStats = new AppJankStats(
- /*App Uid*/APP_ID,
- /*Widget Id*/"test widget id",
- /*Widget Category*/AppJankStats.SCROLL,
- /*Widget State*/AppJankStats.SCROLLING,
- /*Total Frames*/100,
- /*Janky Frames*/25,
- getOverrunHistogram()
- );
- return jankStats;
- }
-
- private FrameOverrunHistogram getOverrunHistogram() {
- FrameOverrunHistogram overrunHistogram = new FrameOverrunHistogram();
- overrunHistogram.addFrameOverrunMillis(-2);
- overrunHistogram.addFrameOverrunMillis(1);
- overrunHistogram.addFrameOverrunMillis(5);
- overrunHistogram.addFrameOverrunMillis(25);
- return overrunHistogram;
- }
-
}
diff --git a/tests/AppJankTest/src/android/app/jank/tests/JankTrackerActivity.java b/tests/AppJankTest/src/android/app/jank/tests/JankTrackerActivity.java
new file mode 100644
index 0000000..80ab6ad3
--- /dev/null
+++ b/tests/AppJankTest/src/android/app/jank/tests/JankTrackerActivity.java
@@ -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.
+ */
+
+package android.app.jank.tests;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+
+public class JankTrackerActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.jank_tracker_activity_layout);
+ }
+}
+
+
diff --git a/tests/AppJankTest/src/android/app/jank/tests/JankUtils.java b/tests/AppJankTest/src/android/app/jank/tests/JankUtils.java
new file mode 100644
index 0000000..0b4d97e
--- /dev/null
+++ b/tests/AppJankTest/src/android/app/jank/tests/JankUtils.java
@@ -0,0 +1,52 @@
+/*
+ * 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.jank.tests;
+
+import android.app.jank.AppJankStats;
+import android.app.jank.FrameOverrunHistogram;
+
+public class JankUtils {
+ private static final int APP_ID = 25;
+
+ /**
+ * Returns a mock AppJankStats object to be used in tests.
+ */
+ public static AppJankStats getAppJankStats() {
+ AppJankStats jankStats = new AppJankStats(
+ /*App Uid*/APP_ID,
+ /*Widget Id*/"test widget id",
+ /*Widget Category*/AppJankStats.SCROLL,
+ /*Widget State*/AppJankStats.SCROLLING,
+ /*Total Frames*/100,
+ /*Janky Frames*/25,
+ getOverrunHistogram()
+ );
+ return jankStats;
+ }
+
+ /**
+ * Returns a mock histogram to be used with an AppJankStats object.
+ */
+ public static FrameOverrunHistogram getOverrunHistogram() {
+ FrameOverrunHistogram overrunHistogram = new FrameOverrunHistogram();
+ overrunHistogram.addFrameOverrunMillis(-2);
+ overrunHistogram.addFrameOverrunMillis(1);
+ overrunHistogram.addFrameOverrunMillis(5);
+ overrunHistogram.addFrameOverrunMillis(25);
+ return overrunHistogram;
+ }
+}
diff --git a/tests/AppJankTest/src/android/app/jank/tests/TestWidget.java b/tests/AppJankTest/src/android/app/jank/tests/TestWidget.java
new file mode 100644
index 0000000..5fff460
--- /dev/null
+++ b/tests/AppJankTest/src/android/app/jank/tests/TestWidget.java
@@ -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 android.app.jank.tests;
+
+import android.app.jank.AppJankStats;
+import android.app.jank.JankTracker;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class TestWidget extends View {
+
+ private JankTracker mJankTracker;
+
+ /**
+ * Create JankTrackerView
+ */
+ public TestWidget(Context context) {
+ super(context);
+ }
+
+ /**
+ * Create JankTrackerView, needed by system when inflating views defined in a layout file.
+ */
+ public TestWidget(Context context, AttributeSet attributeSet) {
+ super(context, attributeSet);
+ }
+
+ /**
+ * Mock starting an animation.
+ */
+ public void simulateAnimationStarting() {
+ if (jankTrackerCreated()) {
+ mJankTracker.addUiState(AppJankStats.ANIMATION,
+ Integer.toString(this.getId()), AppJankStats.ANIMATING);
+ }
+ }
+
+ /**
+ * Mock ending an animation.
+ */
+ public void simulateAnimationEnding() {
+ if (jankTrackerCreated()) {
+ mJankTracker.removeUiState(AppJankStats.ANIMATION,
+ Integer.toString(this.getId()), AppJankStats.ANIMATING);
+ }
+ }
+
+ private boolean jankTrackerCreated() {
+ if (mJankTracker == null) {
+ mJankTracker = getJankTracker();
+ }
+ return mJankTracker != null;
+ }
+}
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index 1e997b3..f44eacb 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -41,6 +41,7 @@
"platform-test-annotations",
"wm-flicker-common-app-helpers",
"wm-shell-flicker-utils",
+ "systemui-tapl",
],
data: [":FlickerTestApp"],
}
diff --git a/tests/FlickerTests/Notification/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationWarmTest.kt b/tests/FlickerTests/Notification/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationWarmTest.kt
index ad70757..da90c4f 100644
--- a/tests/FlickerTests/Notification/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationWarmTest.kt
+++ b/tests/FlickerTests/Notification/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationWarmTest.kt
@@ -16,6 +16,8 @@
package com.android.server.wm.flicker.notification
+import android.platform.systemui_tapl.controller.NotificationIdentity
+import android.platform.systemui_tapl.ui.Root
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.platform.test.rule.DisableNotificationCooldownSettingRule
@@ -28,8 +30,6 @@
import android.tools.traces.component.ComponentNameMatcher
import android.view.WindowInsets
import android.view.WindowManager
-import androidx.test.uiautomator.By
-import androidx.test.uiautomator.Until
import com.android.server.wm.flicker.helpers.NotificationAppHelper
import com.android.server.wm.flicker.helpers.setRotation
import com.android.server.wm.flicker.navBarLayerIsVisibleAtEnd
@@ -87,8 +87,9 @@
.withWindowSurfaceDisappeared(ComponentNameMatcher.NOTIFICATION_SHADE)
.waitForAndVerify()
}
+
protected fun FlickerTestData.openAppFromNotification() {
- doOpenAppAndWait(startY = 10, endY = 3 * device.displayHeight / 4, steps = 25)
+ doOpenAppAndWait()
}
protected fun FlickerTestData.openAppFromLockNotification() {
@@ -101,25 +102,27 @@
WindowInsets.Type.statusBars() or WindowInsets.Type.displayCutout()
)
- doOpenAppAndWait(startY = insets.top + 100, endY = device.displayHeight / 2, steps = 4)
+ doOpenAppAndWait()
}
- protected fun FlickerTestData.doOpenAppAndWait(startY: Int, endY: Int, steps: Int) {
- // Swipe down to show the notification shade
- val x = device.displayWidth / 2
- device.swipe(x, startY, x, endY, steps)
- device.waitForIdle(2000)
- instrumentation.uiAutomation.syncInputTransactions()
+ protected fun FlickerTestData.doOpenAppAndWait() {
+ val shade = Root.get().openNotificationShade()
// Launch the activity by clicking the notification
+ // Post notification and ensure that it's collapsed
val notification =
- device.wait(Until.findObject(By.text("Flicker Test Notification")), 2000L)
- notification?.click() ?: error("Notification not found")
- instrumentation.uiAutomation.syncInputTransactions()
+ shade.notificationStack.findNotification(
+ NotificationIdentity(
+ type = NotificationIdentity.Type.BY_TEXT,
+ text = "Flicker Test Notification",
+ )
+ )
+ notification.clickToApp()
// Wait for the app to launch
wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
}
+
@Presubmit @Test override fun appWindowBecomesVisible() = appWindowBecomesVisible_warmStart()
@Presubmit @Test override fun appLayerBecomesVisible() = appLayerBecomesVisible_warmStart()
diff --git a/tests/Input/res/xml/bookmarks.xml b/tests/Input/res/xml/bookmarks.xml
index a4c898d..68ec123 100644
--- a/tests/Input/res/xml/bookmarks.xml
+++ b/tests/Input/res/xml/bookmarks.xml
@@ -23,7 +23,7 @@
androidprv:modifierState="META" />
<bookmark
category="android.intent.category.APP_CONTACTS"
- androidprv:keycode="KEYCODE_C"
+ androidprv:keycode="KEYCODE_P"
androidprv:modifierState="META" />
<bookmark
category="android.intent.category.APP_EMAIL"
@@ -31,21 +31,13 @@
androidprv:modifierState="META" />
<bookmark
category="android.intent.category.APP_CALENDAR"
- androidprv:keycode="KEYCODE_K"
+ androidprv:keycode="KEYCODE_C"
androidprv:modifierState="META" />
<bookmark
category="android.intent.category.APP_MAPS"
androidprv:keycode="KEYCODE_M"
androidprv:modifierState="META" />
<bookmark
- category="android.intent.category.APP_MUSIC"
- androidprv:keycode="KEYCODE_P"
- androidprv:modifierState="META" />
- <bookmark
- role="android.app.role.SMS"
- androidprv:keycode="KEYCODE_S"
- androidprv:modifierState="META" />
- <bookmark
category="android.intent.category.APP_CALCULATOR"
androidprv:keycode="KEYCODE_U"
androidprv:modifierState="META" />
@@ -57,7 +49,7 @@
<bookmark
category="android.intent.category.APP_CONTACTS"
- androidprv:keycode="KEYCODE_C"
+ androidprv:keycode="KEYCODE_P"
shift="true" />
<bookmark
@@ -65,4 +57,4 @@
class="com.test.BookmarkTest"
androidprv:keycode="KEYCODE_J"
shift="true" />
-</bookmarks>
\ No newline at end of file
+</bookmarks>
diff --git a/tests/Input/res/xml/bookmarks_legacy.xml b/tests/Input/res/xml/bookmarks_legacy.xml
index 8bacf49..78cc48b 100644
--- a/tests/Input/res/xml/bookmarks_legacy.xml
+++ b/tests/Input/res/xml/bookmarks_legacy.xml
@@ -22,23 +22,17 @@
shortcut="b" />
<bookmark
category="android.intent.category.APP_CONTACTS"
- shortcut="c" />
+ shortcut="p" />
<bookmark
category="android.intent.category.APP_EMAIL"
shortcut="e" />
<bookmark
category="android.intent.category.APP_CALENDAR"
- shortcut="k" />
+ shortcut="c" />
<bookmark
category="android.intent.category.APP_MAPS"
shortcut="m" />
<bookmark
- category="android.intent.category.APP_MUSIC"
- shortcut="p" />
- <bookmark
- role="android.app.role.SMS"
- shortcut="s" />
- <bookmark
category="android.intent.category.APP_CALCULATOR"
shortcut="u" />
@@ -49,7 +43,7 @@
<bookmark
category="android.intent.category.APP_CONTACTS"
- shortcut="c"
+ shortcut="p"
shift="true" />
<bookmark
@@ -57,4 +51,4 @@
class="com.test.BookmarkTest"
shortcut="j"
shift="true" />
-</bookmarks>
\ No newline at end of file
+</bookmarks>
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
index c6d2819..fafb0e0 100644
--- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -575,9 +575,9 @@
),
TestData(
"META + C -> Launch Default Contacts",
- intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_C),
+ intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_P),
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
- intArrayOf(KeyEvent.KEYCODE_C),
+ intArrayOf(KeyEvent.KEYCODE_P),
KeyEvent.META_META_ON,
intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CONTACTS)
@@ -593,9 +593,9 @@
),
TestData(
"META + K -> Launch Default Calendar",
- intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_K),
+ intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_C),
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
- intArrayOf(KeyEvent.KEYCODE_K),
+ intArrayOf(KeyEvent.KEYCODE_C),
KeyEvent.META_META_ON,
intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CALENDAR)
@@ -610,24 +610,6 @@
AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_MAPS)
),
TestData(
- "META + P -> Launch Default Music",
- intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_P),
- KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
- intArrayOf(KeyEvent.KEYCODE_P),
- KeyEvent.META_META_ON,
- intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
- AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_MUSIC)
- ),
- TestData(
- "META + S -> Launch Default SMS",
- intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_S),
- KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
- intArrayOf(KeyEvent.KEYCODE_S),
- KeyEvent.META_META_ON,
- intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
- AppLaunchData.createLaunchDataForRole(RoleManager.ROLE_SMS)
- ),
- TestData(
"META + U -> Launch Default Calculator",
intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_U),
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
@@ -872,10 +854,10 @@
AppLaunchData.createLaunchDataForRole(RoleManager.ROLE_BROWSER)
),
TestData(
- "META + C -> Launch Default Contacts",
- intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_C),
+ "META + P -> Launch Default Contacts",
+ intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_P),
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
- intArrayOf(KeyEvent.KEYCODE_C),
+ intArrayOf(KeyEvent.KEYCODE_P),
KeyEvent.META_META_ON,
intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CONTACTS)
@@ -890,10 +872,10 @@
AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_EMAIL)
),
TestData(
- "META + K -> Launch Default Calendar",
- intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_K),
+ "META + C -> Launch Default Calendar",
+ intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_C),
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
- intArrayOf(KeyEvent.KEYCODE_K),
+ intArrayOf(KeyEvent.KEYCODE_C),
KeyEvent.META_META_ON,
intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CALENDAR)
@@ -908,24 +890,6 @@
AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_MAPS)
),
TestData(
- "META + P -> Launch Default Music",
- intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_P),
- KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
- intArrayOf(KeyEvent.KEYCODE_P),
- KeyEvent.META_META_ON,
- intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
- AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_MUSIC)
- ),
- TestData(
- "META + S -> Launch Default SMS",
- intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_S),
- KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
- intArrayOf(KeyEvent.KEYCODE_S),
- KeyEvent.META_META_ON,
- intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
- AppLaunchData.createLaunchDataForRole(RoleManager.ROLE_SMS)
- ),
- TestData(
"META + U -> Launch Default Calculator",
intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_U),
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
@@ -948,14 +912,14 @@
AppLaunchData.createLaunchDataForRole(RoleManager.ROLE_BROWSER)
),
TestData(
- "META + SHIFT + C -> Launch Default Contacts",
+ "META + SHIFT + P -> Launch Default Contacts",
intArrayOf(
KeyEvent.KEYCODE_META_LEFT,
KeyEvent.KEYCODE_SHIFT_LEFT,
- KeyEvent.KEYCODE_C
+ KeyEvent.KEYCODE_P
),
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
- intArrayOf(KeyEvent.KEYCODE_C),
+ intArrayOf(KeyEvent.KEYCODE_P),
KeyEvent.META_META_ON or KeyEvent.META_SHIFT_ON,
intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CONTACTS)
@@ -1732,4 +1696,4 @@
return true
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/PackageWatchdog/src/com/android/server/ExplicitHealthCheckServiceTest.java b/tests/PackageWatchdog/src/com/android/server/ExplicitHealthCheckServiceTest.java
index cd2ab86..055e159 100644
--- a/tests/PackageWatchdog/src/com/android/server/ExplicitHealthCheckServiceTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/ExplicitHealthCheckServiceTest.java
@@ -16,6 +16,8 @@
package com.android.server;
+import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_HEALTH_CHECK_PASSED_PACKAGE;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
@@ -35,8 +37,6 @@
private ExplicitHealthCheckService mExplicitHealthCheckService;
private static final String PACKAGE_NAME = "com.test.package";
- private static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE =
- "android.service.watchdog.extra.health_check_passed_package";
@Before
public void setup() throws Exception {
@@ -52,7 +52,7 @@
IBinder binder = mExplicitHealthCheckService.onBind(new Intent());
CountDownLatch countDownLatch = new CountDownLatch(1);
RemoteCallback callback = new RemoteCallback(result -> {
- assertThat(result.get(EXTRA_HEALTH_CHECK_PASSED_PACKAGE))
+ assertThat(result.getString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE))
.isEqualTo(PACKAGE_NAME);
countDownLatch.countDown();
});
diff --git a/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java b/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java
index ad032fb..15a580c 100644
--- a/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java
+++ b/tests/broadcasts/unit/src/android/app/BroadcastStickyCacheTest.java
@@ -20,6 +20,7 @@
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
@@ -186,6 +187,22 @@
}
@Test
+ public void getIntent_queryActionTwiceWithNullResult_verifyRegisterReceiverIsCalledOnce()
+ throws RemoteException {
+ setActivityManagerMock(null);
+ final Intent intent = queryIntent(new IntentFilter(Intent.ACTION_DEVICE_STORAGE_FULL));
+ final Intent cachedIntent = queryIntent(
+ new IntentFilter(Intent.ACTION_DEVICE_STORAGE_FULL));
+
+ assertNull(intent);
+ assertNull(cachedIntent);
+
+ verify(mActivityManagerMock, times(1)).registerReceiverWithFeature(
+ eq(mIApplicationThreadMock), anyString(), anyString(), anyString(), any(),
+ any(), anyString(), anyInt(), anyInt());
+ }
+
+ @Test
public void getIntent_querySameActionWithDifferentFilter_verifyRegisterReceiverCalledTwice()
throws RemoteException {
setActivityManagerMock(Intent.ACTION_DEVICE_STORAGE_LOW);
@@ -226,6 +243,6 @@
when(ActivityManager.getService()).thenReturn(mActivityManagerMock);
when(mActivityManagerMock.registerReceiverWithFeature(any(), anyString(),
anyString(), anyString(), any(), any(), anyString(), anyInt(),
- anyInt())).thenReturn(new Intent(action));
+ anyInt())).thenReturn(action != null ? new Intent(action) : null);
}
}
diff --git a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
index 100d869..4a6d4b1 100644
--- a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
+++ b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
@@ -17,8 +17,10 @@
package com.android.systemfeatures
import android.annotation.SdkConstant
+import com.squareup.javapoet.ClassName
import com.squareup.javapoet.FieldSpec
import com.squareup.javapoet.JavaFile
+import com.squareup.javapoet.MethodSpec
import com.squareup.javapoet.TypeSpec
import java.io.IOException
import javax.annotation.processing.AbstractProcessor
@@ -27,6 +29,7 @@
import javax.lang.model.SourceVersion
import javax.lang.model.element.Modifier
import javax.lang.model.element.TypeElement
+import javax.lang.model.element.VariableElement
import javax.tools.Diagnostic
/*
@@ -35,7 +38,16 @@
* <p>The output is a single class file, `com.android.internal.pm.SystemFeaturesMetadata`, with
* properties computed from feature constant definitions in the PackageManager class. This
* class is only produced if the processed environment includes PackageManager; all other
- * invocations are ignored.
+ * invocations are ignored. The generated API is as follows:
+ *
+ * <pre>
+ * package android.content.pm;
+ * public final class SystemFeaturesMetadata {
+ * public static final int SDK_FEATURE_COUNT;
+ * // @return [0, SDK_FEATURE_COUNT) if an SDK-defined system feature, -1 otherwise.
+ * public static int maybeGetSdkFeatureIndex(String featureName);
+ * }
+ * </pre>
*/
class SystemFeaturesMetadataProcessor : AbstractProcessor() {
@@ -56,19 +68,31 @@
return false
}
- // We're only interested in feature constants defined in PackageManager.
- var featureCount = 0
- roundEnv.getElementsAnnotatedWith(SdkConstant::class.java).forEach {
- if (
- it.enclosingElement == packageManagerType &&
- it.getAnnotation(SdkConstant::class.java).value ==
- SdkConstant.SdkConstantType.FEATURE
- ) {
- featureCount++
- }
- }
+ // Collect all FEATURE-annotated fields from PackageManager, and
+ // 1) Use the field values to de-duplicate, as there can be multiple FEATURE_* fields that
+ // map to the same feature string name value.
+ // 2) Ensure they're sorted to ensure consistency and determinism between builds.
+ val featureVarNames =
+ roundEnv
+ .getElementsAnnotatedWith(SdkConstant::class.java)
+ .asSequence()
+ .filter {
+ it.enclosingElement == packageManagerType &&
+ it.getAnnotation(SdkConstant::class.java).value ==
+ SdkConstant.SdkConstantType.FEATURE
+ }
+ .mapNotNull { element ->
+ (element as? VariableElement)?.let { varElement ->
+ varElement.getConstantValue()?.toString() to
+ varElement.simpleName.toString()
+ }
+ }
+ .toMap()
+ .values
+ .sorted()
+ .toList()
- if (featureCount == 0) {
+ if (featureVarNames.isEmpty()) {
// This is fine, and happens for any environment that doesn't include PackageManager.
return false
}
@@ -77,16 +101,8 @@
TypeSpec.classBuilder("SystemFeaturesMetadata")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addJavadoc("@hide")
- .addField(
- FieldSpec.builder(Int::class.java, "SDK_FEATURE_COUNT")
- .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
- .addJavadoc(
- "The number of `@SdkConstant` features defined in PackageManager."
- )
- .addJavadoc("@hide")
- .initializer("\$L", featureCount)
- .build()
- )
+ .addField(buildFeatureCount(featureVarNames))
+ .addMethod(buildFeatureIndexLookup(featureVarNames))
.build()
try {
@@ -104,7 +120,41 @@
return true
}
+ private fun buildFeatureCount(featureVarNames: Collection<String>): FieldSpec {
+ return FieldSpec.builder(Int::class.java, "SDK_FEATURE_COUNT")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
+ .addJavadoc(
+ "# of {@link android.annotation.SdkConstant}` features defined in PackageManager."
+ )
+ .addJavadoc("\n\n@hide")
+ .initializer("\$L", featureVarNames.size)
+ .build()
+ }
+
+ private fun buildFeatureIndexLookup(featureVarNames: Collection<String>): MethodSpec {
+ val methodBuilder =
+ MethodSpec.methodBuilder("maybeGetSdkFeatureIndex")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .addJavadoc("@return an index in [0, SDK_FEATURE_COUNT) for features defined ")
+ .addJavadoc("in PackageManager, else -1.")
+ .addJavadoc("\n\n@hide")
+ .returns(Int::class.java)
+ .addParameter(String::class.java, "featureName")
+ methodBuilder.beginControlFlow("switch (featureName)")
+ featureVarNames.forEachIndexed { index, featureVarName ->
+ methodBuilder
+ .addCode("case \$T.\$N: ", PACKAGEMANAGER_CLASS, featureVarName)
+ .addStatement("return \$L", index)
+ }
+ methodBuilder
+ .addCode("default: ")
+ .addStatement("return -1")
+ .endControlFlow()
+ return methodBuilder.build()
+ }
+
companion object {
private val SDK_CONSTANT_ANNOTATION_NAME = SdkConstant::class.qualifiedName
+ private val PACKAGEMANAGER_CLASS = ClassName.get("android.content.pm", "PackageManager")
}
}
diff --git a/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java b/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
index 4ffb5b9..74ce6da 100644
--- a/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
+++ b/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
@@ -16,10 +16,16 @@
package com.android.systemfeatures;
+import static com.android.internal.pm.SystemFeaturesMetadata.maybeGetSdkFeatureIndex;
+
import static com.google.common.truth.Truth.assertThat;
+import android.content.pm.PackageManager;
+
import com.android.internal.pm.SystemFeaturesMetadata;
+import com.google.common.collect.Range;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -33,4 +39,17 @@
// It defines 5 annotated features, and any/all other constants should be ignored.
assertThat(SystemFeaturesMetadata.SDK_FEATURE_COUNT).isEqualTo(5);
}
+
+ @Test
+ public void testSdkFeatureIndex() {
+ // Only SDK-defined features return valid indices.
+ final Range validIndexRange = Range.closedOpen(0, SystemFeaturesMetadata.SDK_FEATURE_COUNT);
+ assertThat(maybeGetSdkFeatureIndex(PackageManager.FEATURE_PC)).isIn(validIndexRange);
+ assertThat(maybeGetSdkFeatureIndex(PackageManager.FEATURE_VULKAN)).isIn(validIndexRange);
+ assertThat(maybeGetSdkFeatureIndex(PackageManager.FEATURE_NOT_ANNOTATED)).isEqualTo(-1);
+ assertThat(maybeGetSdkFeatureIndex(PackageManager.NOT_FEATURE)).isEqualTo(-1);
+ assertThat(maybeGetSdkFeatureIndex("foo")).isEqualTo(-1);
+ assertThat(maybeGetSdkFeatureIndex("0")).isEqualTo(-1);
+ assertThat(maybeGetSdkFeatureIndex("")).isEqualTo(-1);
+ }
}